Sunteți pe pagina 1din 70

Materialul acesta este incomplet si nefinisat.

Cursul se bazeaza pe Programare avansata in Oracle9i, Ed.Tehnica 2004, I.Popescu, A. Alecu,


L. Velcescu, G. Florea; Neprocedural in Oracle10g, Editura Universitatii din Bucuresti, L.
Velcescu, I. Popescu, 2008..
Cursul, predat efectiv, reprezinta o finisare si o completare a acestui material.

SQL
Structured Query Language (SQL) este un limbaj universal care poate fi
utilizat pentru a defini, interoga, reactualiza i gestiona baze de date relaionale.
SQL este accesibil utilizatorilor nceptori, dar n acelai timp poate oferi
programatorilor experimentai faciliti deosebite. SQL este un limbaj nonprocedural, adic se specific ce informaie este solicitat, dar nu modul cum se
obine aceast informaie. SQL poate fi utilizat autonom sau prin inserarea
comenzilor sale ntr-un limbaj de programare. SQL a sistemului Oracle este o
extensie a normei SQL89 i o implementare a normei SQL92.
n SQL se disting trei familii de comenzi:
Comenzi pentru definirea datelor, care permit descrierea (definirea)
obiectelor ce modeleaz sistemul studiat. Aceste comenzi definesc
limbajul de definire a datelor (LDD).
Comenzi pentru manipularea datelor, care permit consultarea,
reactualizarea, suprimarea sau inserarea datelor. Aceste comenzi definesc
limbajul de manipulare a datelor (LMD).
Comenzi pentru controlul datelor, care permit asigurarea confidenialitii
i integritii datelor, salvarea informaiei, realizarea fizic a modificrilor
n baza de date, rezolvarea unor probleme de concuren. Aceste comenzi
definesc limbajul de control al datelor (LCD).
Sistemul impune anumite restricii asupra identificatorilor.
Numele unui obiect nu poate depi 30 de caractere, cu excepia numelui
bazei de date care este limitat la 8 caractere i a numelui legturii unei
baze care poate ajunge la 128 caractere.
Nu se face distincie ntre litere mici i litere mari.
Numele trebuie s nceap printr-un caracter alfabetic i nu poate fi un
cuvnt cheie rezervat; poate s conin literele mari i mici ale alfabetului
englez, cifrele 0 - 9 i caracterele $, _, #.

Oracle

Un utilizator nu trebuie s defineasc dou obiecte cu acelai nume.


n general este bine ca numele unui obiect s fie descriptiv i fr
prescurtri excesive.

Limbajul de definire a datelor


Limbajul de definire a datelor const din acele instruciuni SQL (CREATE,
ALTER, DROP) care permit crearea, modificarea i distrugerea obiectelor BD.
Principalele obiecte ce pot fi definite i manipulate n sistemul Oracle sunt
urmtoarele: tabele (table), indeci (index), secvene (sequence), vizualizri (view),
proceduri (procedure), funcii (function), pachete (package), declanatori (trigger),
cliee (snapshot) etc.

Tipuri de date
Pentru memorarea datelor numerice, tipurile cele mai frecvent folosite sunt:
NUMBER, INTEGER, FLOAT, DECIMAL.
Pentru memorarea irurilor de caractere, cele mai frecvent tipuri de date
utilizate sunt: CHAR, VARCHAR2 i LONG.
Exist restricii referitoare la folosirea tipului de date LONG.
ntr-un tabel poate s fie o singur coloan de tip LONG.
Nu pot fi comparate dou iruri de caractere de tip LONG.
O coloan de tip LONG nu poate fi parametru ntr-o procedur.
O funcie nu poate ntoarce ca rezultat o valoare de tip LONG.
O coloan de tip LONG nu poate fi folosit n clauzele WHERE, ORDER BY,
GROUP BY, CONNECT.
Operatorii sau funciile Oracle nu pot fi folosii n SQL pentru a modifica
coloane de tip LONG.
O coloan de tip LONG nu poate fi indexat.
Alte tipuri de date scalare furnizate de SQL sunt NCHAR i NVARCHAR2,
folosite pentru reprezentarea caracterelor limbilor naionale.

SQL

Informaii relative la timp sau dat calendaristic se obin utiliznd tipul


DATE. Pentru fiecare dat de tip DATE sunt depuse: secolul, anul, luna, ziua, ora,
minutul, secunda.
Pentru o coloan de tip DATE sistemul rezerv 7 bytes, indiferent dac se
memoreaz doar timpul, sau doar data calendaristic.
Formatul implicit al datei se definete cu ajutorul parametrului de iniializare
NLS_DATE_FORMAT. n general, acest parametru este setat la forma DD-MONYY. Dac nu este specificat timpul, timpul implicit este 12:00:00.
n Oracle8, alturi de aceste tipuri scalare, exist i tipuri de date LOB
(Large Objects), care specific locaia unor obiecte de dimensiuni mari.

Tabele
Crearea unui tabel
Crearea unui tabel const din generarea structurii sale, adic atribuirea unui
nume tabelului i definirea caracteristicelor sale (se definesc coloanele, se definesc
constrngerile de integritate, se specific parametrii de stocare etc.).
Pentru a crea un tabel, utilizatorul trebuie s aib acest privilegiu i s
dispun de spaiul de memorie n care s creeze obiectul. La nivelul schemei sale,
un utilizator are toate privilegiile.
CREATE TABLE [<nume_schema>.] <nume_tabel> (
<nume_coloana_1> <tip_date> [DEFAULT <expresie>],

<nume_coloana_n> <tip_date> [DEFAULT <expresie>])


[CLUSTER <nume_cluster> (<coloana_1>,, <coloana_m>)]
[ENABLE | DISABLE <clause>];
Comanda poate conine opional clauza TABLESPACE, care specific spaiul
tabel n care va fi stocat tabelul. De asemenea, poate conine opional clauza
STORAGE care este folosit pentru setarea parametrilor de stocare prin intermediul
crora se specific mrimea i modul de alocare a extinderilor segmentului tabel.
La crearea unui tabel nu este nevoie s se specifice dimensiunea maxim a acestuia,
ea fiind determinat pn la urm de ct de mult spaiu a fost alocat spaiului tabel
n care este creat tabelul.
Structura unui tabel poate fi creat n urmtoarele patru moduri:

Oracle

fr a indica cheile;
indicnd cheile la nivel de coloan;
indicnd cheile la nivel de tabel;
prin copiere din alt tabel.
1. Crearea structurii unui tabel fr a indica cheile:
CREATE TABLE
carte
(codel
CHAR(5),
titlu
VARCHAR2(30),
autor
VARCHAR2(30),
pret
NUMBER(8,2),
nrex
NUMBER(3),
coded
CHAR(5));
2. Crearea structurii unui tabel indicnd cheile la nivel coloan:
CREATE TABLE
carte
(codel
CHAR(5) PRIMARY KEY,
titlu
VARCHAR2(30),
autor
VARCHAR2(30),
pret
NUMBER(8,2),
nrex
NUMBER(3),
coded
CHAR(5) NOT NULL
REFERENCES domeniu(coded));
Constrngerea de cheie primar sau extern ce presupune?
CREATE TABLE
(codel
titlu
autor
pret
nrex
coded

carte
CHAR(5) PRIMARY KEY,
VARCHAR2(30),
VARCHAR2(30),
NUMBER(8,2),
NUMBER(3),
CHAR(5) NOT NULL
REFERENCES domeniu(coded)
ON DELETE CASCADE);

SQL

Opiunea ON DELETE CASCADE specific c suprimarea oricrui domeniu


de carte din tabelul domeniu este autorizat i implic suprimarea automat a
tuturor crilor din domeniul respectiv care se gsesc n tabelul carte.
3. Crearea structurii unui tabel indicnd cheile la nivel de tabel:
CREATE TABLE carte
(codel
CHAR(5),
titlu
VARCHAR2(30),
autor
VARCHAR2(30),
pret
NUMBER(8,2),
nrex
NUMBER(3),
coded
CHAR(5) NOT NULL,
PRIMARY KEY (codel),
FOREIGN KEY (coded)
REFERENCES domeniu (coded));
Dac cheia primar are mai mult de o coloan atunci cheile trebuie indicate
la nivel de tabel.
CREATE TABLE imprumuta
(codel
CHAR(5),
codec
CHAR(5),
dataim
DATE DEFAULT SYSDATE,
datares DATE,
dataef
DATE,
PRIMARY KEY (codel, codec, dataim),
FOREIGN KEY (codel)
REFERENCES carte(codel),
FOREIGN KEY (codec)
REFERENCES cititor(codec));
4. Crearea structurii unui tabel prin copiere din alt tabel:
CREATE TABLE carte_info
AS SELECT
codel, titlu, autor
FROM
carte
WHERE
coded = I;
Constrngerile din primul tabel nu se pstreaz i pentru al doilea tabel.
Comanda creeaz un tabel, dar i insereaz date n tabel.

Oracle

Constrngeri
Constrngere este un mecanism care asigur c valorile unei coloane sau a
unei mulimi de coloane satisfac o condiie declarat. Unei constrgeri i se poate da
un nume unic. Dac nu se specific un nume explicit atunci sistemul automat i
atribuie un nume de forma SYS_Cn, unde n reprezint numrul constrngerii.
Constrngerile pot fi terse, pot fi adugate, pot fi activate sau dezactivate, dar nu
pot fi modificate.
Exemplu:
S se defineasc o constrngere la nivel de coloan prin care s se specifice
cheia primar i cheia extern.
CREATE TABLE carte
(codel
CHAR(5)
CONSTRAINT cp_carte PRIMARY KEY,
titlu
VARCHAR2(30),
coded
CHAR(5)
CONSTRAINT nn_coded NOT NULL
CONSTRAINT ce_coded
REFERENCES domeniu(coded));
Exemplu:
S se defineasc o constrngere la nivel de tabel prin care s se specifice
cheia primar i cheia extern.
CREATE TABLE carte
(codel
CHAR(5),
titlu
VARCHAR2(30),
coded
CHAR(5) NOT NULL,
CONSTRAINT cp_carte PRIMARY KEY (codel),
CONSTRAINT ce_coded
FOREIGN KEY (coded)
REFERENCES domeniu(coded));
Observaii
Liniile ce nu respect constngerea sunt depuse automat ntr-un tabel special.
Constrngerile previn tergerea unui tabel dac exist dependene.
Constrngerile pot fi create o dat cu tabelul sau dup ce acesta a fost creat.
Constrngerile pot fi activate sau dezactivate n funcie de necesiti.

SQL

Constrngeri declarative: constrngeri de domeniu, constrngerea de


integritate a entitii, constrngerea de integritate referenial.
Constrngerile de domeniu definesc valori luate de un atribut (DEFAULT,
CHECK, UNIQUE, NOT NULL).
constrngerea (coloan) DEFAULT ;
constrngerea (coloan sau tabel) CHECK ; constrngerea CHECK la nivel de
tabel poate compara coloane ntre ele, poate face referin la una sau mai multe
coloane, dar nu poate conine subcereri. Constrngerea la nivel de coloan nu
poate referi alte coloane ale aceluiai tabel.
CREATE TABLE carte
(codel
CHAR(5),
pret
NUMBER(8,2)
CONSTRAINT alfa
CHECK (pret < nrex),);
La execuia acestei comenzi apare mesajul: ORA 02438: Column check
constraint cannot reference other columns. Dac se adaug o virgul dup
NUMBER(8, 2) atunci constrngerea va fi la nivel de tabel, iar n aceste caz este
permis referirea altei coloane.
constrngerea (coloan sau tabel) UNIQUE ;
constrngerea declarativ NOT NULL poate fi doar la nivel coloan.
Constrngerea de integritate a entitii precizeaz cheia primar a unui
tabel. Cnd se creeaz cheia primar se genereaz automat un index unic. Valorile
cheii primare sunt distincte i diferite de valoarea null.
Constrngerea de integritate referenial asigur coerena ntre cheile
primare i cheile externe corespunztoare. Cnd este definit o cheie extern
sistemul Oracle verific:
dac a fost definit o cheie primar pentru tabelul referit de cheia extern;
dac numrul coloanelor ce compun cheia extern corespunde numrului de
coloane a cheii primare;
dac tipul i lungimea fiecrei coloane a cheii externe corespunde cu tipul i
lungimea fiecrei coloane a cheii primare.
n versiunea Oracle8 exist posibilitatea ca o constrngere s fie amnat
(DEFERRABLE). n acest caz, mai multe comenzi SQL pot fi executate fr a se
verifica restricia, aceasta fiind verificat numai la sfritul tranzaciei, atunci cnd

Oracle

este executat comanda COMMIT. Dac vreuna din comenzile tranzaciei ncalc
restricia, atunci ntreaga tranzacie este derulat napoi i este returnat o eroare.
Opiunea implicit este NOT DEFERRABLE.
O noutate introdus n Oracle8 este posibilitatea de a partiiona tabele,
adic de a mpri tabelul n mai multe pri independente, fiecare cu parametri de
stocare diferii i cu posibilitatea ca pri diferite ale tabelului s se gseasc pe
spaii tabel diferite. Fiecare partiie a tabelului va conine nregistrri care au
valoarea cheii ntr-un interval specificat. Partiionarea este transparent pentru
utilizatori i aplicaii. Dac o parte a tabelului este inaccesibil, celelalte pri pot fi
disponibile pentru reactualizare. De asemenea, se poate bloca accesul la o parte a
tabelului n timp ce restul nregistrrilor sunt disponibile.
Exemplu:
CREATE TABLE carte (
)
PARTITIONED BY RANGE (nrex)
((PARTITION mic VALUES LESS THAN(2)
TABLESPACE
STORAGE ),
PARTITION mediu VALUES LESS THAN (10)
TABLESPACE
STORAGE ),
PARTITION mare VALUES LESS THAN (MAXVALUE)
TABLESPACE
STORAGE ));
Modificarea structurii unui tabel
Comanda care realizeaz modificarea structurii tabelului (la nivel de coloan
sau la nivel de tabel), dar nu modificarea coninutului acestuia, este ALTER TABLE.
Comanda ALTER TABLE permite:
adugarea (ADD) de coloane, chei (primare sau externe), constrngeri
ntr-un tabel existent;
modificarea (MODIFY) coloanelor unui tabel;
specificarea unei valori implicite pentru o coloan existent;
activarea i dezactivarea (ENABLE, DISABLE) unor constrngeri;
suprimarea (DROP) cheii primare, a cheii externe sau a unor constrngeri.

SQL

Comanda ALTER TABLE are urmtoarea sintax simplificat:


ALTER TABLE [<nume_schema>.] <nume_tabel>
[ADD
(<nume_coloana> <tip_date>, <constrngere>) |
MODIFY
(<nume_coloana_1>,, <nume_coloana_n>) |
DROP
<clauza_drop>,]
[ENABLE | DISABLE <clause>];
1. Pentru a aduga o coloan, o cheie primar, o cheie extern sau o constrngere
unui tabel este folosit urmtoarea form:
ALTER TABLE
nume_tabel
ADD
(nume_coloana
constrangere,
nume_coloana
constrangere);
2. Pentru a modifica una sau mai multe coloane existente:
ALTER TABLE
MODIFY

nume_tabel
(nume_coloana
nume_coloana

constrangere,
constrangere);

3. Pentru a suprima cheia primar sau alte constrngeri sunt utilizate formele:
ALTER TABLE
nume_tabel
DROP PRIMARY KEY;
ALTER TABLE
nume_tabel
DROP CONSTRAINT nume_constrangere;
4. Pentru a activa (ENABLE) sau dezactiva (DISABLE) constrngeri este utilizat
forma:
ALTER TABLE
nume_tabel
ENABLE
nume_constrangere;
Observa?ii
Schimbarea definiiei unei coloane din NOT NULL n NULL O.K.
Schimbarea definiiei unei coloane din NULL n NOT NULL se poate face doar
dac exist sigurana c fiecare linie a coloanei respective este NOT NULL sau
dac tabelul (???sau coloana???) este vid.
Pentru mrirea lungimii coloanei nu exist condiii speciale. Pot reduce
lungimea unei coloane sau pot schimba tipul unei coloane doar dac coloana nu
conine valori sau conine doar valori NULL.
Definirea cheii primare sau a cheii externe dup crearea tabelului.

10

Oracle

CREATE TABLE
carte
(CODEL char(5),
);
ALTER TABLE
carte
ADD CONSTRAINT cheie_prim PRIMARY KEY (codel);
Suprimarea cheii primare.
ALTER TABLE carte
DROP PRIMARY KEY;
Dac exist o CE care refer o CP i dac se ncearc tergerea cheii primare,
aceast tergere nu se poate realiza (tabelele sunt legate prin declaraia de cheie
extern). tergerea este totui permis dac n comanda ALTER apare opiunea
CASCADE, care determin i tergerea cheilor externe ce refer cheia primar.
ALTER TABLE carte
DROP PRIMARY KEY CASCADE;
Suprimarea cheii externe.
ALTER TABLE
carte
ADD CONSTRAINT beta
FOREIGN KEY (coded) REFERENCES domeniu;
ALTER TABLE
carte
DROP CONSTRAINT
beta;
Schimbarea cheii primare. Este destul de complicat procesul schimbrii cheii
primare fr a afecta modul de proiectare a bazei de date. Schimbarea se face n
dou etape: se terge cheia primar i apoi se recreeaz.
ALTER TABLE
carte
ADD
(PRIMARY KEY(codel));
ALTER TABLE
carte
DROP PRIMARY KEY;
ALTER TABLE
carte
ADD
PRIMARY KEY(titlu, autor));
Adugarea unei coloane. Aceast coloan iniial va fi null (pentru toate liniile).
Nu se poate specifica unde s apar coloana, ea devenind ultima coloan a
tabelului.
ALTER TABLE
carte
ADD
(rezumat LONG);

SQL

11

Suprimarea unei coloane.


se creeaz un tabel selectnd toate cmpurile, cu excepia coloanei care trebuie
tears (CREATE
TABLE AS SELECT );
se transfer privilegiile;
se terge tabelul iniial.
n Oracle9i se poate terge direct prin DROP COLUMN.
Constrngerile pot fi adugate (ADD CONSTRAINT), terse (DROP
CONSTRAINT), activate (ENABLE) sau dezactivate (DISABLE), dar nu pot fi
modificate.
ALTER TABLE
cititor
ADD CONSTRAINT
cp_cititor
PRIMARY KEY (codec)
DISABLE;
ALTER TABLE
cititor
ENABLE CONSTRAINT
cp_cititor;
Prima comand adaug o constrngere, dar nu-i d via. Constrngerea
exist, dar server-ul nu o verific. Cnd se activeaz o constrngere, sistemul
controleaz toate liniile tabelului i insereaz ntr-un tabel special toate liniile care
nu verific constrngerea. Tabelul are urmtoarea structur:
(ROW_ID
ROWID
(OWNER
VARCHAR2(30),
(TABLE_NAME
VARCHAR2(30),
(CONSTRAINT
VARCHAR2(30))
Din punct de vedere fizic, comanda ALTER TABLE permite schimbarea
parametrilor PCTFREE i PCTUSED i a parametrilor din clauza STORAGE.
Comanda permite alocarea (ALLOCATE EXTENT) i dealocarea
(DEALLOCATE UNUSED) manual a spaiului utilizat de ctre un tabel.
Alocarea se face prin adugarea de noi extinderi, iar dealocarea reprezint
eliberarea spaiului nefolosit de tabel (care nu a fost folosit niciodat sau a
devenit liber datorit tergerii unor linii).
Suprimarea unui tabel
DROP TABLE [<nume_schema>.]<nume_tabel>;

12

Oracle

Suprimarea unui tabel presupune:


suprimarea definiiei sale n dicionarul datelor;
suprimarea indecilor asociai;
suprimarea privilegiilor conferite n legtur cu tabelul;
recuperarea spaiului ocupat de tabel;
invalidarea (dar nu suprimarea) funciilor, procedurilor, vizualizrilor,
sinonimelor referitoare la tabel.
DROP TABLE este ireversibil. Nu poate fi fcut un rollback pe aceast
comand. In DD, informaiile despre tabele se gsesc n vizualizarea
USER_TABLES. Dintre cele mai importante coloane ale acesteia, fac parte:
TABLE_NAME
TABLESPACE_NAME
CLUSTER_NAME
PCT_FREE
PCT_USED
INI_TRANS
NITIAL_EXTENT
NEXT_EXTENT
MIN_EXTENTS
MAX_EXTENTS
PCT_INCREASE
BACKED_UP
NUM_ROWS
BLOCKS
EMPTY_BLOCKS
AVG_SPACE
AVG_ROW_LEN
TABLE_LOCK
PARTITIONED
TEMPORARY
NESTED

Numele tabelului
Spaiul tabel n care se afl tabelul
Numele cluster-ului din care face parte tabelul
Procentul de spaiu pstrat liber n interiorul fiecrui bloc
Procentul de spaiu ce poate fi utilizat n fiecare bloc
Numrul iniial de tranzacii concurente n interiorul unui
bloc
Dimensiunea spaiului alocat pentru prima extensie
Dimensiunea spaiului alocat pentru urmtoarea extensie
Numrul minim de extensii ce se aloc la crearea unui tabel
Numrul maxim de extensii ce se aloc la crearea unui tabel
Procentul cu care crete dimensiunea unei extensii
Y sau N, dup cum tabelului i-a fost fcut o copie de
siguran de la ultima modificare
Numrul de nregistrri din tabel
Numrul de blocuri utilizate de tabel
Numrul de blocuri ce nu conin date
Spaiul mediu liber din tabel
Lungimea medie, n octei, a unei linii
ENABLED (activat) sau DISABLED (dezactivat): este
activat sau nu blocarea tabelului
YES sau NO, indic dac tabelul este partiionat (sau nu)
Y sau N, indic dac tabelul este temporar (sau nu)
YES sau NO, indic dac tabelul este imbricat (sau nu)

DESCRIBE USER_TABLES;
SELECT
TABLE_NAME, NUM_ROWS, NESTED
FROM
USER_TABLES;

SQL

13

Indeci
Un index este un obiect al schemei unei baze de date care:
crete viteza de execuie a cererilor;
garanteaz c o coloan conine valori unice.
Server-ul Oracle utilizeaz identificatorul ROWID pentru regsirea liniilor n
structura fizic a bazei de date. Indexul, din punct de vedere logic, este compus
dintr-o valoare cheie i din identificatorul adres ROWID.
Cheia indexului poate fi coloana unui tabel sau concatenarea mai multor
coloane (numrul maxim de coloane care pot defini cheia indexului este 32).
Coloanele care apar n cheia indexului trebuie declarate NOT NULL n tabel.
Indecii, fiind obiecte ale schemei bazei, beneficiaz de procesul de definire
a unui obiect. Un index unic este creat automat cnd n definirea unui tabel apar
constrngerile PRIMARY KEY sau UNIQUE. Crearea unui index pe una sau mai
multe coloane ale unui tabel se face prin comanda:
CREATE [UNIQUE] INDEX <nume_index>
ON [<nume_schema>.] <nume_tabel>
(<nume_col> [ASC | DESC], <nume_col> [ASC | DESC], )
| CLUSTER <nume_cluster>];
Cnd este creat un index, un segment de date este rezervat automat n spaiul
tabel. Alocarea de memorie este controlat prin clauzele INITIAL, PCTINCREASE,
PCTFREE, NEXT, care pot s apar n comanda CREATE INDEX. Gestiunea
inseriilor i a reactualizrilor se face, ca i la tabele, utiliznd parametrii
PCTFREE i PCTUSED.
Exemplu:
1) S se creeze un index descresctor relativ la coloana adresa din tabelul cititor.
2) S se afieze informaiile referitoare la indexul cititor_idx.
Soluie:
CREATE INDEX cititor_idx
ON cititor (adresa DESC);
SELECT
TABLE_NAME, UNIQUENESS, MIN_EXTENTS
FROM
USER_INDEXES

14

Oracle

WHERE

INDEX_NAME='cititor_idx';

tergerea unui index se face prin comanda:


DROP INDEX nume_index [ON [nume_schema.] nume_tabel]
Pentru a suprima indexul trebuie ca acesta s se gseasc n schema
personal sau s ai privilegiul de sistem DROP ANY INDEX.
Pentru a reconstrui un index se pot folosi dou metode:
se terge indexul (DROP INDEX) i se recreeaz (CREATE INDEX);
se utilizeaz comanda ALTER INDEX cu opiunea REBUILD.
Modificarea parametrilor de stocare a indecilor (STORAGE), alocarea
(ALLOCATE EXTENT) i dealocarea (DEALLOCATE UNUSED) manual a
spaiului utilizat de un index se pot realiza cu ajutorul comenzii ALTER INDEX.
Validarea unui index, adic verificarea integritii indexului specificat
pentru un tabel, se face prin comanda:
VALIDATE INDEX nume_index [ON nume_tabel] [WITH LIST]
Oracle8 folosete urmtoarele tipuri de indeci:
index de tip arbore B* creat la executarea unei comenzi standard CREATE
INDEX;
index partiionat folosit n cazul tabelelor mari pentru a stoca valorile
coloanei indexate n mai multe segmente;
index de cluster bazat pe coloanele comune ale unui cluster;
index cu cheie invers sunt B* arbori, dar care stocheaz datele n mod
invers;
index de tip bitmap nu se stocheaz valorile efective ale coloanei indexate,
ci un bitmap format pe baza acestor valori.
Ce tabele sau ce coloane trebuie (sau nu) indexate?
indexai tabelele pentru care interogrile selecteaz un numr redus de
rnduri (sub 5%);
indexai tabelele care sunt interogate folosind clauze SQL simple;
nu indexai tabelele ce conin puine nregistrri (accesul secvenial este mai
simplu);

SQL

15

nu indexai tabelele care sunt frecvent actualizate, deoarece tergerile,


inserrile i modificrile sunt ngreunate de indeci;
indexai coloanele folosite frecvent n clauza WHERE sau n clauza ORDER
BY;
nu indexai coloanele ce conin date asemntoare (puine valori distincte);
indexai coloanele care sunt utilizate pentru a face legtura dintre tabele.
Versiunea Oracle8 permite construirea de tabele organizate pe baz de
index. n acest caz, datele sunt stocate n indexul asociat. Un astfel de tabel poate fi
manipulat de ctre aplicaii la fel ca un tabel obinuit, folosind comenzi SQL.
Diferena const n faptul c n cazul tabelului organizat pe baz de index, toate
operaiile sunt efectuate numai asupra indexului. n loc ca fiecare intrare a
indexului s conin valoarea coloanei sau coloanelor indexate i valoarea ROWID
(care identific unic un rnd) pentru rndul corespunztor, ea conine ntreg rndul.
Coloana sau coloanele dup care se face indexarea sunt cele care constituie cheia
primar a tabelului.
Informaii despre indeci pot fi obinute cu ajutorul view-urilor
USER_INDEXES i USER_IND_COLUMNS. Dintre coloanele tabelului
USER_INDEXES se remarc:
INDEX_NAME
INDEX_TYPE
TABLE_OWNER
TABLE_NAME
TABEL_TYPE
UNIQUENESS
TABLESPACE_NAME
INITIAL_EXTENT
NEXT_EXTENT
MIN_EXTENTS
MAX_EXTENTS
PCT_INCREASE
BLEVEL
LEAF_BLOCKS
DISTINCT_KEYS
STATUS
NUM_ROWS
PARTITIONED

Numele indexului
Tipul indexului (NORMAL, LOB, CLUSTER etc.)
Proprietarul tabelului indexat
Numele tabelului indexat
Tipul tabelului indexat (TABLE, CLUSTER etc.)
Starea de unicitate (UNIQUE, NONUNIQUE)
Spaiul tabel n care este stocat indexul
Spaiul alocat pentru prima extensie
Spaiul alocat pentru urmtoarea extensie
Numrul minim de extensii alocate
Numrul maxim de extensii
Procentul cu care cresc extensiile
Nivelul din B-arbore. Acesta arat adncimea indexului de
la ramuri la frunze
Numrul de blocuri frunz din index
Numrul de chei distincte n index
Starea indexului (VALID, INVALID, DIRECT_LOAD)
Numrul de linii utilizate. Acesta nu trebuie s includ
valorile NULL din tabelul de baz
Determin dac indexul este partiionat (YES sau NO)

16

Oracle

GENERATED

Determin dac sistemul a generat numele indexului (Y)


sau utilizatorul (N)

Exemplu:
S se obin informaii referitoare la indecii tabelului carte.
SELECT
a.index_name, a.column_name,
a.column_position poz, b.uniqueness
FROM
user_indexes b, user_ind_columns a
WHERE
a.index_name = b.index_name
AND
a.table_name = carte;

Secvene
O secven este un obiect n baza de date care servete pentru a genera ntregi
unici n sistemele multi-utilizator, evitnd apariia conflictelor i a blocrii.
Secvenele sunt memorate i generate indiferent de tabele aceeai
secven poate fi utilizat pentru mai multe tabele. O secven poate fi creat de un
utilizator i poate fi partajat de mai muli utilizatori.
Crearea unei secvene se face cu ajutorul comenzii:
CREATE SEQUENCE [<nume_schema>.]<nume_secventa>
[INCREMENT BY n] [START WITH m]
[{MAXVALUE n | NOMAXVALUE}] [{MINVALUE n | NOMINVALUE}]
[{CACHE k | NOCACHE}]
[{ORDER | NOORDER}]

CACHE k | NOCACHE specific numrul de valori alocate de server-ul Oracle


pe care le va pstra n memoria cache pentru a oferi utilizatorilor un acces rapid
(implicit sunt alocate 20 de valori);

ORDER | NOORDER specific dac valorile generate de secven sunt ordonate


n conformitate cu cererile.
O secven este referit ntr-o comand SQL cu ajutorul pseudo-coloanelor:

NEXTVAL refer valoarea urmtoare a secvenei;

CURRVAL refer valoarea curent a secvenei.

NEXTVAL i CURRVAL pot fi folosite n:

SQL

17

clauza VALUES a unei comenzi INSERT;


clauza SET a unei comenzi UPDATE;
lista unei comenzi SELECT.
NEXTVAL i CURRVAL nu pot fi folosite n:
subinterogare;
interogarea unei vizualizri;
comand SELECT cu operatorul DISTINCT;
comand SELECT cu clauza GROUP BY sau ORDER BY;
clauza WHERE a unei comenzi SELECT;
condiia unei constrngeri CHECK;
valoarea DEFAULT a unei coloane ntr-o comand CREATE TABLE sau
ALTER TABLE;
comand SELECT care este combinat cu alt comand SELECT printr-un
operator mulime (UNION, INTERSECT, MINUS).
Din dicionarul datelor pot fi obinute informaii despre secvene folosind
vizualizarea USER_SEQUENCES.
Exemplu:
1) S se creeze o secven domeniuseq care s fie utilizat pentru a insera noi
domenii n tabelul domeniu i s se insereze un nou domeniu.
2) S se afieze informaiile referitoare la secvena domeniuseq.
CREATE SEQUENCE domeniuseq
START WITH 1
INCREMENT BY 1;
INSERT INTO domeniu
VALUES (domeniuseq.NEXTVAL,Informatica);
SELECT INCREMENT, START, MAXVALUE, MINVALUE,
FROM
USER_SEQUENCES
WHERE SEQUENCE_NAME = 'domeniuseq';
Modificarea unei secvene se face prin comanda ALTER SEQUENCE.
Sintaxa comenzii este similar instruciunii CREATE SEQUENCE , dar:

18

Oracle

noua valoare maxim pentru MAXVALUE nu poate fi mai mic dect


valoarea curent;
opiunea START WITH nu poate fi modificat de comand.
Suprimarea unei secvene se face cu ajutorul comenzii:
DROP SEQUENCE [<nume_schema>.]<nume_secventa>;
Dup ce a fost tears, secvena nu mai poate fi referit. Pentru a putea terge
sau modifica secvena trebuie fie s fi proprietarul acesteia, fie s ai privilegiul de
sistem DROP ANY SEQUENCE, respectiv privilegiul ALTER SEQUENCE.

Comentarii
Sistemul Oracle ofer posibilitatea de a comenta obiectele create, printr-un
text care este inserat n dicionarul datelor. Comentariul se poate referi la tabele,
vizualizri, cliee sau coloane.
COMMENT ON
{TABLE
nume_obiect.nume_coloana}
IStextcomentariu

nume_obiect

COLUMN

Sinonime
Oracle ofer posibilitatea de a atribui mai multe nume aceluiai obiect.
Aceste nume adiionale sunt numite sinonime (synonymes). Ele sunt utile deoarece
permit simplificarea formulrii cererii i referirea la obiecte, fr a fi nevoie s se
specifice proprietarii obiectelor sau localizarea acestora.
Spre deosebire de alias a crui durat de via este limitat la cererea ce
conine alias-ul, sinonimele sunt salvate n dicionarul datelor i pot fi reutilizate.
Sistemul Oracle permite crearea de sinonime pentru obiecte de tipul: tabel,
vizualizare, secven, funcie, procedur, pachet, clieu, sinonim.
CREATE [PUBLIC]
[schema.]obiect

SYNONYM

[schema.]nume_sinonim FOR

Administratorul bazei poate produce i poate suprima sinonime publice sau


private, iar utilizatorii pot genera sau suprima doar sinonime private. Pentru
suprimarea unui sinonim din baza de date se utilizeaz comanda:

SQL

19

DROP [PUBLIC] SYNONYM [schema.]nume_sinonim

Vizualizri
Vizualizarea (view) este un tabel logic (virtual) relativ la date din una sau mai
multe tabele sau vizualizri. Vizualizarea este definit plecnd de la o cerere a
limbajului de interogare a datelor, motenind caracteristicile obiectelor la care se
refer. Vizualizarea, fiind virtual, nu solicit o alocare de memorie pentru date. Ea
este definit n DD cu aceleai caracteristici ca i un tabel.
Textul cererii care definete vizualizarea este salvat n DD. Nucleul Oracle
determin fuzionarea cererii relative la vizualizare cu comanda de definire a
vizualizrii, analizeaz rezultatul fuziunii n zona partajat i execut cererea.
Oracle transform cererea referitoare la o vizualizare ntr-o cerere relativ
la tabelele de baz.
Dac sunt utilizate clauzele UNION, GROUP BY i CONNECT BY, atunci
Oracle nu determin fuzionarea, el va rezolva vizualizarea i apoi va aplica cererea
rezultatului obinut.
O vizualizare reflect la orice moment coninutul exact al tabelelor de baz.
Orice modificare efectuat asupra tabelelor se repercuteaz instantaneu asupra
vizualizrii. tergerea unui tabel implic invalidarea vizualizrilor asociate
tabelului i nu tergerea acestora.
Vizualizrile sunt definite pentru:
furnizarea unui nivel mai nalt de securizare a bazei;
simplificarea formulrii unei cereri;
mascarea complexitii datelor;
afiarea datelor ntr-o alt reprezentare dect cea a tabelelor de baz;
asigurarea independenei datelor;
asigurarea confidenialitii anumitor informaii;
definirea constrngerilor de integritate;
restricionarea acesului la date.

20

Oracle

Crearea unei vizualizri se realizeaz cu ajutorul comenzii:


CREATE [OR REPLACE][FORCE | NOFORCE] VIEW
[<nume_schema>.]<nume_view> [(<alias>[,<alias>])]
AS <cerere_SELECT>
[WITH {CHECK OPTION [CONSTRAINT <nume_constrangere>] |
READ ONLY }];
OR REPLACE recreeaz vizualizarea dac aceasta deja exist.
FORCE creeaz vizualizarea chiar dac tabelul de baz nu exist sau chiar dac
vizualizarea face referin la obiecte care nc nu sunt create. Dei vizualizarea
va fi creat, utilizatorul nu poate s o foloseasc.
NO FORCE este implicit i se refer la faptul c vizualizarea este creat numai
dac tabelele de baz exist.
Cererea este o comand SELECT care poate s conin alias pentru coloane.
WITH CHECK OPTION specific faptul c reactualizarea datelor din tabele
(inserare sau modificare) se poate face numai asupra datelor selectate de
vizualizare (care apar n clauza WHERE).
WITH READ ONLY asigur c nici o operaie LMD nu poate fi executat asupra
vizualizrii.
Exemplu:
S se genereze o vizualizare care conine informaii referitoare la mprumutul
crilor i n care s fie implementat constrngerea c orice carte, care exist ntrun singur exemplar, poate fi mprumutat maximum 15 zile.
CREATE VIEW imprumutare
AS SELECT
*
FROM
imprumuta
WHERE
codel NOT IN
(SELECT codel
FROM
carte
WHERE
nrex = 1)
OR
datares - dataim < 15
WITH CHECK OPTION;
Observaii:
Numrul coloanelor specificate n definiia vizualizrii trebuie s fie egal cu cel
din lista asociat comenzii SELECT.

SQL

21

Cererea ce definete o vizualizare poate conine cereri SELECT complexe care


includ subcereri, grupri, operaii de compunere.
Cererea care definete o vizualizare nu poate conine clauza ORDER BY.
Clauza poate fi specificat dac se fac interogri asupra vizualizrii.
Modificarea unei vizualizri presupune modificarea definiiei acesteia.
Pentru a nlocui o vizualizare trebuie avut privilegiul de sistem necesar pentru
distrugerea i crearea acesteia. nlocuirea se poate face n dou moduri.
Vizualizarea poate fi distrus (DROP VIEW) i apoi recreat (CREATE)
cu noua definiie. Atunci cnd este distrus, toate privilegiile sunt retrase.
Aceste privilegii trebuie s fie create pentru noua vizualizare.
Vizualizarea poate fi recreat prin redefinire cu instruciunea CREATE
VIEW, dar cu clauza OR REPLACE. Aceast metod conserv toate
privilegiile curente.
Modificarea unui vizualizri are urmtoarele efecte:
definiia vizualizrii din DD este actualizat;
nici unul din obiectele de baz nu este afectat de nlocuire;
toate restriciile care existau n vizualizarea original sunt distruse;
toate vizualizrile i programele PL/SQL dependente de vizualizarea
nlocuit devin invalide.
Suprimarea unei vizualizri se realizeaz prin comanda DROP VIEW care
terge definiia vizualizrii din baza de date.
DROP VIEW <nume_view>;
tergerea vizualizrii nu va afecta tabelele relativ la care a fost definit
vizualizarea. Aplicaiile i vizualizrile care se bazeaz pe vizualizarea suprimat
devin invalide. Pentru a suprima o vizualizare, utilizatorul trebuie s aib
privilegiul DROP ANY VIEW sau s fie creatorul vizualizrii respective.
Recompilarea unei vizualizri permite detectarea eventualelor erori
referitoare la vizualizare, naintea executrii vizualizrii. Dup fiecare modificare a
tabelelor de baz este recomandabil ca vizualizarea s se recompileze:
ALTER VIEW <nume_view> COMPILE;
Reactualizarea tabelelor implic reactualizarea corespunztoare a
vizualizrilor!!!

22

Oracle

Reactualizarea vizualizrilor implic reactualizarea tabelelor


de baz? NU! Exist restricii care trebuie respectate!!!
Nu pot fi nserate, terse sau actualizate date din vizualizri ce conin:
operatorul DISTINCT; clauzele GROUP BY, HAVING, START WITH,
CONNECT BY; pseudo-coloana ROWNUM; funcii grup; operatori de
mulimi.
Nu pot fi inserate sau actualizate date care ar nclca constrngerile din
tabelele de baz.
Nu pot fi inserate sau actualizate valorile coloanelor care rezult prin calcul.
Nu se pot face operaii LMD asupra coloanelor calculate cu DECODE.
Alturi de restriciile prezentate anterior, aplicabile tuturor vizualizrilor,
exist restricii specifice, aplicabile vizualizrilor bazate pe mai multe tabele.
Regula fundamental este c orice operaie INSERT, UPDATE sau
DELETE pe o vizualizare bazat pe mai multe tabele poate modifica datele doar din
unul din tabelele de baz.
Un tabel de baz al unei vizualizri este protejat prin cheie (key preserved
table) dac orice cheie selectat a tabelului este de asemenea i cheie a vizualizrii.
Deci, un tabel protejat prin cheie este un tabel ale crui chei se pstreaz i la nivel
de vizualizare. Pentru ca un tabel s fie protejat prin cheie nu este necesar ca
tabelul s aib toate cheile selectate n vizualizare. Este suficient ca, atunci cnd
cheia tabelului este selectat, aceasta s fie i cheie a vizualizrii.
Asupra unui join view pot fi aplicate instruciunile INSERT, UPDATE sau
DELETE, doar dac sunt ndeplinite urmtoarele condiii:
instruciunea LMD afecteaz numai unul dintre tabelele de baz;
n cazul instruciunii UPDATE, toate coloanele care pot fi reactualizate
trebuie s corespund coloanelor dintr-un tabel protejat prin cheie (n caz
contrar, Oracle nu va putea identifica unic nregistrarea care trebuie
reactualizat);
n cazul instruciunii DELETE, rndurile unei vizualizri pot fi terse numai
dac exist un tabel n join protejat prin cheie i numai unul (n caz contrar,
Oracle nu ar ti din care tabel s tearg);
n cazul instruciunii INSERT, toate coloanele n care sunt inserate valori
trebuie s provin dintr-un tabel protejat prin cheie;

SQL

23

ALL_UPDATABLE_COLUMNS,
DBA_UPDATABLE_COLUMNS
i
USER_UPDATABLE_COLUMNS sunt vizualizri din DD ce conin informaii
referitoare la coloanele vizualizrilor existente, care pot fi reactualizate.

Exmplu:
1. S se creeze un view ce conine cmpurile nume, prenume, job din tabelul
salariat.
2. S se insereze, s se actualizeze i s se tearg o nregistrare n acest view.
Ce efect vor avea aceste aciuni asupra tabelului de baz?
Soluie:
CREATE VIEW
AS SELECT
FROM

vederea2
nume, prenume, job
salariat;

Nu se pot face inserari deoarece view-ul nu conine cheia primar!


INSERT INTO vederea2
VALUES
('Popescu','Valentin','grafician');
va genera eroarea:
ORA-01400: cannot insert NULL into
("SCOTT"."SALARIAT"."COD_SALARIAT")
Actualizarea job-ului salariatului avnd numele "Popescu":
UPDATE
vederea2
SET
job = 'programator'
WHERE
nume = 'Popescu';
SELECT
nume, prenume, job
FROM
salariat;
tergerea nregistrrii referitoare la salariatul avnd numele "Popescu":
DELETE
vederea2
WHERE
nume = 'Popescu';
Operaiile care se realizeaz asupra view-ului se realizeaz i n tabelul
salariat. Pentru un caz mai general, cnd view-ul conine cheia extern a tabelului
de baz, sunt permise modificri ale view-ului, dac acestea nu afecteaz cheia
extern.

24

Oracle

Exemplu:
S se creeze un view care conine cmpurile nume, prenume, job din tabelul
salariat. S se introduc n view doar persoanele care sunt graficieni.
CREATE VIEW vederea21
AS SELECT
nume, prenume, job
FROM
salariat
WHERE
job = 'grafician'
WITH CHECK OPTION;
Exemplu:
S se creeze o vizualizare care s conin cod_salariat, nume, prenume din
tabelul salariat i coloana tip din tabelul grafician. Apoi s se insereze, s se
actualizeze i s se tearg o nregistrare din acest view (vizualizarea conine cheia
primar cod_salariat din tabelele salariat i grafician).
Soluie:
CREATE VIEW
AS SELECT
FROM
WHERE

vederea4
s.cod_salariat,nume,prenume,tip
salariat s, grafician g
s.cod_salariat=g.cod_salariat;

n cazul inserrii unei nregistrri pentru care se specific toate cmpurile:


INSERT INTO
vederea4
VALUES
(30,'Popescu','Valentin','artist plastic');
va apare urmtoarea eroare:
ORA-01776: cannot modify
through a join view

more

than

one

base

TABLE

Pot fi inserate date doar ntr-un tabel de baz (n oricare, dar n unul singur)
prin intermediul view-ului, astfel:
INSERT INTO vederea4 (cod_salariat, nume)
VALUES
(30, 'Popescu');
Comanda pentru tergerea unei nregistrri:
DELETE
vederea4
WHERE
cod_salariat = 3;
va genera urmtoarea eroare:

SQL

25

ORA-01752: cannot delete from view without exactly one


key-preserved TABLE.
Modificarea unei nregistrri se face prin secvena care urmeaz. Toate
actualizrile care se fac n view se fac i n tabelele de baz.
UPDATE
vederea4
SET
tip = 'designer'
WHERE
cod_salariat = 3;
Exemplu:
Care dintre coloanele unei vizualizri sunt actualizabile?
SELECT
column_name, updatable
FROM
user_updatable_columns
WHERE
table_name = 'vederea4';
Exemplu:
1. S se creeze un view (vederea3) care s conin, pentru fiecare categorie de
salariat, salariile medii i numrul de angajai din tabelul salariat.
2. S se insereze, s se actualizeze i s se tearg o nregistrare n view.
Soluie:
CREATE VIEW
AS SELECT
FROM
GROUP BY

vederea3 (nr, job, salmed)


COUNT(*), job, AVG(salariu)
salariat
job;

Nu se pot face inserri, actualizri sau tergeri ntr-un view ce conine funcii
grup. Dup oricare din aceste operaii apare acelai mesaj:
ORA-01732: data manipulation operation not legal on
this view
Exemplu:
S se creeze o vizualizare care s conin coloanele cod_contractant, adresa,
telefon din tabelul contractant i coloanele nr_contract, tip_contract,
data_incheiere din tabelul contract. S se insereze o nregistrare n vizualizare.
CREATE VIEW vederea44
AS SELECT
c.cod_contractant, adresa, telefon,
co.nr_contract, tip_contract,
data_incheiere

26

FROM
WHERE

Oracle

contractant c, contract co
c.cod_contractant=co.cod_contractant;

La inserarea unei nregistrri creia i se specific valorile tuturor cmpurilor


din ambele tabele:
INSERT INTO vederea44(cod_contractant, adresa,
nr_contract, data_incheiere)
VALUES
(200, 'Str. Marmurei, 14', '6235',
TO_DATE('January 03,2002','Month dd,yyyy'));
se obine eroarea:
ORA-01779: cannot modify a column which maps to a non
key-preserved TABLE
Cele dou tabele de baz, contractant i contract, se afl ntr-o relaie oneto-many, iar view-ul creat conine cheile primare din ambele tabele. Datorit
acestei situaii, doar tabelul contract este protejat prin cheie i, prin urmare, doar el
poate fi modificat prin intermediul view-ului. Aceasta, deoarece ar putea exista mai
multe nregistrri n view, cu aceeai valoare corespunztoare cmpului
cod_contractant (CP n contractant). Exact aceeai eroare se obine dac ncercm
inserarea unei nregistrri n vederea44, specificnd fie i numai un cmp
provenind din tabela contractant (indiferent dac el conine sau nu CP).
Singura operaie de inserare permis este aceea efectuat prin specificarea
cheilor provenind doar din tabelul contract. Astfel, prin executarea comenzii:
INSERT INTO vederea44(nr_contract, tip_contract)
VALUES
('6234', 0);
este creat o nregistrare, dar este modificat i tabelul contract. Dac la inserie nu
se specific cheia primar din contract:
INSERT INTO vederea44(tip_contract)
VALUES
(1);
ORA-01400: mandatory (NOT NULL) column is missing or
NULL during insert

Grupri

SQL

27

Cluster-ul este o regrupare fizic a dou sau mai multe tabele, relativ la una
sau mai multe coloane, cu scopul mririi performanelor. Coloanele comune
definesc cheia cluster-ului.
Un cluster este un obiect al bazei care necesit:
un nume unic la nivelul schemei,
specificare a coloanelor care compun cheia cluster-ului,
specificare a spaiului de stocare (opional),
un index (relativ la cheia cluster-ului).
Un cluster trebuie s aib cel puin un index. Acest index trebuie creat
naintea oricrei comenzi LMD care va aciona asupra tabelelor cluster-ului. Un
index al cluster-ului se deosebete de un index al tabelului (de exemplu, absena
indexului afecteaz utilizatorul datele cluster-ului nu sunt accesibile).
Coloanele comune definite pentru cluster, reprezint cheia cluster-ului i
criteriul de regrupare. Liniile diferitelor tabele sunt regrupate n interiorul aceluiai
bloc urmrind cheia cluster-ului. Dac liniile asociate unei aceiai valori a cheii
cluster-ului necesit un spaiu de mai multe blocuri, atunci blocurile sunt nlnuite.
Crearea unui cluster presupune:
crearea structurii cluster-ului;
crearea indexului cluster-ului;
crearea tabelelor care vor compune cluster-ul.
Crearea unui cluster:
CREATE CLUSTER nume_cluster
(nume_coloana tip_data [,nume_coloana tip_data] ) [SIZE n]
Exist dou modaliti pentru introducerea unui tabel ntr-un cluster.
O prim variant presupune c cluster-ul este creat pentru un tabel care deja
exist. De fapt, nu se poate asocia un cluster unui tabel care exist!
A doua variant presupune c introducerea tabelului n cluster se face n
momentul crerii structurii tabelului (comanda CREATE TABLE).
Exerciiu:
S se obin un cluster referitor la lista crilor din fiecare domeniu.
Varianta 1
CREATE CLUSTER cdoml(cdom

CHAR(1));

28

Oracle

CREATE INDEX indcom ON CLUSTER cdoml;


CREATE TABEL domino
CLUSTER cdoml(coded)
AS SELECT * FROM domeniu;
DROP TABEL domeniu;
RENAME domino TO domeniu;
ALTER TABLE carte
MODIFY
coded NOT NULL;
CREATE TABEL carticica
CLUSTER cdoml(coded)
AS SELECT * FROM carte;
DROP TABLE carte;
RENAME carticica TO carte;
Varianta 2
CREATE CLUSTER cdoml(cdom CHAR(1));
CREATE INDEX indcom ON CLUSTER cdoml;
-- crearea spatiului
CREATE TABLE domeniu
(coded
CHAR(1) NOT NULL,
intdom
CHAR() ... )
CLUSTER cdoml(coded);
CREATE TABLE carte
(codel
CHAR(5) NOT NULL,

coded CHAR(1) NOT NULL)


CLUSTER cdoml(coded);
Pentru a scoate un tabel dintr-un cluster sunt parcurse urmtoarele etape: se
creeaz un nou tabel, n afara cluster-ului, prin duplicarea celui vechi; se distruge
tabelul din cluster; se suprim cluster-ul.
CREATE TABLE alfa
AS SELECT * FROM domeniu;
DROP TABLE domeniu;
RENAME alfa TO domeniu;
CREATE TABLE beta
AS SELECT * FROM carte;
DROP TABLE carte;
RENAME beta TO carte;

SQL

29

DROP CLUSTER cdoml;


Un alt tip de cluster oferit de Oracle este cluster-ul hash. n acest caz, pentru
a accesa o nregistrare, cluster-ul hash nu folosete un index, ci o funcie numeric,
numit funcia hash. Funcia are ca parametru cheia cluster-ului i returneaz o
anumit valoare (valoare hash). Aceast valoare corespunde blocului de date din
cluster pe care Oracle l va citi sau scrie pe baza comenzii executate.
De exemplu, apelurile telefonice efectuate de un client ntr-o lun vor fi
facturate mpreun. Apelurile pot fi depozitate ntr-un cluster hash a crui cheie
este format din coloanele ce conin numrul telefonului, anul i luna n care a avut
loc convorbirea.
Suprimarea unui cluster din baza de date se face prin comanda:
DROP CLUSTER nume_cluster
n urma tergerii unui cluster, tabelele pe care acesta le conine nu mai sunt
grupate. Secvena urmtoare suprim: cluster-ul, toate tabelele definite relativ la
acest cluster i constrngerile lor de integritate.
DROP CLUSTER nume_cluster
INCLUDING TABLES
CASCADE CONSTRAINTS;
Modificarea unui cluster permite redefinirea condiiilor, modificarea
parametriilor de stocare i a caracteristicelor de stare (ALTER CLUSTER).

Informaii despre obiectele bazei de date

Pot fi obinute consultnd DD. Dintre ele se remarc:


definiiile tuturor obiectelor din baza de date;
spaiul alocat i spaiul utilizat n prezent de obiectele schemei;
constrngerile de integritate;
numele utilizatorilor bazei;
privilegiile i rolurile acordate fiecrui rol;
alte informaii generale despre baza de date.

Tabelul USER_CATALOG conine informaii despre tabelele i vizualizrile


definite de un utilizator particular. Acest tabel poate fi referit i prin sinonimul su
public CAT.
Tabelul USER_OBJECTS conine informaii despre toate obiectele definite
de utilizatorul curent. Tabelul are urmtoarea schem relaional:

30

Oracle

USER_OBJECTS (object_name, object_id, object_type, created, last_ddl_time,


timestamp, status)
Vizualizrile cele mai importante ale dicionarului datelor conin:
descrierea tabelelor definite de utilizatori (USER_ALL_TABLES),
informaii despre constrngerile definite de utilizator(USER_CONSTRAINTS),
informaii despre legturile bazei de date (USER_DB_LINKS),
erorile curente ale obiectelor depozitate (USER_ERRORS),
informaii despre indecii creai de utilizator (USER_INDEXES),
informaii despre tabelele utilizatorului (USER_TABLES) etc.
Vizualizrile din dicionarul datelor referitoare la tabele conin:
USER_TAB_COLUMNS|COLS informaii despre coloanele tabelelor,
USER_CONS_COLUMNS informaii despre constrngeri la nivel coloan,
USER_TAB_COMMENTS informaii despre comentarii la nivel tabel,
USER_COL_COMMENTS informaii despre comentarii la nivel coloan,
USER_TAB_PARTITIONS informaii despre partiiile tabelelor.

Limbajul de manipulare a datelor


SQL furnizeaz comenzi ce permit consultarea (SELECT) i actualizarea
(INSERT, UPDATE, DELETE) coninutului bazei de date. Aceste comenzi definesc
limbajul de manipulare a datelor (LMD).
Comenzile limbajului LMD pot fi:
formulate direct, utiliznd interfaa SQL*PLUS ;
utilizate n utilitare ale sistemului ORACLE;
ncapsulate ntr-un program PL/SQL ;

SQL

31

ncapsulate ntr-un program scris n limbaj gazd.


n funcie de momentul n care se dorete realizarea actualizrilor asupra
bazei de date, utilizatorul poate folosi una din urmtoarele comenzi:
SET AUTOCOMMIT ON schimbrile se efectueaz imediat;
SET AUTOCOMMIT OFF schimbrile sunt pstrate ntr-un buffer pn la
execuia uneia din comenzile:
COMMIT, care are rolul de a permanentiza schimbrile efectuate;
ROLLBACK, care determin renunarea la schimbrile realizate.

Comanda INSERT
INSERT INTO nume_tabel / nume_view [(col1[, col2[,]])]
VALUES (expresia1[, expresia2[,]]) / subcerere;
expresia1, expresia2, reprezint expresii a cror evaluare este atribuit
coloanelor precizate (se insereaz o linie);
subcerere, reprezint o interogare (se insereaz una sau mai multe linii).
Observaii:

Dac lipsete specificaia coloanelor se consider c sunt completate


toate cmpurile tabelului sau vizualizrii.

Dac nu a fost specificat lista coloanelor i dac exist cmpuri care nu


au valori efective, atunci valoarea null va fi atribuit acestor cmpuri.

Dac se introduc date doar n anumite coloane, atunci aceste coloane


trebuie specificate. n restul coloanelor se introduce automat null.

Specificarea cererii din comanda INSERT determin copierea unor date


dintr-un tabel n altul pe attea linii cte au rezultat din cerere.

Dac se introduc numai anumite cmpuri ntr-o nregistrare, atunci


printre acestea trebuie s se gseasc cmpurile cheii primare.

Pentru a putea executa comanda INSERT este necesar ca utilizatorul care


execut aceast instruciune s aib privilegiul de a insera nregistrri n
tabel sau n vizualizare.

Exemplu:

32

Oracle

S se insereze n tabelul carte toate crile din tabelul carte_info,


presupunnd c tabelul carte_info a fost deja creat. De asemenea, s se introduc o
nou carte creia i se cunoate codul (c34), titlul (algebra) i preul (500).
Soluie:
INSERT INTO
SELECT
FROM
INSERT INTO
VALUES

carte
*
carte_info;
carte(codel,titlu,autor,nrex,pret,coded)
(c34,algebra,null,null,500,null);

Exemplu:
INSERT INTO carte(codel, nrex)
VALUES ('c25', 25);
INSERT INTO domeniu
VALUES ('&cod','&intdom');inserare prin parametrizare
Exemplu:
Presupunnd c tabelul salariat a fost completat cu datele tuturor salariailor
editurii, s se completeze tabelele grafician, tehnoredactor i redactor_sef, n
concordan cu datele coninute n tabelul salariat (nu pot exista graficieni,
tehnoredactori sau redactori efi care s nu fie salariai!).
Soluie:
INSERT
SELECT
FROM
WHERE
INSERT
SELECT
FROM
WHERE
INSERT
SELECT
FROM
WHERE
Exemplu:

INTO grafician (cod_salariat)


cod_salariat
salariat
job = grafician;
INTO tehnoredactor (cod_salariat)
cod_salariat
salariat
job = tehnoredactor;
INTO redactor_sef (cod_salariat)
cod_salariat
salariat
job = redactor_sef;

SQL

33

Se dorete ca toi graficienii avnd salariile mai mari dect media salariilor
s colaboreze la realizarea tuturor frame-urilor din publicaii coordonate de
redactori efi avnd vechimea maxim. S se completeze tabelul realizeaza cu
nregistrrile corespunztoare.
Soluie:
INSERT

INTO realizeaza (cod_salariat, nr_publicatie,


nr_capitol, nr_frame)
s.cod_salariat,f.nr_publicatie, f.nr_capitol,
f.nr_frame
salariat s, frame f
s.salariu > (SELECT AVG(s1.salariu)
FROM
salariat s1)
job = 'grafician'
f.nr_publicatie IN
(SELECT p.nr_publicatie
FROM
salariat s2, publicatie p
WHERE
s2.cod_salariat = p.cod_salariat
AND
s2.vechime = (SELECT MAX(s3.vechime)
FROM
salariat s3));

SELECT
FROM
WHERE
AND
AND

Comanda DELETE
DELETE
[WHERE

[FROM] tablename / viewname


condiie]

Observaii:

Pentru a se putea executa instruciunea DELETE, utilizatorul care o


lanseaz n execuie trebuie s aib acest privilegiu.

Comanda DELETE nu terge structura tabelului.

n clauza WHERE pot fi folosite i subcereri.

Comanda nu poate fi folosit pentru tergerea valorilor unui cmp


individual. Acest lucru se poate realiza cu ajutorul comenzii UPDATE.

Atenie la tergere, pentru a nu afecta integritatea referenial!

Exemplu:

34

Oracle

S se elimine cititorii care au numele Popai cei care au restituit astzi cel
puin o carte.
DELETE FROM cititor
WHERE
nume=Popa
OR
codec IN (SELECT codec
FROM
imprumuta
WHERE
data_ef=SYSDATE);
Exemplu:
S se tearg toi tehnoredactorii care colaboreaz la mai puin de trei
publicaii.
Soluie:
DELETE
FROM salariat
WHERE
job = tehnoredactor
AND
COUNT
(SELECT DISTINCT c.nr_publicatie
FROM
capitol c
WHERE
c.cod_salariat = cod_salariat)< 3;

Comanda UPDATE
Valorile cmpurilor care trebuie modificate pot fi furnizate explicit sau pot fi
obinute n urma unei cereri SQL.
UPDATE
SET
[WHERE

tablename / viewname
(column1[,column2[,]]) = (subquery) / column = expr / (query)
condition]

Observaii:

Pentru a se putea executa instruciunea UPDATE, utilizatorul care o


lanseaz n execuie trebuie s aib acest privilegiu.

Dac nu este specificat clauza WHERE se vor modifica toate liniile.

Cererea trebuie s furnizeze un numr de valori corespunztor numrului


de coloane din paranteza care precede caracterul de egalitate.

Exemplu:

SQL

35

Preul crilor scrise de Lucian Blaga s fie modificat, astfel nct s fie egal
cu preul celei mai scumpe cri de informatic din bibliotec.
Soluie:
UPDATE
SET
WHERE

carte
pret = (SELECT
MAX(pret)
FROM
carte
WHERE
coded = I)
autor = Lucian Blaga;

Exemplu:
S se modifice preul crilor din bibliotec, care se gsesc ntr-un numr de
exemplare mai mic dect media numrului de exemplare pe bibliotec. Noua
valoare a preului s fie egal cu suma preurilor crilor scrise de Zola.
Soluie:
UPDATE
SET
WHERE

carte
pret = (SELECT
FROM
WHERE
nrex < (SELECT
FROM

SUM(pret)
carte
autor = Zola)
AVG(nrex)
carte);

Exemplu:
S se mreasc cu 5% salariile redactorilor efi care lucreaz la publicaia
care are cel mai mare numr de frame-uri.
Soluie:
UPDATE salariat
SET
salariu = 1,05*salariu
WHERE cod_salariat IN
(SELECT cod_salariat
FROM
publicatie
WHERE
nr_publicatie IN
(SELECT
nr_publicatie
FROM
frame
GROUP BY nr_publicatie
HAVING
COUNT(*) > ANY
(SELECT
COUNT(*)
FROM
frame

36

Oracle

GROUP BY

nr_publicatie)));

Exemplu:
S se reduc cu 10% salariile redactorilor efi care nu sunt asociai nici unei
publicaii.
Soluie:
UPDATE
SET
WHERE

salariat
salariu = 0,9*salariu
cod_salariat IN
(SELECT cod_salariat
FROM
redactor_sef
WHERE
cod_salariat NOT IN
(SELECT cod_salariat
FROM
publicatie));

Comanda SELECT
SELECT
FROM
[WHERE
[START WITH
[CONNECT BY
[GROUP BY
[HAVING
[ORDER BY
[FOR UPDATE

[ALL | DISTINCT]
{* | list de atribute selectate | expr AS alias}
{ [schema.]{tabel [PARTITION (partition_name)] |
[THE] (subquery)} [alias_tabel] }
condiie]
condiie]
condiie]
list de expresii
condiie]]
{expresie | poziie | c_alias} [ASC | DESC]]
[OF [schema.]{table | view}.coloan] [NOWAIT]

Clauzele START WITH i CONNECT BY sunt utile pentru a construi cereri


ierarhizate. Pentru a specifica nregistrarea rdcin a arborelui se va folosi clauza
START WITH. Dac aceast clauz este omis fiecare nregistrare din tabel poate fi
considerat ca nregistrare de start. Cu ajutorul clauzei CONNECT BY se pot
specifica coloanele (printe i copil) care particip la relaie. Prin ordinea
apariiilor acestor coloane (n condiie) se poate determina ordinea de parcurgere a
structurii arborescente (top-down sau bottom-up). Prin folosirea operatorului
PRIOR se poate face referin la nregistrarea printe.

SQL

37

Clauza FOR UPDATE permite blocarea coloanei (coloanelor) nainte de a


actualiza sau terge nregistrri din tabelele bazei de date. Prin folosirea clauzei
NOWAIT se va genera o excepie i nu se va mai atepta pn la ridicarea blocajelor
de pe nregistrri.
Operatorii utilizai (n ordinea prioritii de execuie) sunt:
operatori aritmetici (unari sau binari),
operatorul de concatenare ( || ),
operatorii de comparare (=, !=, ^=, < >, >, >=, <, <=, IN (echivalent cu
=ANY, adic egal cu cel puin una din valorile listei), NOT IN (echivalent cu
!=ALL, adic diferit de toate elementele listei), ALL, [NOT] BETWEEN x
AND y, [NOT] EXISTS, [NOT] LIKE, IS [NOT] NULL,
operatori logici (NOT, AND, OR).
Limbajul permite prezena unor instruciuni SELECT imbricate n oricare
din clauzele WHERE, HAVING sau FROM (instruciunile SELECT care apar n
clauzele respective se numesc subcereri).
n cazul folosirii subcererilor, pot fi utilizai operatorii ALL, ANY, IN
(=ANY), EXIST, NOT IN (!=ANY), care sunt specifici cererilor ce returneaz mai
multe linii (multiple-row subquery) sau operatorii de comparaie =, <, >, >=, <=,
<>, specifici cererilor care returneaz o singur linie (single-row subquery).
Executarea subcererilor se poate face:

fie cu sincronizare (corelat evaluarea subcererii face referin la o


coloan a cererii principale i cererea interioar se execut pentru fiecare
linie a cererii principale care o conine);

fie fr sincronizare (ncuibrit se execut mai nti cererea


interioar, iar rezultatul ei este transmis cererii de nivel imediat superior).

Exemplu:
n ce interogri este necesar utilizarea cuvntului cheie HAVING?
A. cnd este necesar s eliminm linii duble din rezultat;
B. cnd este necesar s ordonm mulimea rezultat;
C. cnd este necesar s efectum un calcul pe grup;

38

Oracle

D. cnd este necesar s restricionm grupurile de linii returnate.

Cererimonorela?ie
Exemplu:
S?seafiezedataioracurent?.
SELECT
FROM

TO_CHAR(SYSDATE,DD/MM/YY HH24:MI:SS)
DUAL;

Exemplu:
Utiliznd ideea c directorul este salariatul care nu are ef, s se tipreasc
numele directorului.
SELECT
ename,NVL(TO_CHAR(mgr),Nu are sef)
FROM
emp
WHERE
mgr IS NULL;
Exemplu:
S se afieze codurile cititorilor care nu au mprumutat cri ntr-un interval
precizat.
SELECT
DISTINCT codec
FROM
imprumuta
WHERE
dataim NOT BETWEEN &d1 AND &d2;

Clauza GROUP BY
Exemplele care urmeaz arat modul general de constituire a subansamblelor
virtuale folosind clauza GROUP BY. Fiecare expresie care apare n SELECT
trebuie s aib aceeai valoare pentru toate liniile care aparin aceleiai partiii.
Numele coloanelor din GROUP BY nu trebuie s figureze obligatoriu n lista de la
SELECT.
Exemplu:
S?seob?in?num?ruldecteoriafostmprumutat?
fiecarecarte.
SELECT
codel, COUNT(*)
FROM
imprumuta
GROUP BY codel;
Exemplu:

SQL

39

S se obin pentru fiecare autor, media preurilor crilor din bibliotec.


SELECT
autor, AVG(pret)
FROM
carte
GROUP BY
autor;
Exemplu:
Pentru departamentele n care salariul maxim depete 5000$ s se obin
codul acestor departamente i salariul maxim pe departament.
SELECT
deptno, MAX(sal)
FROM
emp
GROUP BY
deptno
HAVING
MAX(sal)>5000;
Exemplu:
S se afieze numele i salariul celor mai prost pltii angajai din fiecare
departament.
SELECT
ename, sal
FROM
emp
WHERE
(deptno, sal) IN
(SELECT
deptno, MIN(sal)
FROM
emp
GROUP BY deptno);
Exemplu:
S se obin numrul crilor mprumutate cel puin o dat.
SELECT
COUNT(DISTINCT codel)
FROM
imprumuta;
Exemplu:
S se afieze numrul crilor mprumutate cel puin de dou ori (pentru
fiecare carte mprumutat mai mult dect o dat s se obin numrul de cte ori a
fost mprumutat).
SELECT
COUNT(COUNT(codel))
FROM
imprumuta
GROUP BY
codel
HAVING
COUNT(*)>1;

40

Oracle

n cererea anterioar COUNT(codel), reprezint numrul care arat de cte


ori a fost mprumutat fiecare carte, iar COUNT(COUNT(codel)), reprezint
numrul total al crilor mprumutate.
Exemplu:
Lista codurilor cititorilor care au mai mult de 3 cri nerestituite la termen.
SELECT
codec
FROM
imprumuta
WHERE
dataef IS NULL AND datares < SYSDATE
GROUP BY codec
HAVING
COUNT(*) > 2;

Relaii ierarhice
SQL permite afiarea rndurilor unui tabel innd cont de relaiile ierarhice
care apar ntre rndurile tabelului. Parcurgerea n mod ierarhic a informaiilor se
poate face doar la nivelul unui singur tabel. Operaia se realizeaz cu ajutorul
clauzelor START WITH i CONNECT BY.
n comanda SELECT pot s apar clauzele:
CONNECT BY {expresie = PRIOR expresie | PRIOR expresie = expresie}
[START WITH conditie]
Clauza CONNECT BY specific coloanele prin care se realizeaz relaia
ierarhic. Operatorul PRIOR stabilete direcia n care este parcurs arborele. Dac
apare n stnga, atunci arborele este parcurs de sus n jos, iar dac apare n dreapta
arborele este parcurs de jos n sus. Clauza START WITH specific nodul
(nregistrarea de nceput) arborelui. Dac lipsete, orice nod poate fi rdcin.
Clauza SELECT poate conine pseudo-coloana LEVEL, care indic nivelul
nregistrrii n arbore (ct de departe este de nodul rdcin). Nodul rdcin are
nivelul 1, fii acestuia au nivelul 2 .a.m.d.
Exemplu:
Ierarhia poate fi reprezentat cu ajutorul unui tabel. De exemplu:
Se presupune c fiecare salariat are un singur superior (este o ierarhie). S se
afieze superiori ierarhic lui Ion.

SQL

41

SELECT LEVEL, nume


FROM
salariat
CONNECT BY nume = PRIOR nume_sef
START WITH nume = (SELECT nume_sef
FROM
salariat
WHERE
nume = Ion);

Cereri multi relaie


Comanda SELECT ofer posibilitatea de a consulta informaii care provin
din mai multe tabele. Operatorii care intervin n astfel de cereri pot fi: operatori pe
mulimi (UNION, UNION ALL, INTERSECT, MINUS) sau operatori compunere
care implementeaz diferite tipuri de join.
Exist dou moduri de realizare a cererilor multi-relaie:
forma procedural, n care trebuie indicat drumul de acces la informaie prin
imbricarea de comenzi SELECT;
forma relaional, n care drumul de acces la informaie este n sarcina
sistemului.
Exemplu:
S se obin, utiliznd aceste dou forme, codurile i titlurile crilor
mprumutate.
a) Forma procedural (imbricare de comenzi SELECT):
SELECT
codel, titlu
FROM
carte
WHERE
codel IN (SELECT
codel
FROM
imprumuta);
b) Forma relaional:
SELECT
carte.codel, titlu
FROM
carte, imprumuta
WHERE
carte.codel = imprumuta.codel;
Operatori pe mulimi (UNION, UNION ALL, INTERSECT, MINUS)
Comenzile SELECT, care intervin n cereri ce conin operatori pe mulimi,
trebuie s satisfac anumite condiii:
toate comenzile SELECT trebuie s aib acelai numr de coloane;
opiunea DISTINCT este implicit (excepie UNION ALL);

42

Oracle

numele coloanelor sunt cele din prima comand SELECT;


dimensiunea coloanei implicit este cea mai mare dintre cele dou coloane;
sunt admise combinaii de forma:
1. SELECT1 UNION SELECT2 INTERSECT SELECT3 i ordinea de
execuie este de la stnga la dreapta;
2. SELECT1 UNION (SELECT2 INTERSECT SELECT3) i ordinea
este dat de paranteze.
Exemplu:
S se obin, utiliznd operatorul INTERSECT, codurile crilor din care sunt
mai puin de 15 exemplare i care au fost mprumutate de cel puin trei ori.
SELECT
codel
FROM
carte
WHERE
nrex < 15
INTERSECT
SELECT
codel
FROM
imprumuta
GROUP BY codel
HAVING
COUNT(*) > 3;
Exemplu:
S se afieze codurile cititorilor care nu au mprumutat cri.
SELECT
codec
FROM
cititor
MINUS
SELECT
DISTINCT codec
FROM
imprumuta;
Operaii de compunere
Un join simplu (natural join) este o instruciune SELECT care returneaz
linii din dou sau mai multe tabele. Este preferabil ca tabelul care are linii mai
puine s fie al doilea n operaia de compunere. Comanda dureaz mai puin, dac
tabela este indexat dup coloana, relativ la care se face compunerea. Compunerea
a n tabele cere minim (n-1) condiii de join.
Exemplu:
S se obin codurile i titlurile crilor mprumutate.
SELECT
carte.codel, titlu

SQL

43

FROM
WHERE

carte, imprumuta
carte.codel = imprumuta.codel;

S-ar putea ca tabelele legate prin operaia de compunere s nu aib coloane


comune (non-equijoin). n acest caz n clauza WHERE nu apare operatorul egalitate
i sunt folosii operatorii: <=, >=, BETWEEN.
Pentru a simplifica scrierea i pentru a elimina ambiguitile care pot s
apar este necesar folosirea alias-ului pentru tabele. Alias-ul este valid doar pentru
instruciunea SELECT curent.
Exemplu:
S se obin pentru fiecare salariat numele, salariul i grila de salarizare ( join).
SELECT
e.ename, e.sal, s.grade
FROM
emp e, salgrade s
WHERE
e.sal BETWEEN s.lasal AND s.hisal;
Exemplu:
S se obin titlurile i preurile crilor mai scumpe dect cartea avnd titlul
Baze de date, al crui autor este Oszu (self join).
SELECT
x.titlu, x.pret
FROM
carte x, carte y
WHERE
x.pret > y.pret
AND
y.titlu = Baze de date
AND
y.autor = Oszu;
O alt variant de rezolvare a problemei, ca o cerere cu sincronizare:
SELECT
titlu, pret
FROM
carte x
WHERE
EXISTS
(SELECT *
FROM
carte
WHERE
carte.titlu=Baze de date
AND
carte.autor=Oszu
AND
x.pret > pret);
Dac o linie nu satisface condiia de join, atunci linia respectiv nu va apare
n rezultatul cererii. Pentru a evita aceast pierdere, n algebra relaional a fost
introdus operatorul outer-join.

44

Oracle

Un outer-join (join extern) este reprezentat prin operatorul (+) care este
plasat n clauza WHERE dup numele tabelului ale crui linii trebuie s nu se
piard din rezultatul cererii. Semnul (+) poate fi plasat n oricare parte a condiiei
din clauza WHERE, ns nu n ambele pri. Efectul operatorului (+) este c se
genereaz valori null pentru coloanele tabelului lng care apare scris, ori de cte
ori tabelul nu are nici o linie care s poat fi reunit cu o linie din cellalt tabel.
Exemplu:
S se obin titlurile crilor i numele domeniului cruia i aparin,
remarcnd situaiile n care domeniul nu ar avea cri (dac domeniul este fr cri
atunci apare null la titlul crii).
SELECT
titlu, intdom
FROM
carte, domeniu
WHERE
carte.coded(+) = domeniu.coded;

Exemplu:
Considerm c tabelele dept i emp au urmtorul coninut:
dept
emp
deptno
1
2

dname
algebra
analiza

empno
101
102
103
105
106

deptno
null
null
null
1
1

Interogarea urmtoare furnizeaz lista tuturor salariailor, inclusiv a celor


care nu sunt asignai nici unui departament (right outher join).
SELECT
a.deptno, a.dname, b.empno, b.deptno
FROM
dept a, emp b
WHERE
a.deptno(+) = b.deptno;
Rezultatul cererii anterioare va fi:
a.deptno a.dname b.empno b.deptno
101
102
103

SQL

45

1
1

algebra 105
algebra 106

1
1

Interogarea urmtoare afieaz lista departamentelor, inclusiv a celor care nu


au salariai (left outer join).
SELECT
a deptno, a.dname, b.empno, b.deptno
FROM
dept a, emp b
WHERE
a.deptno = b.deptno(+);
Rezultatul cererii anterioare va fi:
a.deptno a.dname b.empno
1
algebra 105
1
algebra 106
2
analiza null

b.deptno
1
1
null

Interogarea urmtoare produce ca rezultat departamentele, chiar i cele fr


funcionari, i funcionarii, chiar i cei care nu sunt asignai nici unui departament
(full outer join).
SELECT
NVL(TO_CHAR(b.empno),***) id,
NVL(a.dname,***) nume_dep
FROM
dept a, emp b
WHERE
a.deptno = b.deptno(+)
UNION
SELECT
NVL(TO_CHAR(b.empno),***) id,
NVL(a.dname,***) nume_dep
FROM
dept a, emp b
WHERE
a.deptno(+) = b.deptno;
Rezultatul cererii va fi:
id
***
101
102
103
105
106
Subcereri

nume_dep
analiza
***
***
***
algebra
algebra

46

Oracle

De cele mai multe ori, pentru a implementa anumite interogri, nu este


suficient o singur cerere SELECT ci sunt necesare subcereri. Subcererile sunt
comenzi SELECT ncapsulate n oricare din clauzele WHERE, HAVING, FROM.
Dac subcererea urmeaz clauzei WHERE sau HAVING, ea poate conine
unul dintre operatorii ALL, ANY, IN (=ANY), EXIST, NOT IN (!=ALL) care sunt
specifici cererilor care ntorc mai multe linii (multiple-row subquery) sau unul
dintre operatorii de comparare (=, <, >, >=, <=, <>) care sunt specifici cererilor
care ntorc o singur linie (single-row subquery).
Subcererile trebuie incluse ntre paranteze i trebuie plasate n partea dreapt
a operatorului de comparare. Subcererea nu poate conine ORDER BY.
Exemplu:
S se obin numele i salariul angajailor, avnd salariul minim.
SELECT
ename, sal
FROM
emp
WHERE
sal=(SELECT MIN(sal)
FROM
emp);
Exemplu:
S se obin job-ul i salariul mediu minim.
SELECT
job, AVG(sal)
FROM
emp
GROUP BY job
HAVING
AVG(sal)=(SELECT
MIN(AVG(sal))
FROM
emp
GROUP BY
job);
Operatorul ANY presupune c este adevrat condiia dac comparaia este
adevrat pentru cel puin una din valorile returnate. Sunt evidente relaiile:
< ANY mai mic ca maximul;
> ANY mai mare ca minimul;
= ANY IN.
Pentru operatorul ALL se presupune c este adevrat condiia, dac
comparaia este adevrat pentru toate elementele listei returnate. Pentru operatorul
ALL sunt evidente relaiile:
< ALL mai mic ca minimul;
> ALL mai mare ca maximul;
! = ALL NOT IN.

SQL

47

Exemplu:
WHERE codec > ALL (C1, C2) este superior tuturor elementelor din list;
WHERE codec > ANY (C1, C2) este superior cel puin unui element din
list.
Exemplu:
S se obin salariaii al cror salariu este mai mare ca salariile medii din
toate departamentele.
SELECT
ename, job
FROM
emp
WHERE
sal > ALL(SELECT
AVG(sal)
FROM
emp
GROUP BY
deptno);
Exist subcereri care au ca rezultat mai multe coloane (multiple-column
subquery). Aceste interogri au urmtoarea sintax general:
SELECT
FROM
WHERE

col,col,
tabel
(col,col,) IN (SELECT
FROM
WHERE

col,col,
tabel
condiie);

Exemplu:
S se obin numele, numrul departamentului, salariul i comisionul tuturor
funcionarilor ale cror salarii i comisioane coincid cu salariile i comisioanele
unor salariai din departamentul 7.
SELECT
ename, deptno, sal, com
FROM
emp
WHERE
(sal,NVL(com,-1)) IN
(SELECT
sal,NVL(com,-1)
FROM
emp
WHERE
deptno = 7);
Rezultatul acestei interogri este diferit de rezultatul urmtoarei interogri:
SELECT
ename, deptno, sal, com
FROM
emp

48

Oracle

WHERE
AND

sal IN (SELECT
sal
FROM
emp
WHERE
deptno=7)
NVL(com,-1) IN (SELECT
NVL(com,-1)
FROM
emp
WHERE
deptno=7);

Dac una din valorile returnate de subcerere este valoarea null atunci cererea
nu ntoarce nici o linie. Prin urmare, dac valoarea null poate s fac parte din
rezultatul subcererii nu trebuie utilizat operatorul NOT IN. Problema nu mai apare
dac se utilizeaz operatorul IN.
Exemplu:
S se obin salariaii care nu au subordonai.
SELECT
e.ename
FROM
emp e
WHERE
e.empno NOT IN (SELECT
FROM

m.mgr
emp m);

n acest caz, instruciunea SQL nu ntoarce nici o linie deoarece una din
valorile furnizate de subcerere este valoarea null.
Exemplu:
S se obin numele salariailor, salariile, codul departamentului n care
lucreaz i salariul mediu pe departament pentru toi angajaii care au salariul mai
mare ca media salariilor din departamentul n care lucreaz (folosirea subcererii n
clauza FROM).
SELECT a.ename,a.sal,a.deptno,b.salavg
FROM
emp a,(SELECT
deptno,avg(sal) salavg
FROM
emp
GROUP BY deptno) b
WHERE
a.deptno=b.deptno
AND
a.sal>b.salavg
Exemplu:
S se obin lista cititorilor care au mprumutat cel puin o carte.
SELECT
nume
FROM
cititor
WHERE
codec IN (SELECT DISTINCT codec

SQL

49

FROM

imprumuta);

Exemplu:
S se obin codurile cititorilor care nu au mprumutat niciodat cri.
SELECT
codec
FROM
cititor
WHERE
codec NOT IN
(SELECT DISTINCT codec
FROM
imprumuta);
Exemplu:
S se obin lista cititorilor care sunt n ntrziere cu predarea crilor.
Exemplu:
S se obin numele cititorilor care au mprumutat cel puin o carte scris de
ZOLA.
SELECT
nume
FROM
cititor
WHERE
codec IN
(SELECT DISTINCT codec
FROM
imprumuta
WHERE
codel IN
(SELECT codel
FROM
carte
WHERE
autor=ZOLA));
Exemplu:
S se obin numele cititorilor
ZOLA.
SELECT
nume
FROM
cititor
WHERE
codec NOT IN
(SELECT
FROM
WHERE

care nu au mprumutat nici o carte scris de

DISTINCT codec
imprumuta
codel IN
(SELECT codel
FROM
carte
WHERE
autor=ZOLA));

50

Oracle

Operatorul IN poate fi nlocuit cu = ANY (un element este n list dac i


numai dac este egal cu un element al listei), iar operatorul NOT IN poate fi
nlocuit prin !=ALL.
Exemplu:
S se obin codurile cititorilor care au mprumutat o carte de algebr.
SELECT
DISTINCT codec
FROM
imprumuta
WHERE
codel IN
(SELECT codel
FROMcarte
WHERE
coded=
(SELECT coded
FROM
domeniu
WHERE
intdom=ALGEBRA));
Exemplu:
S se obin cititorii care au mprumutat numai cri scrise de ZOLA.
SELECT
nume
FROM
cititor
WHERE
codec NOT IN
(SELECT DISTINCT codec
FROM
imprumuta
WHERE
codel NOT IN
(SELECT codel
FROM
carte
WHERE
autor=ZOLA));
Exemplu:
S se obin numele cititorilor care au mprumutat cel puin o carte de
informatic (procedural).
Exemplu:
S se obin, utiliznd sincronizarea subcererii cu cererea principal, titlurile
crilor care au toate exemplarele mprumutate (se selecteaz un titlu din carte i
pentru acest titlu se numr cte exemplare sunt mprumutate).
SELECT
titlu
FROM
carte
WHERE
nrex=(SELECT COUNT(*)

SQL

51

FROM
WHERE
AND

imprumuta
codel = carte.codel
dataef IS NULL);

Exemplu:
S se obin titlurile crilor al cror
din domeniul respectiv.
SELECT
titlu
FROM
carte c
WHERE
pret > (SELECT
FROM
WHERE

pre depete media preurilor crilor

AVG(pret)
carte
coded = c.coded);

Exemplu:
S se obin codurile cititorilor i codul ultimei cri mprumutate.
SELECT
codec, codel
FROM
imprumuta i
WHERE
dataim>=ALL (SELECT dataim
FROM
imprumuta
WHERE
codec=i.codec);
Pentru aceast interogare, clauza WHERE putea fi scris i sub forma:
WHERE
dataim=(SELECT
MAX(dataim)
FROM
imprumuta
WHERE
codec=i.codec);
Exemplu:
S se obin lista codurilor crilor mprumutate i codul primului cititor care
a mprumutat aceste crti.
SELECT
codel,codec
FROM
imprumuta i
WHERE
dataim<=ALL (SELECT dataim
FROM
imprumuta
WHERE
i.codel=codel);
Exemplu:
S se obin codurile crilor din care cel puin un exemplar este mprumutat.
SELECT
codel
FROM
carte
WHERE
EXISTS

52

Oracle

(SELECT
FROM
WHERE
AND

codel
imprumuta
codel = carte.codel
dataef IS NULL);

Operatorul WHERE EXISTS (subcerere) presupune c predicatul este


adevrat dac subcererea ntoarce cel puin un tuplu, iar WHERE NOT EXISTS
(subcerere) presupune c predicatul este adevrat dac subcererea nu ntoarce nici
un tuplu. EXISTS i NOT EXISTS cer sincronizarea subcererii.
Exemplu:
S se obin titlurile crilor care sunt momentan mprumutate.
Soluia 1 (cu sincronizare):
SELECT
titlu
FROM
carte
WHERE
EXISTS
(SELECT
FROM
WHERE
AND

*
imprumuta
codel = carte.codel
dataef IS NULL);

Soluia 2 (fr sincronizare):


SELECT
titlu
FROM
carte
WHERE
codel IN
(SELECT
FROM
WHERE

DISTINCT codel
imprumuta
dataef IS NULL);

Exemplu:
S se obin codurile crilor care nu au fost mprumutate niciodat.
Soluia 1 (cu sincronizare)
SELECT
codel
FROM
carte
WHERE
NOT EXISTS
(SELECT codel
FROM
imprumuta
WHERE
codel = carte.codel);
Soluia 2 (fr sincronizare)

SQL

53

SELECT
FROM
WHERE

codel
carte
codel NOT IN
(SELECT
FROM

DISTINCT codel
imprumuta);

Exemplu:
S se obin lista salariailor avnd salariul minim n departamentul n care
lucreaz.
SELECT
ename,sal
FROM
emp e
WHERE
sal=(SELECT MIN(sal)
FROM
emp
WHERE
deptno=e.deptno);
Exemplu:
S se obin numele primilor trei salariai avnd retribuia maxim (ideea
rezolvrii este de a verifica dac numrul salariailor care au leafa mai mare dect
leafa salariatului considerat, este mai mic dect 3).
SELECT
ename
FROM
emp a
WHERE
3>(SELECT
COUNT(*)
FROM
emp
WHERE
sal > a.sal);
Exemplu:
S se obin numele cititorilor care au mprumutat cel puin aceleai cri ca
i cititorul avnd codul C19 (ideea problemei este de a selecta cititorii pentru care
este vid lista crilor mprumutatede C19 mai puin lista crilor mprumutate de
acei cititori).
SELECT
nume
FROM
cititor
WHERE
NOT EXISTS
(SELECT codel
FROM
imprumuta
WHERE
codec=C19
MINUS
SELECT codel
FROM
imprumuta

54

Oracle

WHERE

codec= cititor.codec);

Dac problema era modificat n sensul c cel puineste nlocuit prin cel
mult atunci trebuiau inversate interogrile legate prin MINUS.
Exemplu:
S se obin codurile cititorilor care au mprumutat aceleai cri ca i
cititorul avnd un cod specificat.
Rezolvarea problemei se bazeaz pe urmtoarea idee: A = B A B i B
A (A-B) = i (B-A) = A-B i B-A nu furnizeaz nici un tuplu rezultat.
SELECT
FROM
WHERE

AND

AND

codec
imprumuta i
NOT EXISTS
(SELECT codel
FROM
imprumuta
WHERE
codec=i.codec
MINUS
SELECT codel
FROM
imprumuta
WHERE
codec=&ccc)
NOT EXISTS
(SELECT codel
FROM
imprumuta
WHERE
codec=&ccc
MINUS
SELECT codel
FROM
imprumuta
WHERE
codec=i.codec)
codec!=&ccc);

Ultimul operator (AND), asigur s nu apar n rezultat cititorul specificat.


n cazul formei relaionale de rezolvare a cererii, drumul de acces la
informaie este n sarcina SGBD-lui i prin urmare nu mai apar cereri imbricate.
Exemplu:
S se obin numele cititorilor care au mprumutat cel puin o carte.
Soluia 1 (forma relaional):
SELECT
DISTINCT nume
FROM
cititor,imprumuta

SQL

55

WHERE

cititor.codec=imprumuta.codec;

Soluia 2 (forma procedural):


SELECT
nume
FROM
cititor
WHERE
codec IN
(SELECT
DISTINCT codec
FROM
imprumuta);
Exemplu:
S se obin numele cititorilor care au mprumutat cel puin dou cri.
Soluia 1 (forma relaional):
Soluia 2 (forma procedural):
Exemplu:
S se obin numele cititorilor i titlurile crilor de informatic mprumutate
de aceti cititori.
SELECT
nume, titlu
FROM
cititor, carte, imprumuta, domeniu
WHERE
imprumuta.codel = carte.codel
AND
carte.coded = domeniu.coded
AND
imprumuta.codec = cititor.codec
AND
intdom = INFORMATICA;
Exemplu:
S se afieze numele, prenumele, salariul lucrtorilor, codurile publicaiilor
la care lucreaz i salariul mediu pe publicaie pentru toi angajaii care au salariul
mai mare dect media salariului pe publicaia respectiv.
Exemplu:
S se obin numele salariailor care nu cunosc nici o limb strin.
Exemplu:
S se afieze graficienii care au ntrziat s predea frame-urile.
a) cu sincronizare:
b) fr sincronizare:
Exemplu:
S se determine revistele coordonate de redactori efi care nu cunosc limba
n care sunt scrise. Se tie c n urma inspectrii vizuale a rezultatului interogrii se

56

Oracle

poate decide schimbarea redactorilor efi ai revistelor respective, de aceea se


dorete blocarea nregistrrilor gsite.
SELECT
p.nr_publicatie
FROM
salariat s, publicatie p
WHERE
s.cod_salariat = p.cod_salariat
AND
p.limba NOT IN
(SELECT limba_cun
FROM
limba
WHERE
limba.cod_salariat = s.cod_salariat)
FOR UPDATE OF p.cod_salariat;

Func?iinSQL

funcii pentru manipularea caracterelor,


funcii aritmetice,
funcii pentru manipularea datelor calendaristice,
funcii de conversie,
funcii grup
funcii diverse.

Funcii de conversie
Conversiile pot fi fcute:
implicit de ctre server-ul Oracle ;
explicit de ctre utilizator.
Conversii implicite
n cazul atribuirilor, sistemul poate converti automat:
VARCHAR2 sau CHAR n NUMBER ;
VARCHAR2 sau CHAR n DATE;
VARCHAR2 sau CHAR n ROWID;
NUMBER, ROWID, sau DATE n VARCHAR2.
Pentru evaluarea expresiilor, sistemul poate converti automat:
VARCHAR2 sau CHAR n NUMBER, dac irul de caractere reprezint un
numr;

SQL

57

VARCHAR2 sau CHAR n DATE, dac irul de caractere are formatul


implicit DD-MON-YY;
VARCHAR2 sau CHAR n ROWID.
Conversii explicite

funcia TO_CHAR convertete data calendaristic sau informaia


numeric n ir de caractere conform unui format;

funcia TO_NUMBER convertete un ir de caractere n numr;

funcia TO_DATE convertete un ir de caractere n dat calendaristic


conform unui format.

Dac formatul este omis, convertirea se face conform unui format implicit.
Funcia TO_DATE are forma TO_DATE(ir_de_caractere [,fmt]). Funcia este
utilizat dac se dorete conversia unui ir de caractere care nu are formatul
implicit al datei calendaristice (DD-MON-YY).
Alte funcii de conversie sunt: CHARTOROWID, CONVERT, HEXTORAW,
RAWTOHEX, ROWIDTOCHAR etc., iar denumirea semnificativ arat rolul
fiecreia.
Exemplu:
SELECT TO_DATE(Feb 22,1981,Mon dd,YYYY)
FROM DUAL;

Funcii pentru manipularea caracterelor

LENGTH(string) returneaz lungimea irului de caractere string;

LENGTHB(string) ndeplinete aceai funcie ca i LENGTH, cu


deosebirea c returneaz numrul de octei ocupai;

SUBSTR(string, start [,n]) returneaz subirul lui string care ncepe pe


poziia start i are lungimea n; dac n nu este specificat, subirul se
termin la sfritul lui string;

LTRIM(string [,chars]) terge din stnga irului string orice caracter


care apare n chars pn la gsirea primului caracter care nu este n
chars; dac chars nu este specificat, se terg spaiile libere din stnga lui
string;

RTRIM(string [,chars]) este similar funciei LTRIM, cu excepia


faptului c tergerea se face la dreapta irului de caractere;

58

Oracle

LPAD(string, length [,chars]) adaug chars la stnga irului de


caractere string pn cnd lungimea noului ir devine length; n cazul n
care chars nu este specificat, atunci se adaug spaii libere la stnga lui
string;

RPAD(string, length [,chars]) este similar funciei LPAD, dar


adugarea de caractere se face la dreapta irului;

REPLACE(string1, string2 [,string3]) returneaz string1 cu toate


apariiile lui string2 nlocuite prin string3; dac string3 nu este specificat,
atunci toate apariiile lui string2 sunt terse;

INITCAP(string) transform primul caracter al irului n majuscul;

INSTR(string, chars [,start [,n]]) caut n string, ncepnd de de la


poziia start, a n-a apariie a secvenei chars i ntoarce poziia
respectiv; dac start nu este specificat, cutarea se face de la nceputul
irului; dac n nu este specificat, se caut prima apariie a secvenei
chars;

UPPER(string), LOWER(string) transform toate literele irului de


caractere string n majuscule, respectiv minuscule;

ASCII(char) returneaz codul ASCII al unui caracter;

CHR(num) returneaz caracterul corespunztor codului ASCII


specificat;

CONCAT(string1, string2) realizeaz concatenarea a dou iruri de


caractere;

SOUNDEX(string) returneaz reprezentarea fonetic a irului de


caractere specificat;

TRANSLATE(string, from, to) fiecare caracter care apare n irurile de


caractere string i from este transformat n caracterul corespunztor (aflat
pe aceeai poziie ca i n from) din irul de caractere to;

Funcii aritmetice
Cele mai importante funcii aritmetice sunt: ABS (valoarea absolut),
ROUND (rotunjire cu un numr specificat de zecimale), TRUNC (trunchiere cu un
numr specificat de zecimale), EXP (ridicarea la putere a lui e), LN (logaritm
natural), LOG (logaritm ntr-o baz specificat), MOD (restul mpririi a dou
numere specificate), POWER (ridicarea la putere), SIGN (semnul unui numr),

SQL

59

COS (cosinus), COSH (cosinus hiperbolic), SIN(sinus), SQRT(rdcina ptrat),


TAN(tangent), funciile LEAST i GREATEST, care returneaz cea mai mic,
respectiv cea mai mare valoare a unei liste de expresii etc.

Funcii grup

AVG (media aritmetic),

COUNT(*) (numrul de linii returnate de o cerere),

COUNT (numrul valorilor unui expresii),

SUM (suma valorilor unei expresii),

MIN (valoarea minim a unei expresii),

MAX (valoarea maxim a unei expresii),

STDDEV (deviaia standard),

VARIANCE (dispersia).

Observaii:
Funciile grup opereaz pe un grup de linii i nu cer folosirea clauzei
GROUP BY.

Funciile grup ignor valorile null.

Orice funcie grup ntoarce o singur valoare.

Ele ntorc valoarea null cnd sunt aplicate unei mulimi vide, cu excepia
operatorului COUNT care ntoarce valoarea zero.

Spre deosebire de funciile COUNT, MIN i MAX care pot fi aplicate


unor cmpuri numerice sau nenumerice, restul funciilor grup se aplic
doar cmpurilor numerice.

Funciile grup pot s apar n lista de la SELECT sau n clauza HAVING.

Exemplu:
S se afieze numrul crilor distincte mprumutate.
SELECT
FROM

COUNT(DISTINCT codel)
imprumuta;

Exemplu:
Comanda care urmeaz este greit! De ce?

60

Oracle

SELECT
FROM

titlu, COUNT(*)
carte;

Exemplu:
S se calculeze media preurilor crilor din bibliotec.
SELECT
FROM

AVG(pret)
carte;

Funcii pentru manipularea datelor calendaristice

SYSDATE returneaz data i timpul curent;

ADD_MONTHS(d, count) returneaz data care este dup count luni de


la data d;

NEXT_DAY(d, day) returneaz urmtoarea dat dup data d, a crei zi a


sptmnii este cea specificat prin irul de caractere day;

LAST_DAY(d) returneaz data corespunztoare ultimei zile a lunii din


care data d face parte;

MONTHS_BETWEEN(d2, d1) returneaz numrul de luni dintre cele


dou date calendaristice specificate;

NEW_TIME(data, zona_intrare, zona_iesire) returneaz ora din


zona_intrare corespunztoare orei din zona_iesire;

ROUND(d) dac data d este nainte de miezul zilei, ntoarce data d cu


timpul setat la ora 12:00 AM; altfel, este returnat data corespunztoare
zilei urmtoare, cu timpul setat la ora 12:00 AM;

TRUNC(d) ntoarce data d, dar cu timpul setat la ora 12:00 AM (miezul


nopii);

LEAST(d1, d2, , dn), GREATEST(d1, d2, , dn) returneaz, dintr-o


list de date calendaristice, prima, respectiv ultima dat n ordine
cronologic.

Exemplu:
ROUND(25-jul-95, MONTH) este 01-AUG-95,
ROUND(25-jul-95, YEAR) este 01-JAN-96,
TRUNC(25-jul-95, MONTH) este 01-JUL-95,
TRUNC(25-jul-95, YEAR) este 01-JAN-95.

SQL

61

Utilizarea literelor mari sau mici n formatul unei date calendaristice


precizeaz forma rezultatului. De exemplu, MONTH va da rezultatul MAY, iar
Month va da rezultatul May.
Pentru afiarea cmpurilor de tip dat calendaristic sau pentru calcule n
care sunt implicate aceste cmpuri, exist funcii specifice. Cteva din elementele
care apar n formatul unei date calendaristice sunt prezentate n tabelul urmtor.
Format
SS
SSSSS
MI
HH
HH24
DAY
D
DD
DDD
MM
MON
MONTH
YY
YYYY
YEAR
CC
Q
W
WW

Descriere
Secunda relativ la minut
Secunda relativ la zi
Minut
Ora
Ora
Ziua sptmnii
Ziua sptmnii
Ziua lunii
Ziua anului
Numrul lunii
Numele prescurtat al lunii
Luna
Ultimele dou cifre ale anului
Anul
Anul n litere
Secolul
Numrul trimestrului
Sptmna lunii
Sptmna anului

Domeniu

0-59
0-86399
0-59
0-12
0-24
SUNDAY-SATURDAY
1-7
1-31 (depinde de lun)
1-366 (depinde de an)
1-12
JAN-DEC
JANUARY-DECEMBER
de exemplu, 99
de exemplu, 1999
de exemplu, 17
1-4
1-5
1-52

Operaii cu date calendaristice


Operaie
Data + numr
Data - numr
Data - data
Data + numar/24

Rezultat
Data
Data
Numr zile
Data

Funcii diverse

Descriere
Adaug un numr de zile la o dat
Scade un numr de zile dintr-o dat
Scade dou date calendaristice
Adun un numr de ore la o dat

62

Oracle

DECODE(value, if1, then1, if2, then2, , ifN, thenN, else) returneaz


then1 dac value este egal cu if1, then2 dac value este egal cu if2 etc.;
dac value nu este egal cu nici una din valorile if, atunci funcia ntoarce
valoarea else (selecie multipl);

NVL(e1, e2) dac e1 este NULL, returneaz e2; altfel, returneaz e1;

UID returneaz ID-ul utilizatorului curent;

USER returneaz username-ul utilizatorului curent;

VSIZE(expr) returneaz numrul de octei ai unei expresii de tip DATE,


NUMBER sau VARCHAR2;

EMPTY_BLOB iniializeaz o variabil sau o coloan de tip BLOB;

NLS_CHARSET_NAME(id_set_caractere) returneaz numele setului


de caractere NLS asociat cu identificatorul setului transmis ca argument.
Aceast funcie nu exist n versiuni anterioare Oracle8.

Exemplu:
NVL(comision, 0) este 0 dac comisionul este null. Prin urmare, expresia
salariu*12 + comision nu este corect, deoarece rezultatul su este null dac
comisionul este null. Forma corect este salariu*12 + NVL(comision, 0).

Exemplu:
S se afieze preul modificat al unor cri n funcie de editur. Pentru crile
din editura ALL s se dubleze preurile, pentru cele din editura UNIVERS s se
tripleze preurile, iar pentru cele din editura XXX s se reduc la jumtate acest pre.
SELECT
pret,editura,
DECODE(editura, ALL,pret*2,
UNIVERS,pret*3,
XXX,pret/2,
pret) pret_revizuit
FROM
carte;

SQL

63

LIMBAJUL PENTRU CONTROLUL DATELOR


Sistemul de gestiune trebuie:

s pun la dispoziia unui numr mare de utilizatori o mulime coerent


de date;

s garanteze coerena datelor n cazul manipulrii simultane de ctre


diferii utilizatori.
Coerena este asigurat cu ajutorul conceptului de tranzacie. Tranzacia este
unitatea logic de lucru constnd din una sau mai multe instruciuni SQL, care
trebuie s fie executate atomic (ori se execut toate, ori nu se execut nici una!),
asigurnd astfel trecerea BD dintr-o stare coerent n alt stare coerent.
Dac toate operaiile ce constituie tranzacia sunt executate i devin efective,
spunem c tranzacia este validat, iar modificrile aduse de tranzacie devin
definitive.
Dac dintr-un motiv sau altul (neverificarea condiiilor, accesul imposibil) o
operaie a tranzaciei nu a fost executat spunem c tranzacia a fost anulat.
Modificrile aduse de toate operaiile tranzaciei anulate sunt i ele anulate i se
revine la starea bazei de date de dinaintea tranzaciei anulate.
Este posibil ca o tranzacie s fie descompus n subtranzacii, astfel nct
dac este necesar s se anuleze doar parial unele operaii.
Fiecare tranzacie se poate termina:

normal (commit);

anormal (rollback).

Controlul tranzaciilor const n:

definirea nceputului i sfritului unei tranzacii,

validarea sau anularea acesteia,

eventual descompunere n subtranzacii.

Limbajul pentru controlul datelor (LCD) permite salvarea informaiei,


realizarea fizic a modificrilor n baza de date, rezolvarea unor probleme de
concuren. Limbajul conine urmtoarele instruciuni:
COMMIT - folosit pentru permanentizarea modificrilor executate asupra
BD (modificrile sunt nregistrate i sunt vizibile tuturor utilizatorilor);

64

Oracle

ROLLBACK - folosit pentru refacerea strii anterioare a BD (sunt anulate


toate reactualizrile efectuate de la nceputul tranzaciei);
SAVEPOINT - folosit n conjuncie cu instruciunea ROLLBACK, pentru
definirea unor puncte de salvare n fluxul programului.
O tranzacie const:
dintr-o singur instruciune LDD;
dintr-o singur instruciune LCD;
din instruciuni LMD care fac schimbri consistente n date.
Tranzacia ncepe:
dup o comand COMMIT,
dup o comand ROLLBACK,
dup conectarea iniial la Oracle,
cnd este executat prima instruciune SQL.
Tranzacia se termin:
dac sistemul cade;
dac utilizatorul se deconecteaz
dac se dau comenzile COMMIT sau ROLLBACK ;
dac se execut o comand LDD.

Dup ce se termin o tranzacie, prima instruciune SQL executabil va


genera automat nceputul unei noi tranzacii.
Un commit apare automat cnd este executat o comand LDD, sau o
comand LCD, sau dup o ieire normal din SQL*Plus fr specificarea explicit a
comenzilor COMMIT sau ROLLBACK. Un rollback apare automat dup o ieire
anormal din SQL*Plus sau o cdere sistem.
Din momentul n care s-a executat instruciunea COMMIT, BD s-a modificat
(permanent) n conformitate cu instruciunile SQL executate n cadrul tranzaciei
care tocmai s-a terminat. Din acest punct ncepe o nou tranzacie.
Dac se folosete utilitarul SQL*Plus, exist posibilitatea ca dup fiecare
comand LMD s aib loc o permanentizare automat a datelor (un COMMIT
implicit). Acest lucru se poate realiza folosind comanda:

SQL

65

SETAUTO[COMMIT]{ON|OFF]
Comanda ROLLBACK permite restaurarea unei stri anterioare a BD.
ROLLBACK [TO [SAVEPOINT] savepoint];
Dac nu se specific nici un savepoint, toate modificrile fcute n tranzacia
curent sunt anulate, iar dac se specific un anumit savepoint, atunci doar
modificrile de la acel savepoint pn n momentul respectiv sunt anulate.
Executarea unei instruciuni ROLLBACK presupune terminarea tranzaciei curente
i nceperea unei noi tranzacii.
Punctele de salvare pot fi considerate ca nite etichete care refer o
submulime a schimbrilor dintr-o tranzacie, marcnd efectiv un punct de salvare
pentru tranzacia curent. Server-ul Oracle implementeaz un punct de salvare
implicit pe care l mut automat dup ultima comand LMD executat. Dac este
creat un punct de salvare avnd acelai nume cu unul creat anterior, cel definit
anterior este ters automat.
SAVEPOINT savepoint;
Exemplu:
Comanda ROLLBACK nu va genera terminarea tranzaciei.
COMMIT
INSERT
SAVEPOINT a
UPDATE
INSERT
SAVEPOINT b
DELETE
ROLLBACK TO a
Starea datelor nainte de COMMIT sau ROLLBACK este urmtoarea:
starea anterioar a datelor poate fi recuperat;
utilizatorul curent poate vizualiza rezultatele operaiilor LMD prin
interogri asupra tabelelor;
ali utilizatori nu pot vizualiza rezultatele comenzilor LMD fcute de
utilizatorul curent (read consistency);
nregistrrile afectate sunt blocate i, prin urmare, ali utilizatori nu pot
face schimbri n datele acestor nregistrri.

66

Oracle

Execuia unei comenzi COMMIT implic anumite modificri.


Toate schimbrile (INSERT, DELETE, UPDATE) din baza de date fcute
dup anterioara comand COMMIT sau ROLLBACK sunt definitive.
Comanda se refer numai la schimbrile fcute de utilizatorul care d
comanda COMMIT.
Toate punctele de salvare vor fi terse.
Starea anterioar a datelor este pierdut definitiv.
Toi utilizatorii pot vizualiza rezultatele.
Blocrile asupra liniilor afectate sunt eliberate; liniile pot fi folosite de ali
utilizatori pentru a face schimbri n date.
Execuia unei comenzi ROLLBACK implic anumite modificri.
Anuleaz tranzacia n curs i toate modificrile de date fcute dup
ultima comand COMMIT.
Sunt eliberate blocrile liniilor implicate.
Nu terge un tabel creat prin CREATE TABLE. Eliminarea tabelului se
poate realiza doar prin comanda DROP TABLE.
Exemplu:
Ce efect are urmtoarea secven de instruciuni?
(a) SELECT
*
FROM
salariat;
(b) SAVEPOINT

a;

(c) DELETE FROM salariat;


INSERT INTO salariat
VALUES (18,Breaban,Marin,4,5000, tehnored);
INSERT INTO salariat
VALUES (23,Popescu,Emil,7,40000,grafician);
SAVEPOINT
b;
(d) INSERT INTO salariat
VALUES (29,,,5,3000000,tehnoredactor);
SELECT
AVG(salariu)
FROM
salariat;

SQL

67

(e) ROLLBACK TO
SELECT
FROM

b;
AVG(salariu)
salariat;

(f) ROLLBACK TO a;
INSERT INTO salariat
VALUES
(18,Ion,Mihai,5,580,redr_sef);
COMMIT;
ntr-un sistem multi-user, sistemul Oracle furnizeaz read consistency la
nivel de instruciune SQL, adic o singur comand SQL nu poate da rezultate care
sunt contradictorii sau inconsistente. Read consistency asigur c fiecare utilizator
vede datele aa cum existau la ultimul commit, nainte s nceap o operaie
LMD. Prin urmare, modificrile efectuate asupra unei baze de date nu sunt vizibile
dect dup ce operaia de actualizare a fost validat. Numai utilizatorul care a
executat tranzacia poate vedea modificrile fcute de el n cursul acestei tranzacii.
Modelul multiversiune, furnizat de Oracle, asigur consistena la citire:
garanteaz c setul de date vzut de orice instruciune SQL este consistent i
nu se schimb n timpul execuiei unei instruciuni (Oracle asigur o
consisten la citire la nivel de instruciune);
operaiile de citire(SELECT) nu trebuie s vad datele care sunt n proces de
schimbare;
operaiile de scriere (INSERT, DELETE, UPDATE) nu trebuie s afecteze
consistena datelor i s ntrerup sau s intre n conflict cu alte operaii de
scriere concurente.
Cum se implementeaz modelul multiversiune? Dac asupra bazei este
executat o comand LMD, server-ul Oracle face o copie a datelor dinainte de
modificare i o depune n segmentul rollback. Toi utilizatorii (cu excepia celor
care modific datele) vor vedea datele cum sunt nainte de modificare (vd
coninutul segmentului rollback). Dac comanda LMD este commit, atunci
schimbrile din baza de date devin vizibile oricrui utilizator care folosete
instruciunea SELECT. Cnd se termin tranzacia, spaiul ocupat n segmentul
rollback de vechea dat este liber pentru reutilizare. Server-ul Oracle asigur
astfel o vizualizare consistent a datelor n orice moment.

68

Oracle

Blocrile sunt folosite n ORACLE pentru a asigura integritatea datelor,


permind n acelai timp accesul concurent la date de ctre un numr infinit de
utilizatori.
Din punct de vedere a resursei blocate, blocrile pot fi:
la nivel de linie (blocarea afecteaz un rnd);
nivel de tabel (blocarea afecteaz ntreg tabelul).
La nivel de rnd, blocrile se pot face numai n modul exclusiv (X), adic un
utilizator nu poate modifica un rnd pn ce tranzacia care l-a blocat nu s-a
terminat (prin permanentizare sau prin derulare napoi).
Blocrile la nivel de tabel pot fi fcute n mai multe feluri, n funcie de
caracterul mai mult sau mai puin restrictiv al blocrii (RS row share; RX row
exclusive; S share; SRX share row exclusive; X exclusive).
Modul X de blocare la nivel de tabel este cel mai restrictiv. Blocarea n
mod X este obinut la executarea comenzii LOCK TABLE cu opiunea
EXCLUSIVE. O astfel de blocare permite altor tranzacii doar interogarea
tabelului. Tabelul nu mai poate fi blocat n acelai timp de nici o alt
tranzacie n nici un mod.
Modul de blocare RX arat c tranzacia care deine blocarea a fcut
modificri asupra tabelului. O blocare RX permite acces (SELECT,
INSERT, UPDATE, DELETE) concurent la tabel i blocarea concurent a
tabelului de ctre alt tranzacie n modurile RS i RX.
Modul de blocare S (se obine prin comanda LOCK TABLE cu opiunea
SHARE) permite altor tranzacii doar interogarea tabelului i blocarea sa
n modurile S i RS.
Modul de blocare SRX (se obine prin comanda LOCK TABLE cu
opiunea SHARE ROW EXCLUSIVE) permite altor tranzacii doar
interogarea tabelului i blocarea sa n modul RS.
Modul de blocare RS permite acces (SELECT, INSERT, UPDATE,
DELETE) concurent la tabel i blocarea concurent a tabelului de ctre
alt tranzacie n orice mod, n afar de X. Modul de blocare RS, care este
cel mai puin restrictiv, arat c tranzacia care a blocat tabelul, a blocat
rnduri din tabel i are intenia s le modifice.
Din punct de vedere a modului de declanare a blocrii, blocrile pot fi:

SQL

69

implicite (blocarea este fcut automat de sistem n urma unei operaii


INSERT, DELETE sau UPDATE i nu necesit o aciune din partea
utilizatorului);

explicite (blocarea este declanat ca urmare a comenzilor LOCK TABLE


sau SELECT cu clauza FOR UPDATE).

Folosirea clauzei FOR UPDATE ntr-o comand SELECT determin blocarea


rndurilor selectate n modul X i blocarea ntregului tabel (sau tabelelor) pe care se
face interogarea n modul RS. La actualizarea rndurilor (UPDATE) blocarea la
nivel de linie se menine n timp ce blocarea la nivel de tabel devine RX.
Exemplu:
SELECT salariu
FROM
salariat
WHERE
cod_salariat = 1234
FOR UPDATE OF salariu;
UPDATE
SET
WHERE

salariat
salariu = 23456
cod_salariat = 1234;

COMMIT;
La executarea primei comenzi, rndul cu cod_salariat = 1234 este blocat n
mod X n timp ce tabelul salariat este blocat n modul RS. La executarea celei de a
doua comenzi, blocarea la nivel de linie se menine n timp ce blocarea la nivel de
tabel devine RX. La executarea comenzii COMMIT, tranzacia este permanentizat
i toate blocrile sunt eliberate.
Unul sau mai multe tabele pot fi blocate n oricare din modurile prezentate
mai sus folosind comanda LOCK TABLE, care are sintaxa:
LOCK TABLE nume_tabel [, nume tabel]
IN mod_blocare MODE [NOWAIT]
unde mod_blocare poate avea valorile ROW SHARE, ROW EXCLUSIVE, SHARE,
SHARE ROW EXCLUSIVE, EXCLUSIVE. Dac se specific NOWAIT i rndurile
selectate sunt deja blocate de alt tranzacie, atunci utilizatorul este ntiinat de
acest lucru, returnndu-i-se controlul.
Datorit accesului concurent la date este posibil ca mai muli utilizatori s se
blocheze reciproc. Aceast situaie este numit interblocare (deadlock), pentru c
fiecare dintre utilizatori ateapt ca cellalt s elibereze resursa blocat. n cazul

70

Oracle

acesta problema nu se poate rezolva prin simpla ateptare, una din tranzacii
trebuind s fie derulat napoi. Oracle detecteaz automat interblocrile. n acest
caz, Oracle semnaleaz o eroare uneia dintre tranzaciile implicate i deruleaz
napoi ultima instruciune din aceast tranzacie. Acest lucru rezolv interblocarea,
dei cealalt tranzacie poate nc s atepte pn la deblocarea resursei pentru care
ateapt.
Care din urmtoarele comenzi ncheie o tranzacie?
SELECT
ROLLBACK
UPDATE
DELETE
CREATE TABLE