Sunteți pe pagina 1din 74

32

Capitolul II
Structurarea bazelor de date
Scurt istoric
n anii '60, A.F. Codd, cercettor la I.B.M., a studiat posibilitatea
ameliorrii modului de stocare a datelor n fiiere deoarece existena informaiilor
redundante predispunea la erori greu de depistat. n 1970 a publicat un articol,
"A Relational Model of Data for Large Shared Databanks" care a schimbat
complet concepiile privind structura bazelor de date. Un programator, Larry
Ellison, sesiznd importana practic a teoriei lui Codd, a realizat un produs
software, Oracle, i o firm pentru promovarea acestuia, Oracle Corporation. L.
Ellison a devenit astfel unul dintre cei mai bogai oameni de pe planet.

Anomalii rezolvate de modelul relaional


S presupunem c ntr-o bibliotec, bibliotecara pstreaz evidena
crilor cu ajutorul calculatorului, ntr-un fiier pentru cri avnd urmtoarea
structur:

NrInv

Autor

Titlu

Editura

Locul

Anul
apariiei

Avnd n vedere posibilitile unui calculator legate de parcurgerea


fiierelor, s-ar prea c vor putea fi realizate uor o mulime de rapoarte. n
timpul exploatrii pe calculator a fiierului s-au depistat ns probleme cauzate
de modul de structurare a informaiilor.
1. Anomalia la actualizarea datelor:
Conducerea bibliotecii a impus ca numele autorului s fie scris cu
majuscule. Pentru autorii mai puin prolifici nu e nici o problem, dar unii se
regsesc n fiier de zeci sau chiar sute de ori. Modificarea n sute de locuri a
aceluiai nume poate conduce la erori greu de depistat. Aceast anomalie poart
numele de anomalia la actualizare. Pentru eliminarea ei, modelul relaional
propune structurarea informaiilor n dou tabele: un tabel cu numele autorilor i
un tabel cu cri:

CodAutor

NrInv

Autor

CodAutor

Titlu

Editura

Locul

Anul apariieie

33
n momentul nregistrrii unei cri, dac autorul exista deja n tabelul de
autori, i se noteaz codul care apoi este folosit la nregistrarea crii. Dac
autorul nu exist n fiierul de autori, el va fi adugat, n momentul adugrii
atribuindu-se un cod. n acest mod, modificarea numelui autorilor se realizeaz
simplu, numele fiecrui autor aprnd o singur dat.
2. Anomalia la tergerea datelor:
Aceast anomalie poate aprea dac se cere tergerea din fiierul de cri
a nregistrrii corespunznd unei cri pierdute. Odat cu titlul crii se terge i
editura care a publicat-o. Ulterior, dac se dorete realizarea unui raport privind
editurile cu care biblioteca are relaii, n raport nu va mai figura editura care a
realizat cartea suprimat. Acest anomalie poart numele de anomalia la
tergerea datelor.
3. Anomalia la adugarea datelor:
Dac se dorete nregistrarea n baza de date a bibliotecii a datelor unei
noi edituri, n modelul elaborat acest lucru nu este posibil fr adugarea unei
prime cri achiziionate de la aceasta. Dac nu s-a cumprat nici o carte, baza
noastr prezint o anomalie la adugarea datelor.

Normalizarea
Modelul relaional elaborat de Codd propune soluii pentru eliminarea
acestor anomalii. Procesul de structurare a bazei de date n vederea eliminrii
anomaliilor sesizate poart numele de normalizare. Normalizarea const n
aducerea bazei de date ntr-una dintre formele normale, cele mai importante
fiind cele 3 forme prezentate n continuare.
1. Prima form normal
Prima form normal cere ca tabelele n care sunt pstrate informaiile s
satisfac urmtoarelor cerine:
a. Fiecare coloan trebuie s pstreze o informaie elementar (care nu se
mai poate descompune). n exemplul prezentat, dac o carte are mai
muli autori coloana CodAutor ar trebui s conin mai multe coduri,
deci acest mod de structurare nu respect aceast cerin.
b. Fiecare coloan trebuie s aib un nume unic;
c. Tabelul nu poate avea dou linii coninnd informaii identice. Fiecare
tabel din componena unei baze de date normalizate conine o cheie
primar. O cheie primar este un cmp care are valori distincte
pentru toate liniile tabelului. Uneori, mai rar, cheia primar este
obinut prin alturarea valorilor dintr-un ansamblu de mai multe
cmpuri. Pot exista n baza de date tabele care nu au o cheie primar.
Tabelele pentru care s-a definit o cheie primar respect, de regul,
cerina enunat.

34
d. ntr-un tabel nu se admit grupuri de informaii care se repet. n
exemplul dat Editura i Locul formeaz un grup care probabil se repet
pentru toate crile provenind de la aceeai editur.
2. A doua form normal
A doua form normal se refer la tabelele care au o cheie compus din
valorile mai multor cmpuri. Astfel, n exemplul dat dac datele editurii sunt
pstrate ntr-un tabel separat avnd structura:

NumeEd

Oras

Adresa

NumeScurt

Telefon

atunci adugarea unui nou sediu pentru o editur va face ca valoarea din coloana
"NumeScurt" s apar repetat, deoarece ea nu depinde de sediul editurii ci de
numele acesteia. Pentru a satisface cerinele celei de-a doua forme normale,
coloanele unui tabel trebuie s depind direct de toate cmpurile care formeaz o
cheie primar compus.
3. A treia form normal
A treia form normal rezolv anomalia care apare n cazul n care ntr-un
tabel exist una sau mai multe coloane ale cror valori nu depind direct de
valoarea cheii primare. n exemplul dat, s presupunem c n tabelul n care
sunt nregistrate crile exist o coloan care conine numele furnizorului (firma
prin care s-a achiziionat cartea). Cu siguran c prin acelai furnizor s-au
achiziionat i alte cri, deci numele acestuia va aprea pe mai multe linii
deoarece furnizorul nu depinde direct de carte. Coloanele unui tabel care
satisface a treia form normal conin informaii care depind direct de cheia
primar.

Relaii ntre tabelele unei baze de date


Pentru a satisface cerinele impuse de cele 3 forme normale prezentate,
informaiile sunt de regul pstrate ntr-un ansamblu de tabele ntre care exist
relaii de diferite tipuri.
1. Relaii 1 la mai muli (1 la n, one to many)
Dac n exemplul considerat datele privind o editur sunt pstrate ntr-un
fiier iar crile sunt nregistrate n alt fiier, ntre cele dou tabele se stabilete o
dependen de tip "unul la mai muli".

35

cod editur
Edituri
CodE

Nume Adresa Telefon

editura

NrInv

CodA

Titlu

CodE

Anul Carti

cod autor
carte

Acest tip de relaie este cel mai frecvent ntlnit i st la baza modelului
relaional elaborat de Codd.
Cheile primare din cele dou tabele sunt CodE pentru Edituri i NrInv
pentru Cri. n tabelul de cri, CodE i CodA (cod autor) sunt chei strine. O
cheie strin dintr-un tabel A permite regsirea unei linii dintr-un tabel asociat,
B. n tabelul asociat, B, cheia strin din tabelul A este de regul cheie primar.
n cazul dat, cheia strin CodA permite regsirea n tabelul de autori a numelui
acestuia iar cheia strin CodE permite gsirea numelui editurii care a publicat
cartea.
2. Relaii 1 la 1 (one to one)
O relaie de tipul 1 la 1 apare n cazul n care unei linii dintr-un tabel i
corespunde o singur linie n tabelul cu care acesta este n legtur. n cazul n
care fiecrei nregistrri dintr-un tabel i corespunde o nregistrare n al doilea
tabel nu este necesar nregistrarea informaiilor n dou tabele separate.
3. Relaii mai muli la mai muli (m la n, many to many)
O relaie de acest tip apare n exemplul dat ntre tabela de autori i cea de
cri. Astfel un scriitor poate fi autor la mai multe cri iar o carte poate avea
mai muli autori (CodA_2 respectiv NrInv_3 de exemplu).
n astfel de situaii se va proceda la crearea unui tabel suplimentar, de
legtur, care va transforma relaia evideniat (many to many) n relaii one to
many. Fiecare articol din tabelul de legtur va conine o pereche de chei
strine, una fiind cheie primar n primul tabel i una n al doilea tabel:

36

Autori

Cri

CodA_1

NrInv_1

CodA_2

NrInv_2

CodA_3

NrInv_3

CodA_4

NrInv_4

CodA_5

NrInv_5

CodA_6

NrInv_6

CodA_7

NrInv_7
NrInv_8
NrInv_9

Autori
CodA_1

Tab. de legtur

Cri

CodA_2

NrInv_1

NrInv _1

CodA_2

CodA_2

NrInv _3

NrInv _2

CodA_3

CodA_3

NrInv _3

NrInv _3

CodA_4

CodA_6

NrInv _3

NrInv _4

CodA_5

CodA_2

NrInv _8

NrInv _5

CodA_6

NrInv _6

CodA_7

NrInv _7
NrInv _8
NrInv _9

37

Capitolul III
Limbajul SQL
n 1992 ANSI (American National Standards Institute) a definitivat
varianta standard a unui limbaj destinat sistemelor de gestiune a bazelor de date
denumit Structured Query Language, prescurtat SQL (pronunai "es-q-el").
Frazele SQL permit crearea, actualizarea, interogarea i distrugerea bazelor de
date relaionale. Dei toate S.G.B.D. folosesc SQL, adesea ele implementeaz i
funcii care nu exist n standard.
Comenzile de baz ale limbajului SQL care sunt Create, Alter, Select,
Insert, Update, Delete i Drop sunt suportate de toate sistemele de gestiune
de baze de date i permit realizarea tuturor activitilor majore legate de crearea
i exploatarea bazelor de date relaionale. Cuvintele cheie ale limbajului SQL pot
fi scrise att cu litere mici ct i cu majuscule.
Odat instalat, serverul Oracle XE ofer dou interfee pentru introducerea
comenzilor SQL:
a. Introducerea comenzilor SQL folosind interpretorul de comenzi
SQL *Plus executabil ntr-o fereastr de tip Command Prompt
Lansarea n execuie a interpretorului se realizeaz accesnd Run SQL
Command Line din grupul de comenzi Oracle Database 10g Express Edition:

Dup lansarea n execuie a interpertorului este necesar conectarea la


serverul Oracle XE printr-o comand connect, ca n exemplul urmtor, dup care
pot fi introduse comenzi. Comenzile SQL pot fi introduse pe mai multe linii,
marcarea sfritului introducerii unei comenzi realizndu-se printr-un caracter '/'.

38

b. Introducerea comenzilor SQL folosind interfaa grafic:

Dup conectare se selecteaz SQL Commands / Enter Command.

39

Comenzile introduse n fereastra SQL Commands pot fi terminate prin ';'


ca n MySQL de exemplu sau se poate chiar omite caracterul terminal. Astfel
pentru suprimarea tabelului cafea se poate scrie:
drop table cafea;
sau pur i simplu
drop table cafea
efectul fiind acelai.
Comenzile SQL pot fi memorate individual apsnd butonul Save:

Comenzile memorate pot fi reexecutate prin selectare cu mouse-ul (dublu


clic):

40

Tipuri de date suportate de Oracle


a. iruri de caractere
Pentru pstrarea irurilor de caractere, Oracle definete patru tipuri de
date:
-

VARCHAR2 - pentru iruri de caractere de lungime variabil,

NVARCHAR2 pentru iruri de caractere de lungime variabil n


format UNICODE (16 bii / caracter),

CHAR - pentru iruri de caractere avnd lungime fix,

NCHAR - pentru iruri de caractere avnd lungime fix, n format


UNICODE.

Indiferent de tip, la declararea unui cmp trebuie precizat lungimea:


nume varchar2(50)
Pentru VARCHAR2 lungimea specificat este cea maxim admis n timp
ce pentru CHAR ea va fi efectiv utilizat, irurile de lungime mai mic fiind
completate la dreapta cu spaii. Rezult c VARCHAR2 este mai eficient, n
exemplele prezentate n continuare acest tip fiind utilizat sistematic.

b. Date numerice
Datele numerice pot fi declarate n Oracle folosind unul dintre tipurile
urmtoare:
-

NUMBER - pentru numere zecimale,

BINARY_FLOAT - pentru numere reale (memorate fr conversie


n baza 10)

BINARY_DOUBLE- pentru numere


(memorate fr conversie).

reale

dubl

precizie

Cel mai frecvent se folosete tipul NUMBER. Pentru declararea unei date
de tip NUMBER se poate scrie:
inaltime number(3)

41
sau,
inaltime number(3,0)
Pentru numere care au o parte ntreag i una zecimal se scrie:
pret NUMBER(7,2)
nsemnnd reprezentarea cmpului pret folosind 7 poziii zecimale, ultimele dou
fiind folosite pentru partea real.
Exemple:

Numr

Declaraie

Valoare memorat

123.89

NUMBER

123.89

NUMBER(3)

123.89

NUMBER(6,2)

123.89

123.89

NUMBER(6,1)

123.9

123.89

NUMBER(3)

eroare (depire)

123.89

NUMBER(4,2)

eroare (depire)

123.89
124

BINARY_FLOAT i BINARY_DOUBLE sunt tipuri recomandate n cazul n


care datele astfel reprezentate sunt folosite la calcule mai complicate.

c. Tipuri pentru timp i dat calendaristic


Pentru declararea cmpurilor care vor pstra data calendaristic sau
timpul, Oracle folosete tipurile DATE i TIMESTAMP.
Formatele implicite de introducere a datei i a timpului rezult din tabelul
urmtor.

Valoare

Tip dat

12-MAR-2007

DATE

Val. memorat

2007-02-01 01:02:04.1234 TIMESTAMP

d. Tipuri pentru memorarea imaginilor


Pentru declararea cmpurilor destinate pstrrii n baza de date a
imaginilor, Oracle folosete tipurile CLOB sau BLOB.

42

Crearea tabelelor n Oracle XE


Comanda CREATE TABLE
Comanda CREATE TABLE servete la crearea unui nou tabel i la
descrierea cmpurilor acestuia. Ea are formatul general:
CREATE TABLE nume
(nume_cmp tip_cmp [(marime [,precizie])]
[NULL | NOT NULL]
[PRIMARY KEY | UNIQUE]
[,nume_cmp tip_cmp [(marime [,precizie])]
[NULL | NOT NULL]
)
Exemplu:
CREATE TABLE regiune
(ID_regiune CHAR(2) NOT NULL PRIMARY KEY,
nume VARCHAR2(40)
)
Crearea tabelelor va fi realizat mai uor folosind interfaa serverului
Oracle XE, aa cum s-a procedat n primele cursuri. n cazul n care n momentul
crerii unui tabel se impun restricii asupra cmpurilor, se declar chei strine
sau se declar o cheie primar, fraza SQL corespunztoare va conine un numr
de restricii introduse folosind cuvntul rezervat "constraints".
Exemplu:

CREATE TABLE "DEMO_ORDERS"


(
"ORDER_ID" NUMBER NOT NULL ENABLE,
"CUSTOMER_ID" NUMBER NOT NULL ENABLE,

43
"ORDER_TOTAL" NUMBER(8,2),
"ORDER_TIMESTAMP" DATE,
"USER_ID" NUMBER,
CONSTRAINT "DEMO_ORDER_PK" PRIMARY KEY ("ORDER_ID") ENABLE,
CONSTRAINT "DEMO_ORDER_TOTAL_MIN" CHECK (order_total >= 0) ENABLE,
CONSTRAINT "DEMO_ORDERS_CUSTOMER_ID_FK" FOREIGN KEY ("CUSTOMER_ID")
REFERENCES "DEMO_CUSTOMERS" ("CUSTOMER_ID") ENABLE,
CONSTRAINT "DEMO_ORDERS_USER_ID_FK" FOREIGN KEY ("USER_ID")
REFERENCES "DEMO_USERS" ("USER_ID") ENABLE
)
/

Obs. n fraza SQL afiat denumirile cmpurilor, constrngerilor sau


denumirea tabelului apar ntre ghilimele. Aceast scriere permite folosirea de
denumiri coninnd spaii (de evitat!). Dac denumirile nu pot da natere la
confuzii, ghilimelele pot fi omise.
Cele patru constrngeri declarate se refer la cheia primar, limitarea unei
valori i declar dou cmpuri ca fiind chei strine, preciznd i tabelele legate.
n primul exemplu cheia primar a fost declarat adugnd descrierii cmpului
ID_regiune cuvintele PRIMARY KEY.
Din aceste exemple se observ diversitatea modatitilor de scriere a unei
comenzi SQL. Pentru a limita volumul de cunotine legate de sintaxa limbajului,
n cele ce urmeaz comenzile vor fi realizate i testate folosind interfaa
aplicaiei. Aa cum s-a vzut deja, interfaa permite i afiarea comenzilor
create. Deoarece n timpul realizrii unei baze de date se pot produce incidente
mergnd pn la distrugerea serverului Oracle XE, este bine s fie pstrate ntrun fiier avnd extensia .sql un numr ct mai mare de fraze a croir executare
s permit refacerea tabelelor i repopularea lor cu date.

Comanda DROP TABLE


Comanda DROP TABLE permite suprimarea unui tabel.

Sintaxa comenzii

este:
DROP TABLE Nume_tabel
Pentru a da comanda folosind interfaa grafic se selecteaz succesiv
Object Browser / Browse / Tables, se selecteaz apoi tabelul i se apas butonul
Drop:

44

Comanda SELECT
Comanda SELECT creeaz o mulime de selecie. Aceasta poate conine
un articol, mai multe articole sau niciunul. Articolele din mulimea de selecie
conin numai cmpurile indicate de programator. Din acest punct de vedere se
poate considera c SELECT creaz un subtabel coninnd numai informaiile
specificate. Cmpurile nregistrrilor mulimii de selecie pot proveni dintr-un
tabel sau din mai multe tabele legate.
Comanda SELECT are formatul general:
SELECT [DISTINCT] coloana1 [,coloana2]
FROM tabel_1[,tabel_2, ...]
[WHERE condiii]
[GROUP BY list-coloane]
[HAVING conditii]
[ORDER BY list-coloane [ASC | DESC] ]
Dintre cele 5 clauze ale comenzii SELECT numai clauza FROM este
obligatorie. Fiecare dintre clauze are la rndul ei reguli i parametri pentru
construcie, fcnd din SELECT cea mai complex comand a limbajului SQL. n
frazele SELECT irurile de caractere se pun ntre caractere ' (apostrof).
Pentru construirea unei comenzi SELECT se poate folosi asistentul Query
Builder.

45

Aplicaia va afia trei panouri:


-

n stnga un panou coninnd tabelele cuprinse n schema curent :

n centru un panou coninnd tabelele selectate:

clic

clic

Not: JOB_ID din Jobs = JOB_ID din Employees. Pentru impunerea


legturii se va selecta succesiv cu mouse-ul JOB_ID din Employees i din Jobs.
-

n partea de jos un panou cuprinznd cmpurile selectate i alte


specificaii:

46

Selectarea dintr-un singur tabel


Exemple fundamentale:
SELECT Nume, Prenume FROM cititor
SELECT * FROM cititor
SELECT * FROM cititor WHERE nume = 'Popescu'
SELECT nume, prenume, adresa FROM cititor WHERE nume LIKE 'Po%'
SELECT Nume, Prenume FROM cititor ORDER BY Nume
Numele coloanelor scrise dup SELECT precizeaz cmpurile mulimii de
selecie. Dac se dorete ca mulimea de selecie s aib aceeai structur cu
tabelul, n locul listei de coloane se pune *.
Clauza WHERE permite limitarea mulimii de selecie prin introducerea
unei condiii care specific nregistrrile cutate. n cazul selectrii din mai multe
tabele, aceast clauz poate fi folosit i pentru a introduce legturile dintre
tabele. La scrierea condiiei se pot folosi operatorii logici AND, OR sau NOT
precum i operatorii relaionali:
=

Egal

>

Mai mare

<

Mai mic

>=

Mai mare sau egal

<=

Mai mic sau egal

<> sau !=

Diferit de

LIKE

*Vezi nota

Not: Operatorul LIKE permite selectarea liniilor care conin n cmpul


testat iruri de caractere n care se regsete o succesiune de caractere
precizat. Pentru definirea succesiunii de caractere cutat se poate folosi
caracterul generic "%". De exemplu clauza WHERE nume LIKE 'Po%' va permite
selectarea liniilor n care nume = Pop i nume=Popescu.
Clauza WHERE
prenume LIKE '%a' permite selectarea tuturor liniilor n care prenumele se
termin n "a".
Exemple:
SELECT * FROM cititor WHERE nume = 'Popescu' AND
prenume='Mihai'
SELECT * FROM cititor WHERE nume = 'Popescu' OR nume='Mihai'
SELECT * FROM cititor WHERE nume = 'Popescu' AND prenume

47
IN('Ioan','Vasile','Grigore')
IN specific o mulime creia trebuie s-i aparin cmpul specificat
(prenume).
SELECT * FROM cititor WHERE nume = 'Popescu' AND data_nasterii
BETWEEN '12-MAY-1968' AND '29-MAY-1980'
Clauza BETWEEN permite definirea unui interval cruia trebuie s-i
aparin cmpul specificat (data_nasterii).
Clauza ORDER BY servete la impunerea ordinii de afiare a nregistrrilor mulimii de
selecie. Ordonarea poate fi realizat dup valorile unuia sau a mai multor cmpuri, cresctor (ASC)
sau descresctor (DESC). n cazul n care se folosesc mai multe cmpuri, acestea sunt separate prin
virgul.
SELECT * FROM Cititor ORDER BY Nume,Prenume,ID_cititor
SELECT * FROM Angajati ORDER BY salar DESC, Nume ASC, Prenume
ASC
Clauza DISTINCT permite realizarea unei mulimi de selecie care
conine nregistrri distincte, care difer prin cel puin o valoare a unui cmp. De
exemplu :
SELECT DISTINCT Localitate FROM cititor

Ultima fraz va provoca afiarea numelor localitilor n care domiciliaz


cititorii. Fr clauza DISTINCT, numele oraului Cluj-Napoca ar fi fost repetat de
mai multe ori.
Clauza GROUP BY permite gruparea nregistrrilor dup valoarea unui
cmp.
Exemplul 1:
SELECT Localitate, COUNT(*) as Nr_Cititori FROM Cititor GROUP BY
Localitate
n cazul n care se realizeaz o grupare, fiecare dintre liniile mulimii de
selecie se refer la un grup de nregistrri i nu la nregistrri simple. n
exemplul precedent, GROUP BY Localitate precizeaz cmpul dup care se
realizeaz gruparea. nafara valorii cmpului dup care se face gruparea, n
astfel de situaii liniile mulimii de selecie pot conine rezultatul aplicrii unor
funcii matematice asupra articolelor care formeaz grupul (suma valorilor dintrun cmp, media valorilor, valoarea maxim sau minim, numrul de articole care
formeaz grupul etc). Pentru cmpurile care vor conine rezultatul aplicrii unor

48
funcii se recomand folosirea clausei AS nume pentru atribuirea unui nume
relevant coloanei respective. n exemplul dat s-a afiat rezultatul funciei
COUNT(*), care numr nregistrrile din grup. Funciile care pot fi apelate
pentru cmpuri numerice sunt prezentate n tabelul de mai jos.

MIN
MAX
SUM
AVG
COUNT
COUNT DISTINCT

returneaz cea mai mic valoare dintr-o


coloan (cmp numeric)
returneaz cea mai mare valoare dintr-o
coloan (cmp numeric)
returneaz suma valorilor numerice
dintr-o coloan (cmp numeric)
returneaz media valorilor dintr-o coloan
(cmp numeric)
returneaz numrul de valori dintr-o
coloan
returneaz numrul de valori distincte
dintr-o coloan

Exemplul 2:
SELECT Sectie, MAX(salar) as Sal_Max FROM Angajati
GROUP BY Sectie
Se pot ns aplica aceleai funcii i ntregului fiier, fr gruparea
articolelor, caz n care mulimea de selecie va conine o singur nregistrare:
SELECT AVG(salar) FROM Angajati
SELECT AVG(salar) FROM Angajati WHERE functie='Zidar'
SELECT COUNT(*) FROM Cititor
Clauza HAVING servete la precizarea unui filtru care se aplic grupurilor de articole,
dac este prezent clauza GROUP BY.
Exemplu:
SELECT Sectie, AVG(Salar) FROM Angajati GROUP BY Sectie HAVING AVG(Salar) >
500
Dac n fraza SELECT lipsete clauza GROUP BY, folosirea clauzei HAVING nu se
justific, ea avnd acelai efect ca i clauza WHERE.
O situaie aparte prezint comenzile SELECT care nu realizeaz o mulime
de selecie ci un calcul matematic. n acest caz from nume_tabel va fi nlocuit
prin from dual, ca n exemplul urmtor:

49

Cuvntul rezervat dual astfel folosit permite respectarea sintaxei comenzii


SELECT.

Selectarea din mai multe tabele


Principial o baz de date relaional presupune repartizarea datelor n mai
multe tabele. Aa cum s-a vzut deja, acest mod de stocare permite eliminarea
informaiilor redondante. Pentru a gsi articolele dintr-un tabel legate de o
nregistrare din alt tabel trebuie ns indicat n frazele SELECT condiia de
legtur dintre cele dou tabele.
Exemple:
SELECT Edituri.Nume, Carti.Titlu, Carti.Anul FROM Edituri, Carti WHERE
Nume='Minerva' AND Edituri.CodE=Carti.CodE
A doua condiie coninut n clauza WHERE este cea care leag tabelele
Edituri i Carti.
Limbajul SQL permite nlocuirea unei mulimi care contribuie la selecie
printr-o alt fraz SELECT, ca n exemplul urmtor.
SELECT Edituri.Nume, Carti.Titlu, Carti.Anul FROM Edituri, Carti WHERE
Nume='Minerva' AND Edituri.CodE=Carti.CodE AND Titlu.Data IN (SELECT
Data FROM Carti WHERE Data BETWEEN '12-MAY-1975' AND '29-MAY-1980')
Odat cu standardizarea limbajului SQL, pentru introducerea legturilor
stabilite ntre tabele prin definirea de chei primare i strine s-a definit i o alt
modalitate, respectiv clauza JOIN. Folosind JOIN, exemplul anterior poate fi scris
astfel:
SELECT Edituri.Nume, Carti.Titlu, Carti.Anul
FROM Edituri INNER JOIN Carti ON Edituri.CodE=Carti.CodE
WHERE Nume='Minerva'

50

Clauza JOIN este ns i soluie ntr-o alt situaie, respectiv cnd ntr-un
tabel se accept pentru o cheie strin valori nule. Un exemplu simplu este cel
al tabelelor Angajati i Soi prezentate n continuare.

Dintre angajaii din primul tabel doi sunt cstorii, n cazul lor ID_SOT
are valori nenule.
Dac se dorete realizarea unei mulimi de selecie care s cuprind
angajaii, iar pentru cei cstorii numele i prenumele soului/soiei, fraza
SELECT ar putea fi urmtoarea:
select Angajati.Nume, Angajati.Prenume,Soti.Nume_prenume
from Angajati, Soti where Angajati.ID_SOT=SOTI.ID_SOT
Rezultat:

Rezultatul nu este cel dorit deoarece prin condiia pus sunt exclui din
mulimea de selecie angajaii necstorii.
Soluia este oferit de clauza LEFT OUTER JOIN:
select Angajati.Nume, Angajati.Prenume,Soti.Nume_prenume
from Angajati left outer join Soti on Angajati.ID_SOT=SOTI.ID_SOT

51
Rezultatul va cuprinde toate liniile din primul tabel iar pentru liniile din
primul tabel care au corespondent n al doilea tabel, va include i informaiile
corespunztoare din al doilea tabel.

Similar se poate folosi clauza RIGHT OUTER JOIN pentru includerea


tuturor nregistrrilor din al doilea tabel i selectarea din primul doar a celor care
satisfac relaia de legtur.

Utilizarea parametrilor
SQL permite ca la scrierea comenzii SELECT s se foloseasc parametrii.
Valorile acestora sunt cerute ntr-o fereastr separat, n momentul executrii
interogrii.
Exemplu :
sql>select * from edituri where cod_edit > :coded;

52

Comanda INSERT
Comanda INSERT adaug un rnd ntr-un tabel existent.
Exemplu:
INSERT INTO Edituri(CodE,Nume,Adresa,Telefon) VALUES(121,
'Albatros','B-dul Tomis Nr. 32 Constanta','0745654765')
Lista de cmpuri de dup numele tabelei poate fi omis dac toate
cmpurile primesc valori iar acestea sunt scrise n ordinea definit la creare (n
care ele apar n capul de tabel). Dac un cmp nu primete valoare el va primi
implicit valoarea NULL, dac la creare, prin modul de declarare a cmpului,
introducerea unei astfel de valori este autorizat.

Comanda DELETE
Comanda DELETE suprim una sau mai multe nregistrri dintr-un fiier.
Ca i n cazul comenzii SELECT, pentru definirea unui set de nregistrri care vor
fi terse se utilizeaz clauza WHERE.
Exemple:
DELETE FROM Autori WHERE CodAut=7
DELETE FROM Edituri
Ultima comand suprim toate nregistrrile din tabelul Edituri.

Comanda UPDATE
Comanda UPDATE permite modificarea unei nregistrri sau a unui set de
nregistrri. Pentru precizarea setului de nregistrri afectate se folosete clauza
WHERE.
Exemplu:
UPDATE Edituri SET Adresa='str. 1 Mai Nr. 12', Telefon='0745343435'
WHERE Nume='Dacia'
UPDATE Angajati SET Salar=Salar*1.2 WHERE Salar<450

18

Laborator nr. 2
Relaii ntre tabele. Comenzi SQL
1. Pornii aplicaia Start -> Programs -> Oracle Database 10g Express Edition -> Go To
Database
Home Page sau scriei adresa http://127.0.0.1:8080/apex/ n browser-ul dv.
2. Conectai-v la serverul Oracle Database XE , folosind contul creat la laboratorul nr. 1,
respectiv numele de utilizator biblio i parola biblio.
3. Refacerea tabelelor create la laboratorul anterior (dac e cazul) se realizeaz n dou
etape:

se refac tabelele i

se insereaz datele.

Refacerea tabelelor se poate realiza folosind comenzile CREATE salvate anterior ntr-un
fiier .txt. Comenzile pot fi introduse una cte una copiindu-le n fereastra destinat
introducerii comenzilor SQL sau toate odat, folosind posibilitatea aplicaiei de creare i
execuie a scripturilor SQL.
A doua variant fiind mai productiv va fi prezentat n continuare.
Se afieaz fereastra n care pot fi introduse comenzile unui script (Home / SQL / SQL Scripts
/ Upload).

Rezultatul este crearea unui script SQL :

19

n continuare se execut scriptul (Run).

4. Inserarea datelor n tabele


Dup refacerea tabelelor bazei de date se poate trece la refacerea coninutului acestora
folosind fiierele .txt care conin datele. Pentru aceasta se poate proceda astfel:

Se selecteaz n fereastra Home opiunea Utilities / Data Load/Unload / Load:

n fereastra care se afieaz se selecteaz Load Text Data:

20

Se indic faptul c tabelul n care vor fi adugate datele exist (se selecteaz opiunea
Existing table):

Se indic schema (Biblio):

Se selecteaz tabelul care urmeaz s fie repopulat cu date:

Se indic numele fiierului (Browse) i separatorul folosit (tab, \t);

Aplicaia afieaz n continuare informaiile recuperate. Pentru ncrcarea acestora n


tabelul indicat se va apsa butonul Load data.

21

Observaie: La refacerea tabelelor i a coninuturilor acestora folosind metoda expus


anterior, serverul Oracle XE face toate verificrile privind integritatea datelor. Implicaiile
acestui fapt sunt urmtoarele:

Salvarea comenzilor de creare a tabelelor trebuie s urmeze ordinea creerii


iniiale a acestora. Astfel un tabel care conine chei strine va fi creat dup
crearea tabelelor de care acesta depinde.

Restaurarea datelor trebuie s urmeze aceeai logic. Datele dintr-un tabel


care conine o cheie strin vor fi ncrcate dup ncrcarea datelor din tabelul
principal, ale crui nregistrri sunt referite prin valorile cheii strine.

Astfel, de exemplu, tabelul Edituri trebuie creat naintea tabelului Carti.


Datele din tabelul Carti nu pot fi incrcate naintea ncrcrii datelor din
tabelul Edituri.

5. n meniul Object Browser selectai Create / Table, apoi creai urmtoarele tabele:

cititori
cod_cit
number (4, 0)
cnp
number (13, 0)
nume
varchar2 (30)
prenume
varchar2 (20)
localitatea
varchar2 (30)
judetul
varchar2 (20)
adresa
varchar2 (80)
telefon
number (10, 0)
e_mail
varchar2 (50)
cheie primar : cod_cit

cod_carte
cod_autor

autcarti
number (4, 0)
number (4, 0)

chei strine : cod_carte, cod_autor

imprumut
cod_carte
number (4, 0)
cod_cit
number (4, 0)
data_imprumut
date
data_rest
date
chei strine : cod_carte, cod_cit

22
Obs.
 e-mail-ul poate fi null
 data_rest poate fi null
 formatul datei este ZZ-LLL-AA, de ex. 01-OCT-2006
6. Introducei n aceste tabele urmtoarele nregistrri:
- n tabelul cititori:
1 || 1246845691231 || Popescu || Marin || Turda || Cluj || str. Mica, nr. 123 || 0264122112 || popescu@personal.ro
2 || 2342356786431 || Maniu || Laura || Dej || Cluj || str. Zambilelor, nr. 321 || 0744123456 ||
laura_maniu@yahoo.com
3 || 2897654356789 || Rotaru || Clin || Sighisoara || Mure || str. Grii, nr. 43 || 0265012021 ||
calinrotaru@personal.ro

- n tabelul autcarti:
(1; 1), (2; 2), (3; 3), (4; 4)

- n tabelul imprumut:
1; 1; 10 octomrie 2001; 15 octombrie 2001
1; 2; 10 februarie 2007; etc.

23

Comenzi SQL (crearea, editarea, vizualizarea, rularea i tergerea comenzilor SQL).


7. Crearea unei comenzi SQL presupune:

deschiderea paginii SQL-Commands

scrierea comenzii SQL

Obs. Comanda SQL poate s se termine cu ';', '/' sau s nu aib un caracter terminal.
ex. :
SELECT * from autori;
sau

SELECT * from autori


/
sau

SELECT * from autori

rularea (Run sau Ctrl+Enter)

24

salvarea

copierea
 se deschide fereastra care cuprinde comenzile salvate
 se selecteaz comanda care urmeaz a fi copiat
 se apas Save

 se d numele noii comenzi

 se editeaz (dac e cazul) comanda nou

25

 se salveaz din nou


 se ruleaz

8. Introducei cteva comenzi SQL, folosind i opiunea de salvare a acestor comenzi:


 toi autorii n ordine alfabetica, afind toate cmpurile tabelului
select * from autori order by nume asc
 numele i prenumele autorilor n irdine alfabetic
select nume, prenume from autori order by nume asc
 titlurile crilor din bibliotec
select titlu from carti
 titlurile crilor aprute n anul 1991
select titlu from carti where an_apar=1991
 titlurile crilor aprute n anul specificat de utilizator (variabil)
select titlu from carti where an_apar=:an
 titlul crilor i anul de apariie pentru crile care au codul > 2
select titlu, an_apar from carti where cod_carte>2

26
 titlul crii, anul apariiei i codul crii pentru crile aprute nainte de 1991 i
care au codul < 2
select titlu, an_apar, cod_carte from carti where an_apar<=1991 and
cod_carte>2
 numele i prenumele cititorilor care au nume care ncep cu Po
select nume, prenume from cititori where nume like 'Po%'
 afiarea localitilor de unde provin cititorii
select distinct localitatea from cititori
 afiarea numrului de cri din biblitec

select count(*) as nr from carti


9. Introducei i alte comenzi SQL pentru a afla date din celelalte tabele.

27

Laborator nr. 3
Relaii ntre tabele. Comenzi SQL care selecteaz date din mai multe tabele
1. Pornii aplicaia: Start -> Programs -> Oracle Database 10g Express Edition -> Go To
Database Home Page sau scriei adresa http://127.0.0.1:8080/apex/ n browser-ul dv.
2. Conectai-v la serverul Oracle Database XE , folosind contul creat la laboratorul nr. 1,
respectiv numele de utilizator biblio i parola biblio.
3. Introducei cteva comenzi SQL, folosind i opiunea de salvare a acestor comenzi:


selectarea crilor i editurilor corespunztoare


select carti.titlu as titlul_cartii, edituri.nume as editura from carti , edituri where
carti.cod_edit = edituri.cod_edit

 selectarea tuturor crilor i vizualizarea titlurilor i a anilor apariiei acestora


mpreun cu autorii lor:
select carti.titlu as titlul_cartii, carti.an_apar as anul_aparitiei, autori.nume as
autorul, carti.cod_carte, autcarti.cod_carte from autori, carti, autcarti where
autcarti.cod_carte = carti.cod_carte and autcarti.cod_autor = autori.cod_autor

 afiai titlul crii (n ordine alfabetic), numele i prenumele autorului i


editura:
select carti.titlu as titlul_cartii, TRIM(autori.nume) || ' ' || TRIM(autori.prenume)
as Nume_autor, edituri.nume as editura from autori, carti, autcarti, edituri
where autcarti.cod_carte = carti.cod_carte and autcarti.cod_autor =
autori.cod_autor and carti.cod_edit = edituri.cod_edit
Obs. Concatenarea se realizeaz cu ajutorul caracterului ||.

28

 Afiai titlul crii, numele i prenumele autorului, numele i prenumele


cititorului pentru crile mprumutatate inainte de 01 oct 2008:
select carti.titlu as titlul_cartii, TRIM(autori.nume)||' '||TRIM(autori.prenume) as
Nume_autor, TRIM(cititori.nume)||' '||TRIM(cititori.prenume) as Cititorul from
autori, carti, autcarti, cititori, imprumut where autcarti.cod_carte =
carti.cod_carte and autcarti.cod_autor = autori.cod_autor and cititori.cod_cit =
imprumut.cod_cit and imprumut.cod_carte = carti.cod_carte and
data_imprumut < '10-OCT-2008'

4. Introducei i alte comenzi SQL pentru a afla date din celelalte tabele.

O mic pauz

constructiv

innd cont de importana nelegerii modului de structurare a unei baze de date, n


continuare vor fi prezentate cteva studii de caz: evidena notelor elevilor, evidena cinilor de
ras, gestionarea informaiilor legate de o bancsau orice altceva.

1. Creai un utilizator nou, scoala, cu parola scoala


2. Creai o baz de date pentru gestionarea materiilor predate i a notelor obinute de
elevi.
3. Pentru acesta creai urmtoarele tabele:
ELEVI
cod_elev - cheie primar (numr ntreg)
nume - (ir de caractere)
initiala - (caracter)
prenume - (caracter)
data_nasterii - (data)
adresa - (caracter)
telefon - (caracter)

29
MATERII
cod_materie - cheie primar (numr)
nume_materie - (caracter)
NOTE
cod_nota - cheie primar (numr)
cod_elev - cheie strin (numr)
cod_materie - cheie strin (numr)
data - (dat calendaristic)
nota - (numr)
4. Se cere:

S se adauge 4 elevi, 3 materii, i cte 2 note fiecrui elev la fiecare materie;

ELEVI

NOTE

MATERII

30

S se afieze toi elevii n ordine alfabetic sub forma:


nume, initiala, prenume, data_naterii

Vom folosi editorul de interogri (Query Builder)

Fiind o interogare bazat pe un singur tabel, trebuie s parcurgem urmtoarele etape:

Selectm tabelul i alegem cmpurile care sunt parte a interogrii:

Adugm condiiile de ordonare:

Salvm interogarea (Save):

31

Executm interogarea (Run):

Fraza SQL generat poate fi afiat:


select

"ELEVI"."NUME" as "NUME",
"ELEVI"."INITIALA" as "INITIALA",
"ELEVI"."PRENUME" as "PRENUME",
"ELEVI"."DATA_NASTERII" as "DATA_NASTERII"
from "ELEVI" "ELEVI"
order by ELEVI.NUME ASC, ELEVI.INITIALA ASC, ELEVI.PRENUME ASC

5. Alte interogri:

S se afieze toi elevii cu toate notele la toate materiile sub forma:


nume, initiala, prenume, materia, nota

n ordinea descresctoare a notelor , elevii fiind ordonai alfabetic

Fiind o interogare bazat pe mai multe tabele, trebuie s parcurgem urmtoarele


etape:

Alegem tabelele necesare i selectm cmpurile care sunt parte a interogrii:

32

Adugm condiiile de legtur i selectm numai cmpurile care urmeaz s fie


afiate

Adugm criteriile de ordonare:

Salvm interogarea (Save);

33

Executm interogarea (Run)

Fraza SQL generat poate fi afiat:


select

"ELEVI"."NUME" as "NUME",
"ELEVI"."INITIALA" as "INITIALA",
"ELEVI"."PRENUME" as "PRENUME",
"MATERII"."NUME_MATERIE" as "NUME_MATERIE",
"NOTE"."NOTA" as "NOTA"
from "NOTE" "NOTE",
"MATERII" "MATERII",
"ELEVI" "ELEVI"
where "NOTE"."COD_ELEV" =elevi.cod_elev
and "NOTE"."COD_MATERIE" =materii.cod_materie
order by NOTE.NOTA DESC, ELEVI.NUME ASC, ELEVI.INITIALA ASC, ELEVI.PRENUME
ASC

S se afieze toi elevii cu toate notele la o materie (de ex. limba romn) sub
forma:
nume, initiala, prenume, materia, nota

n ordinea descresctoare a notelor , elevii fiind ordonai alfabetic.


select

from

"ELEVI"."NUME" as "NUME",
"ELEVI"."INITIALA" as "INITIALA",
"ELEVI"."PRENUME" as "PRENUME",
"MATERII"."NUME_MATERIE" as "NUME_MATERIE",
"NOTE"."NOTA" as "NOTA"
"NOTE" "NOTE",

34
"MATERII" "MATERII",
"ELEVI" "ELEVI"
where "MATERII"."NUME_MATERIE" ='Limba romana'
and "NOTE"."COD_ELEV" =elevi.cod_elev
and "NOTE"."COD_MATERIE" =materii.cod_materie
order by NOTE.NOTA DESC, ELEVI.NUME ASC, ELEVI.INITIALA ASC, ELEVI.PRENUME
ASC
rezultatul:

S se afieze toi elevii cu note de 10 la o materie (de ex. limba romn) sub
forma:
nume, initiala, prenume, materia, nota

elevii fiind ordonai alfabetic.

select

"ELEVI"."NUME" as "NUME",
"ELEVI"."INITIALA" as "INITIALA",
"ELEVI"."PRENUME" as "PRENUME",
"MATERII"."NUME_MATERIE" as "NUME_MATERIE",
"NOTE"."NOTA" as "NOTA"
from "NOTE" "NOTE",
"MATERII" "MATERII",
"ELEVI" "ELEVI"
where "MATERII"."NUME_MATERIE" ='Limba romana'
and "NOTE"."NOTA" =10
and "NOTE"."COD_ELEV" =elevi.cod_elev
and "NOTE"."COD_MATERIE" =materii.cod_materie
order by ELEVI.NUME ASC, ELEVI.INITIALA ASC, ELEVI.PRENUME ASC
rezultatul:

S se afieze elevii care au nota 10 , indiferent de materie.

select

"ELEVI"."NUME" as "NUME",
"ELEVI"."INITIALA" as "INITIALA",
"ELEVI"."PRENUME" as "PRENUME",

35
"NOTE"."NOTA" as "NOTA",
"MATERII"."NUME_MATERIE" as "NUME_MATERIE"
from "MATERII" "MATERII",
"NOTE" "NOTE",
"ELEVI" "ELEVI"
where "NOTE"."NOTA" =10
and "NOTE"."COD_ELEV" =elevi.cod_elev
and "NOTE"."COD_MATERIE" =materii.cod_materie
order by ELEVI.NUME ASC, ELEVI.INITIALA ASC, ELEVI.PRENUME ASC
rezultat:

S se afieze toate notele mai mari de 7, obinute la matematic dupa 01-JAN2008 .

select

"ELEVI"."NUME" as "NUME",
"ELEVI"."INITIALA" as "INITIALA",
"ELEVI"."PRENUME" as "PRENUME",
"MATERII"."NUME_MATERIE" as "NUME_MATERIE",
"NOTE"."DATA" as "DATA",
"NOTE"."NOTA" as "NOTA"
from "NOTE" "NOTE",
"MATERII" "MATERII",
"ELEVI" "ELEVI"
where "NOTE"."COD_ELEV"="ELEVI"."COD_ELEV"
and
"NOTE"."COD_MATERIE"="MATERII"."COD_MATERIE"
and "MATERII"."NUME_MATERIE" ='Matematica'
and "NOTE"."DATA" >'01-JAN-2008'
and "NOTE"."NOTA" >7
order by ELEVI.NUME ASC, ELEVI.INITIALA ASC, ELEVI.PRENUME ASC
rezultat posibil :

36

Capitolul IV
Limbajul PL/SQL
Generaliti
Limbajul SQL (Structured Query Language) este un limbaj declarativ
orientat pe obinerea de mulimi de selecie ntr-o aplicaie n arhitectur clientserver. Eficiena sa este remarcabil dar n cazul n care elementele unei mulimi
de selecie trebuie accesate pe rnd, nu n grup, utilizarea sa nu mai este
posibil. Pe de alt parte SQL nu ofer nici suportul necesar realizrii interfeei
unei aplicaii. n contrast cu SQL, limbajele procedurale pot manipula linii
individuale dintr-o mulime de selecie. Ele dispun de funcii care permit trecerea
de la o linie la alta i ramificarea codului n funcie de rezultatul testrii valorilor
preluate din tabelele bazei de date.
Limbajul PL/SQL (Procedural Language extensions to SQL) a fost
dezvoltat de compania Oracle ca extensie a limbajului declarativ SQL. PL/SQL
este un limbaj de programare procedural care poate fi folosit pentru descrierea
unor prelucrri complexe sau pentru programarea unor secvene de cod care
trebuie executate automat la apariia unui eveniment (triggere).
O caracteristic remarcabil a limbajului PL/SQL este faptul c
procedurile sau funciile scrise vor fi memorate n baza de date. Aceleai
prelucrri pot fi realizate de regul i n cadrul aplicaiilor client care acceseaz
datele din baz, dar n cazul modificrii unei metode de calcul trebuie refcute
aplicaiile client afectate i suportate toate costurile pe care le implic
redistribuirea unor noi versiuni ale aplicaiilor client.
Avnd n vedere faptul c de multe ori aplicaiile din domeniul bazelor de
date sunt n arhitectur client-server i aplicaia client acceseaz aplicaia server
(Oracle XE) prin intermediul unei reele, utilizarea pe ct posibil a procedurilor
scrise n PL/SQL poate ameliora semnificativ viteza de prelucrare. n cazul unei
proceduri care ar implica transferul spre aplicaia client a unui volum mare de
date (rezultatul unei interogri de exemplu), ntrzierile cauzate de reeaua prin
care se acceseaz serverul de baze de date pot fi mari. Dac prelucrarea datelor
nu presupune afiarea acestora n aplicaia client, mult mai eficient este soluia
prelucrrii datelor pe server, ntr-o procedur scris n PL/SQL.
PL/SQL este bazat pe limbajul ADA, o parte dintre construciile sale
sintactice provenind din Pascal.

Scrierea unui bloc anonim


De regul programarea n PL/SQL nseamn definirea unor proceduri sau
funcii, n sensul pe care acestea le au n oricare dintre limbajele procedurale
cunoscute. O procedur sau o funcie poate fi introdus folosind fereastra SQL
Plus sau folosind interfaa grafic, n SQL Command sau Script Editor.
O succesiune de instruciuni n PL/SQL care nu sunt destinate definirii
unei funcii sau proceduri formeaz un bloc anonim care va fi executat doar o
singur dat.

37
Exemplu:
begin
dbms_output.put_line('Hello World');
end;
/

n fereastra SQL*Plus secvena de cod scris va fi precedat de comanda


set serveroutput on
Aceasta trebuie dat la nceputul sesiunii de lucru i realizeaz activarea
afirii la consol a rezultatului operaiilor de ieire.

Dac se folosete interfaa grafic nu mai este necesar comanda


set serveroutput on.

38
Exemplul urmtor conine declaraia unei variabile, nr. Pentru a afia
valoarea acesteia se realizeaz conversia ei n ir de caractere folosind funcia
to_char():

Elementele limbajului PL/SQL

Codul PL/SQL poate fi coninut n blocuri anonime sau n blocuri care


conin subprograme memorate n baza de date (proceduri sau funcii).
Un bloc anonim se introduce n fereastra n care se introduc comenzi
SQL. El nu este memorat n mod normal n baza de date n vederea reutilizrii
ulterioare. Interfaa serverului Oracle XE permite totui memorarea unui bloc,
ntocmai ca i memorarea unei comenzi SQL orecare. Cele dou exemple
anterioare sunt blocuri anonime.
Un subprogram memorat (denumit uneori stocat) este un subprogram
PL/SQL pe care serverul Oracle l compileaz i l memoreaz n baza de date.
Subprogramul memorat poate fi ulterior apelat dintr-o aplicaie sau dintr-un alt
bloc PL/SQL. Subprogramele pot fi proceduri sau funcii. Diferena dintre cele
dou este faptul c o funcie returneaz o valoare.
Un pachet (engl. package) este format dintr-un un grup de subprograme
i de declaraii de variabile. Serverul Oracle memoreaz elementele coninute
ntr-un pachet, acestea putnd fi apelate din alte pachete sau subprograme.

Sintaxa unui bloc PL/SQL


Un bloc anonim PL/SQL se compune din seciuni i are sintaxa
urmtoare:

39

Bloc anonim
DECLARE
declaratii de variabile
BEGIN
cod program
EXCEPTION
cod tratare exceptii
END;
Dac blocul conine o procedur memorat n baza de date, sintaxa sa
este urmtoarea:

Subprogram memorat de tip procedur


CREATE OR REPLACE PROCEDURE "nume"
(lista_parametri)
IS
declaratii variabile
BEGIN
cod program
EXCEPTION
cod tratare exceptii
END;
Seciunea de declaraii (DECLARE n cazul blocului anonim) cuprinde
declaraii de variabile simple, variabile structurate, variabile tip cursor, funcii
sau proceduri ajuttoare. Zona de declaraii este opional. Pentru funcii,
proceduri i triggere cuvntul DECLARE lipsete, blocul de declaraii fiind implicit
cuprins ntre linia de declarare a funciei sau a procedurii i BEGIN.
Blocul introdus prin EXCEPTION este opional i realizeaz tratarea
erorilor aprute n timpul execuiei codului programului.
Caracterul ';' se folosete pentru a marca sfritul unei instruciuni sau a
unui bloc, dac apare dup END.
Codul poate cuprinde blocuri interioare. Exemplu:

DECLARE
declaraii variable
BEGIN
-- cod program
BEGIN
codul blocului inclus
EXCEPTION
tratare exceptii
END;
-- cod program (continuare)
END;

40

Pentru transformarea exemplelor din urmtoarele subcapitole n exemple


executabile, naintea declaraiilor de variabile va fi introdus fie numele seciunii
de date, DECLARE fie secvena de declarare a unei proceduri stocate (CREATE
OR REPLACE PROCEDURE "nume" IS).

Comentarii
n PL/SQL comentariile n linie se introduc prin dou caractere '-' iar
comentariile pe mai multe linii sunt cuprinse ntre /* respectiv */, ca n limbajul
C.
Exemplu:

Tipuri de date n PL/SQL


Tipurile de date folosite n PL/SQL pot fi:
4. cele folosite n SQL (VARCHAR2, NVARCHAR2, CHAR, NCHAR,
NUMBER, BINARY_FLOAT, BINARY_DOUBLE, DATE, TIMESTAMP,
CLOB i BLOB),
5. tipuri specifice limbajului PL/SQL : BOOLEAN, NUMBER (scris
simplu, fr dimensiune) i PLS_INTEGER (pentru variabile avnd
valori ntregi),

41
6. tipuri specifice structurate: TABLE, VARRAY i RECORD.
Exemplu:
-- Declaratii de variabile
nume VARCHAR2(30);
prenume VARCHAR2(25);
marca NUMBER(6);
activ BOOLEAN;
salar_lunar NUMBER(6);
nb_zile_lucrate NUMBER(2);
salar_zilnic NUMBER(6,2);
medie_zile_lucr CONSTANT NUMBER(2) := 21; -- o constanta
BEGIN
NULL;

-- NULL indica lipsa corpului. Este permisa pt. testare.

END;
/

Obs. Pentru a defini constanta medie_zile_lucr s-a folosit cuvntul


rezervat CONSTANT i imediat s-a atribuit valoarea corespunztoare.
Variabilele declarate servesc de multe ori la memorarea unor valori din
tabelele bazei de date, obinute folosind comenzi SELECT. n astfel de cazuri
este esenial ca tipul declarat pentru o astfel de variabil s coincid cu tipul
coloanei tabelului din care va primi valori. Pentru a evita erorile greu de depistat
cauzate de declararea eronat a acestor variabile, PL/SQL ofer soluia simpl a
prelurii tipului cmpului care va furniza valori folosind %TYPE, astfel:
coded edituri.cod_edit%TYPE;

Variabila coded va fi NUMBER(5), de acelai tip cu cmpul cod_edit din


tabelul edituri.
O situae asemntoare apare n cazul variabilelor structurate (de tipul
RECORD). O astfel de variabil va avea mai multe cmpuri. Dac variabila
trebuie s preia valorile coninute ntr-o linie a unui tabel, la declararea ei se va
folosi %ROWTYPE, astfel:
editura edituri%ROWTYPE;
Variabila editura va fi de tip RECORD i va avea aceleai cmpuri cu
tabelul edituri. Accesul la cmpuri se realizeaz folosind operatorul '.' (punct).
Exemplu: editura.cod_edit, editura.nume etc.

42

Cursoare
Cursoarele permit programatorului s preia date dintr-o mulime de
selecie, linie cu linie, n vederea prelucrrii lor. n PL/SQL un cursor poate fi
implicit sau explicit.
Cursorul implicit presupune utilizarea unei mulimi de selecie avnd o
singur linie i este folosit pentru a atribui valori unui set de variabile.
Exemplu:
SELECT cont, data, valoare into cnt, dt, val from operatii where cod_op = 3;

n vederea selectrii unei singure linii se impune valoarea cheii primare.


Cursorul explicit are nume i este declarat n seciunea de declaraii a
blocului (procedurii, funciei), astfel:
CURSOR c1 IS SELECT ... ;
Exemplu:

CURSOR c1 IS SELECT nume, prenume FROM angajati WHERE functia = 'zidar';


Comanda SQL SELECT va fi executat n momentul deschiderii cursorului
folosind instruciunea OPEN. Liniile mulimii de selecie coninute n cursor vor fi
prelucrate individual, accesul la linia curent realizndu-se folosind instruciunea
FETCH.
Dup terminarea prelucrrii datelor coninute ntr-un cursor, acesta
trebuie nchis folosind instruciunea CLOSE.
Cteva exemple privind folosirea cursoarelor vor fi nserate dup
prezentarea instruciunilor repetitive.

Identificatori
Numele unei variabile const dintr-un ir avnd maximum 30 caractere i
format dintr-o liter urmat opional de alte litere, cifre, $, _. Caracterele '&', '-',
'/' i ' ' (spaiu) nu sunt permise. PL/SQL nu este sensibil la tipul literelor majuscule sau litere mici.
Exemple:
-- Declaratii de variabile
numeprenume VARCHAR2(30); -- identificator acceptat

43
nume_prenume VARCHAR2(30); -- identificator acceptat, _ permis
nume$prenume VARCHAR2(30); -- identificator acceptat, $ permis
nume#prenume VARCHAR2(30); -- identificator acceptat, # permis
-- nume-prenume identificator neacceptat, minus nepermis
-- nume/prenume identificator neacceptat, / nepermis
-- nume prenume identificator neacceptat, spatiu nepermis
-- NUMEPRENUME
NumePrenume
-- NumePrenume
NUMEPRENUME

identif.
identif.

neacceptat,

acelasi

cu

numeprenume

si

neacceptat,

acelasi

cu

numeprenume

si

BEGIN
NULL;
END;
/

Operatori
La scrierea codului n PL/SQL se folosesc urmtoarele tipuri de operatori:
e. aritmetici: + - * /
f. logici : '=' '>' '<' '>=' '<=', '!=' (sau '<>')
g. de concatenare a irurilor '||'
h. de atribuire: ':='
Exemple:
-- Declaratii de variabile
salar NUMBER(6,2);
ore_lucrate NUMBER := 40;
salar_orar NUMBER := 22.50;
bonus NUMBER := 150;
tara VARCHAR2(128);
numarator NUMBER := 0;
gata BOOLEAN := FALSE;
id_valid BOOLEAN;
BEGIN
salar := (ore_lucrate * salar_orar) + bonus; -- calcul salar
tara := 'Suedia'; -- atrib. un literal de tip string
tara := UPPER('Canada'); -- idem, caracterele transf in majuscule
gata := (contor > 100); -- atrib. BOOLEAN, literalul FALSE
id_valid := TRUE; -- atrib. BOOLEAN

44
END;
/

Literali
Exemple:
-- Declaratii de variabile
number1 PLS_INTEGER := 32000; -- literal numeric, val ntreag
number2 NUMBER(8,3);
BEGIN
number2 := 3.125346e3; -- literal numeric
number2 := -8300.00; -- literal numeric
number2 := -14; -- literal numeric
END;

char1 VARCHAR2(1) := 'x'; -- literal caracter


char2 VARCHAR2(1);
BEGIN
char2 := '5'; -- literal caracter
END;
/

-- Declaratii de variabile
string1 VARCHAR2(1000);
string2 VARCHAR2(32767);
BEGIN
string1 := '555-111-2323';
-- daca un sir contine apostrof, acesta se dubleaza
string2 := 'Here''s an example of two single quotation marks.';
END;
/

-- Declaratii de variabile
gata BOOLEAN := TRUE; -- BOOLEAN literal
complet BOOLEAN;
true_or_false BOOLEAN;
BEGIN
gata := FALSE; -- literal BOOLEAN

45
complet := NULL; -- literal BOOLEAN (valoare nedefinita)
true_or_false := (3 = 4);
true_or_false := (3 < 4);
END;
/

-- Declaratii de variabile
date1 DATE := '11-AUG-2005'; -- literal DATE
time1 TIMESTAMP;
BEGIN
time1 := '11-AUG-2005 11:01:01 PM'; -- literal TIMESTAMP
END;
/

Atribuirea folosind SELECT ... INTO


Dac valoarea unei variabile se determin n funcie de valori dintr-o linie
a unui tabel al bazei de date, PL/SQL permite atribuirea valorii acesteia folosind
un cursor implicit, respectiv o construcie
SELECT
expresie
condiie_selectare_linie

INTO

Expresia folosit poate


corespunztoare din tabel.

variabil

folosi variabile,

FROM

tabel

literali i valori

Exemplu:
-- Declaratii de variabile
procent_bonus CONSTANT NUMBER(2,3) := 0.05;
bonus NUMBER(8,2);
ang_id NUMBER(6) := 120; -- atribuie o val. pt testare
BEGIN
-- preia salar din tabelul angajati, calculeaza bonusul i atribuie
--

rezultatul -> variabila bonus


SELECT salar * procent_bonus INTO bonus FROM angajati
WHERE angajat_id = ang_id;

-- listeaza codul angajat_id, bonusul si procent_bonus


DBMS_OUTPUT.PUT_LINE ( 'Angajat: ' || TO_CHAR(ang_id)
|| ' Bonus: ' || TO_CHAR(bonus) || ' Procent bonus: ' ||
TO_CHAR(procent_bonus*100));

WHERE

din

linia

46
END;
/

n aceeai fraz SELECT pot fi atribuite valori mai multor variabile.


Exemplu:
SELECT Nume, Prenume, salar*procent_bonus INTO m_nume, m_prenume,
m_salar
FROM angajati WHERE angajat_id = ang_id;

Funcii uzuale
PL/SQL cuprinde un numr mare de funcii. n tabelul de mai jos sunt
incluse cele mai des folosite.
Funcia

Descriere

Funcii pentru prelucrarea irurilor


upper(s), lower(s)

convertete s n majuscule/minuscule

ltrim(s), rtrim(s)

nltura spaiile de la stnga / dreapta

substr(s, start, lungime)

returneaz un subir definit prin poz. start i lungime

length(s)

returneaz lungimea irului de caractere s

Funcii pentru prelucrarea datei calendaristice


sysdate

data din sistem

to_date(data, format)

returneaza o dat formatat conform formatului


Ex. : to_date('31-12-2007', 'dd-mm-yyyy')

to_char(data, format)

Convertete o dat calendaristic n ir, conform


formatului format. Exemplu:
to_date(d, 'dd-mm-yyyy')

Funcii pentru date numerice


round(x)

rotunjete x

mod(n, p)

returneaz restul mpririi ntregi n/p

abs(x)

returneaz val. absolut

power(x,n)

returneaz xn

dbms_random.random()

genereaz un numr aleator ntreg

Conversii de tip
to_char(n)

convertete n n ir de caractere

to_number(s)

convertete irul s n numr

Alte funcii
user

returneaz numele utilizatorului serverului Oracle

47

Instruciuni
Secvenele de cod scrise n PL/SQL pot conine comenzi SQL (CREATE,
INSERT, DELETE, DROP sau ALTER).
Exemplu:

Insert into deponent values (124, 'Ionescu Valer', 'Str. Crinilor Nr. 7, Craiova',
'0743123989');
Pe lng comenzile SQL sau atribuirile de valori limbajul PL/SQL dispune
de un set complet de instruciuni necesare controlului execuiei programului, ca
oricare limbaj procedural.

Instruciunea de decidere - IF
n limbajul PL/SQL instruciunea IF poate prezenta trei forme.

a. IF-THEN
Exemplu:
-- Declaratii de variabile
vanzari NUMBER(8,2) := 10100;
cota NUMBER(8,2) := 10000;
bonus NUMBER(6,2);
ang_id NUMBER(6) := 120;
BEGIN
IF vanzari > (cota + 200) THEN
bonus := (vanzari - cota)/4;
UPDATE angajati SET salar = salar + bonus WHERE
angajat_id = ang_id;
END IF;
END;
/

Astfel scris IF servete la condiionarea unei aciuni. Aciunea este


declanat dac expresia logic are valoarea adevrat. Secvena de cod care
descrie aciunea este plasat ntre THEN i END IF.

48

b. IF-THEN-ELSE
Exemplu:
-- Declaratii de variabile
vanzari NUMBER(8,2) := 12100;
cota NUMBER(8,2) := 10000;
bonus NUMBER(6,2);
ang_id NUMBER(6) := 120;
BEGIN
IF vanzari > (cota + 200) THEN
bonus := (vanzari - cota)/4;
ELSE
bonus := 50;
END IF;
UPDATE angajati SET salar = salar + bonus WHERE
angajat_id = ang_id;
END;
/

n secvena anterioar prezena clauzei ELSE permite definirea a dou


blocuri de instruciuni, unul cuprins ntre THEN i ELSE i al doilea cuprins ntre
ELSE i END IF. n funcie de valoarea de adevr a expresiei logice va fi executat
primul bloc sau al doilea.

c. IF-THEN-ELSIF
Uneori este necesar alegerea unei secvene de cod din mai multe,
fiecare fiind condiionat de cte o expresie logic. n acest caz se recomand
folosirea structurii IF-THEN-ELSIF.
Exemplu:
-- Declaratii de variabile
vanzari NUMBER(8,2) := 20000;
bonus NUMBER(6,2);
ang_id NUMBER(6) := 120;
BEGIN
IF vanzari > 50000 THEN
bonus := 1500;
ELSIF vanzari > 35000 THEN
bonus := 500;
ELSE

49
bonus := 100;
END IF;
UPDATE angajati SET salar = salar + bonus WHERE
angajat_id = ang_id;
END;
/

Instruciunea CASE
Instruciunea CASE permite impunerea blocului care va fi executat n
funcie de valoarea unei expresii. De cele mai multe ori expresia se reduce la o
variabil.
Exemplu:
-- Declaratii de variabile
grade CHAR(1);
BEGIN
nivel := 'B';
CASE nivel
WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excelent');
WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Foarte bun');
WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Bun');
WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Corect');
WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Slab');
ELSE DBMS_OUTPUT.PUT_LINE('Nu ma pot pronunta');
END CASE;
END;
/

n exemplul prezentat valoarea variabilei nivel condiioneaz blocul care


va fi executat. Valorile posibile sunt introduse prin clauze WHEN iar blocul de
instruciuni care trebuie executat se scrie dup THEN. Dac valoarea variabilei
nivel nu se regsete printre valorile introduse prin WHEN, se va executa blocul
introdus prin clauza ELSE, plasat ultima. Instruciunea se ncheie cu END CASE.

Instruciuni de ciclare
n limbajul PL/SQL exist trei instruciuni de coclare: LOOP, WHILE-LOOP
i FOR-LOOP.

50

a. LOOP
Un bloc LOOP - END LOOP permite definirea unui ciclu din care se iese
prin executarea unei instruciuni EXIT. Instruciunea EXIT este de regul plasat
ntr-un IF a crui condiie trebuie s ajung s fie satisfcut pentru a se evita
rularea blocului LOOP n ciclu infinit.
Exemplu:
credit_rating NUMBER := 0;
BEGIN
LOOP
credit_rating := credit_rating + 1;
IF credit_rating > 3 THEN
EXIT; -- iesire imediata din loop
END IF;
END LOOP;
-- dupa EXIT, executia se continu de aici
DBMS_OUTPUT.PUT_LINE ('Credit rating: ' || TO_CHAR(credit_rating));
IF credit_rating > 3 THEN
RETURN; -- n afara blocului LOOP se folosete RETURN, nu EXIT
END IF;
DBMS_OUTPUT.PUT_LINE ('Credit rating: ' || TO_CHAR(credit_rating));
END;
/

Dac ieirea din ciclu se poate realiza printr-un simplu IF, se poate nlocui
IF prin instruciunea EXIT WHEN conditie_iesire.
Exemplu:
IF count > 100 THEN EXIT; ENDIF;
EXIT WHEN count > 100;
Exemplu:
LOOP
credit_rating := credit_rating + 1;
EXIT WHEN credit_rating > 3
END LOOP;

51

b. WHILE - LOOP
n PL/SQL pentru realizarea unei structuri repetitive condiionate anterior
se utilizeaz instruciunea WHILE - LOOP. Sintaxa unei astfel de structuri
repetitive este urmtoarea:
WHILE condiie LOOP
bloc de instruciuni
END LOOP

c. FOR - LOOP
Ca i n alte limbaje, parcurgerea unui ir de valori se realizeaz folosind
o instruciune FOR - LOOP. Exemplu de utilizare:
-- Declaratii de variabile
p NUMBER := 0;
BEGIN
FOR k IN 1..500 LOOP -- calcul pi ca suma a 500 termeni
p := p + ( ( (-1) ** (k + 1) ) / ((2 * k) - 1) );
END LOOP;
p := 4 * p;
DBMS_OUTPUT.PUT_LINE( 'pi este aproximativ : ' || p );
END;
/

n exemplul dat variabila i va lua valori n intervalul de valori ntregi


introdus prin IN. Valorile sunt de regul consecutive i cresctoare. Dac irul
valorilor introduse prin IN trebuie parcurs n ordine invers se va folosi clauza
REVERSE, ca n exemplul urmtor:
BEGIN
FOR i IN REVERSE 1..5 LOOP
DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
END LOOP;
END;

/
Se interzice modificarea variabilei folosite la controlul ciclului n interiorul
acestuia.
Un exemplu tipic de utilizare a ciclului FOR n domeniul bazelor de date
este cel n care se actualizeaz ntr-un ciclu nregistrrile dintr-un tabel.
Exemple:

52
-- Declaratii de variabile
CURSOR ang_cursor IS SELECT * FROM angajati;
REC angajati%ROWTYPE; -- var. structurata de tip record
BEGIN
FOR REC IN ang_cursor LOOP
UPDATE angajati
SET salar = ...
WHERE ang_id = REC.ang_id;
END LOOP;
END;

/
CREATE OR REPLACE PROCEDURE Afisez
AS
CURSOR c1 IS SELECT * FROM edituri order by nume;
REC edituri%ROWTYPE; -- var. structurata de tip record
BEGIN
FOR REC IN c1 LOOP
DBMS_OUTPUT.PUT_LINE (rec.nume);
END LOOP;
END;
/

BEGIN
OPEN c2;
LOOP
FETCH c2 INTO REC;

-- preia linia curenta in REC

EXIT WHEN c2%NOTFOUND;


DBMS_OUTPUT.PUT_LINE( RPAD(REC.prenume, 25, ' ') ||
REC.id_meserie );
END LOOP;
CLOSE c2;

Not Funcia RPAD() construiete un ir de caractere avnd lungimea


dat de al doilea argument. irul se obine prin completarea la dreapta a irului
dat ca prim argument cu irul dat ca al treilea argument.
n exemplul urmtor cursorul c1 conine doar dou valori din tabelul
angajai. Instruciunea FETCH va prelua cele dou valori n dou variabile locale.

53
jobid angajati.job_id%TYPE; -- variabila pentru id_functie
pren angajati.prenume%TYPE; -- variabila pentru prenume
CURSOR c1 IS SELECT prenume, id_functie FROM angajati
WHERE id_functie LIKE '%ZIDAR';
BEGIN
OPEN c1; -- deschid cursorul - execut select
LOOP
FETCH c1 INTO pren, jobid; -- preiau 2 coloane in variabile
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( RPAD(pren, 25, ' ') || jobid );
END LOOP;
CLOSE c1;

Definirea unei proceduri


De regul secvenele de cod PL/SQL sunt coninute n proceduri sau
funcii. Blocurile anonime pot fi folosite eventual pentru testarea corectitudinii
unei secvene de cod, dar dup ncheierea testrii ele vor fi transformate n
proceduri sau funcii memorate n baza de date.
Codul poate fi scris n fereastra destinat scrierii comenzilor SQL (SQL
Command), n Script Editor sau folosind Object Browser / Create / Procedure.
Indiferent de soluia adoptat, rezultatul va fi o procedur stocat n Oracle XE i
accesibil folosind meniul Object Browser.
Exemplul 1. Crearea unei proceduri folosind SQL Command:

54
Declararea unei proceduri folosind fereastra SQL Command sau SQL*Plus
ncepe cu secvena :
CREATE OR REPLACE PROCEDURE nume ...
Pentru verificarea crerii procedurii se selecteaz Object Browser /
Browse / Procedures i n fereastra care se afieaz se selecteaz procedura
(SALUT).

Exemplul 2. Crearea unei proceduri folosind Object Browser / Create /


Procedure:

Exemplu:

55

n pasul urmtor se definesc parametrii de intrare i de ieire ai


procedurii, dac este cazul.

n continuare se introduce corpul procedurii:

Rezultat:

56

Astfel generat, procedurii i lipsete seciunea destinat declarrii


variabilelor locale. Pentru adugarea acestora se selecteaz Edit i se insereaz
declaraiile necesare.
Apelul procedurii se poate realiza din fereastra destinat introducerii de
comenzi SQL (SQL / SQL Commands) :

Din SQL*Plus apelul se poate face i folosind comanda SQL CALL :

Parametrii procedurilor PL/SQL


Procedurile pot avea un numr de parametri de intrare (IN), parametri de
ieire (OUT) sau de intrare / ieire (IN OUT).
Exemple:
PROCEDURE maj

( v1 IN VARCHAR2, v2 IN VARCHAR2) IS ...

PROCEDURE majusc

( v1 IN VARCHAR2, v2 OUT VARCHAR2) IS ...

PROCEDURE majuscule ( v1 IN VARCHAR2, v2 IN OUT VARCHAR2) AS ...

Dac un parametru este declarat de intrare (IN) modificarea sa n


subprogram nu afecteaz valoarea eventualei variabile folosite ca parametru
efectiv la apelarea funciei.

57
La apelul unei proceduri avnd parametri de tip OUT sau IN OUT, pe
poziiile corespunztoare acestora din lista de parametri efectivi trebuie utilizate
variabile de acelai tip cu cel al parametrilor procedurii.
Un bloc anonim sau o procedur poate avea n zona de declaraii o
declaraie de procedur. Exemplu :
DECLARE -- declaratii de variabile si subprograme
nume VARCHAR2(20) := 'ionescu';
prenume VARCHAR2(25) := 'marin';
PROCEDURE nume_maj ( v1 IN OUT VARCHAR2, v2 IN OUT VARCHAR2) AS
BEGIN
v1 := UPPER(v1); -- trec sirurile in majuscule
v2 := UPPER(v2);
END;
BEGIN
DBMS_OUTPUT.PUT_LINE(nume || ' ' || prenume ); -- afisez val. initiale
nume_maj (nume, prenume); -- apelez procedura cu parameteri
DBMS_OUTPUT.PUT_LINE(nume || ' ' || prenume ); -- afisez noile valori
END;
/

Deoarece procedura nume_maj este cuprins ntr-un bloc anonim,


executarea blocului nu va determina memorarea acesteia n baza de date.

Definirea unei funcii


Funciile sunt subprograme care returneaz o valoare. Ca i n cazul
procedurilor, o funcie poate fi scris n fereastra destinat scrierii comenzilor
SQL (SQL Command), n Script Editor sau folosind interfaa afiat prin
selectarea opiunii Object Browser / Create / Function. Exemplu:

58
Funcia salar poate fi apelat n mai multe moduri, cel mai simplu fiind n
fraze select:

a.

b.
Ca i procedura, o funcie poate avea parametri de intrare.
acestora este

Lista

CREATE OR REPLACE FUNCTION nume_prenume ( nume IN VARCHAR2,


prenume IN VARCHAR2, casatorit IN VARCHAR2)
RETURN VARCHAR2 AS
nup VARCHAR2(45); -- variabila locala
BEGIN
-- Se construieste un sir cuprinzand numele si prenumele
nup := upper(nume) || '

' || prenume;

if length(casatorit) > 0 THEN

--

daca e casatorit, adaug casatorit

nup := nup || ' ' || casatorit;


END IF;
RETURN nup; -- returneaza valoarea lui nup
END;
/

Laborator nr. 5

59

Laborator nr. 4
Relaii ntre tabele. Comenzi SQL care selecteaz date din mai multe tabele
1. Pornii aplicaia Start -> Programs -> Oracle Database 10g Express Edition -> Go To
Database
Home Page sau scriei adresa http://127.0.0.1:8080/apex/ n browser-ul dv.
2. Creai un utilizator nou, caine, cu parola caine
3. Creai o baz de date pentru evidena cinilor de ras din diferite ri.
Pentru aceasta creai urmtoarele tabele
TARI
cod_tara - cheie primar (numr)
tara tara de origine (caracter)
TALIE
cod_talie - cheie primar (numr)
talie marimea cainelui (caracter)
SCOP
cods - cheie primar (numr)
scop - caracter
CAINE
cod_caine - cheie primar (numr)
cod_tara tara de origine (numar)
cod_talie talia cainelui (numr)
rasa rasa cainelui (caracter)
cods scopul folosirii cainelui (numr)
4. Se cere:

S se adauge 10 ri, 5 talii, 6 scopuri i 14 cini

de diferite talii;

TARI

60

TALIE

SCOP

CAINE
Folosind editorul de interogri (Query Builder) i salvnd interogrile sub forma
lab04_interogare1:

S se afieze toi cinii din toate rile:


Fraza SQL corespunztoare:
select

"CAINE"."RASA" as "RASA",
"TARI"."TARA" as "TARA"
from "TARI" "TARI",
"CAINE" "CAINE"
where "CAINE"."COD_TARA" =tari.cod_tara
order by CAINE.RASA ASC

61

S se afieze toi cinii dintr-o ar (de ex. Germania), indiferent de ras.


select

"CAINE"."RASA" as "RASA",
"TARI"."TARA" as "TARA"
from "TARI" "TARI",
"CAINE" "CAINE"
where "TARI"."TARA" ='Germania'
and "CAINE"."COD_TARA" =tari.cod_tara

rezultatul:

S se afieze toi cinii de talie medie dintr-o ar.


select

"CAINE"."RASA" as "RASA",
"TARI"."TARA" as "TARA",
"TALIE"."TALIE" as "TALIE"
from "CAINE" "CAINE",
"TALIE" "TALIE",
"TARI" "TARI"
where "TARI"."TARA" ='Germania'
and "TALIE"."TALIE" ='medie'
and "CAINE"."COD_TALIE" =talie.cod_talie
and "CAINE"."COD_TARA" =TARI.COD_TARA
order by CAINE.RASA ASC
rezultatul:

S se afieze toi cinii utilitari, indiferent de ar sau talie.


select

from

"CAINE"."RASA" as "RASA",
"SCOP"."SCOP" as "SCOP",
"TALIE"."TALIE" as "TALIE",
"TARI"."TARA" as "TARA"
"TARI" "TARI",
"TALIE" "TALIE",

62
"SCOP" "SCOP",
"CAINE" "CAINE"
where "CAINE"."CODS" =scop.cods
and "SCOP"."CODS" =1
and
and

"CAINE"."COD_TALIE" =talie.cod_talie
"CAINE"."COD_TARA" =tari.cod_tara

rezultat:

S se afieze cinii de companie de talie mic din Frana


select

"CAINE"."RASA" as "RASA",
"TARI"."TARA" as "TARA",
"TALIE"."TALIE" as "TALIE",
"SCOP"."SCOP" as "SCOP"
from "SCOP" "SCOP",
"TALIE" "TALIE",
"TARI" "TARI",
"CAINE" "CAINE"
where "TARI"."TARA" ='Franta'
and "CAINE"."COD_TARA" =tari.cod_tara
and "CAINE"."COD_TALIE" =1
and "TALIE"."COD_TALIE" =caine.cod_talie
and "SCOP"."SCOP" ='de companie'
and "CAINE"."CODS" =scop.cods

rezultat :

5. Creai cteva vederi (View):

afiai cinii de talie mic, indiferent de scop i ar

Pentru asta alegei succesiv Object Browser, Create, View

63

?!?!?!?!
fraza SQL

select

"CAINE"."RASA" as "RASA",
"TALIE"."TALIE" as "TALIE"
from "TALIE" "TALIE",
"CAINE" "CAINE"
where "CAINE"."COD_TALIE" =1
and "TALIE"."COD_TALIE" =caine.cod_talie

rezultat :

64

6. Scriei o comand SQL care s selecteze toi cnii dintr-o ar, indiferent de talie
(numerotarea nregistrrilor se poate face apelnd funcia rownum:
select rownum, rasa, tara, talie from CAINe, tari, talie where caine.cod_tara = tari.cod_tara
and caine.cod_talie = talie.cod_talie and tari.tara='Germania'
rezultat :

65

Laborator nr. 5
Relaii ntre tabele. Comenzi SQL.
1. Pornii aplicaia Start -> Programs -> Oracle Database 10g Express Edition -> Go To
Database
Home Page sau scriei adresa http://127.0.0.1:8080/apex/ n browser-ul dv.
2. Creai un utilizator nou, banca, cu parola banca
3. Creai o baz de date pentru gestionarea unor informaii dintr-o banc.
Pentru asta creai urmtoarele tabele
DEPONENT
cod_dep - cheie primar (number - 6,0)
nume numele i prenumele deponentului (varchar2 - 60)
adresa adresa deponentului (varchar2 - 100)
telefon numrul de telefon al deponentului (number - 10)
CONTURI
cont numrul contului (number - 6,0 cheie primar)
cod_dep codul deponentului (number - 6,0 cheie strin)
OPERATII
cod_op codul operaiunii (cheie primar number - 4)
cont numrul contului (number - 6,0, cheie strin )
data data n care se efectueaz operaiunea (dat)
valoare valoarea operaiunii, valoare pozitiv pentru depunere i valoare negativ
pentru
retragere (numr)
Obs.
 Un deponent poate avea mai multe conturi;
 Pentru un cont pot exista mai multe operaii n tabelul de operaii
 Depunerile vor fi pozitive (operatii.valoare >0) iar retragerile negative
(operatii.valoare < 0)
4. Se cere:

S se adauge 5 clieni (deponeni), 7 conturi i 11 operaii pentru diferite conturi;

66

DEPONENT

CONTURI

OPERATII

5. Creai cteva vederi (View) folosind Query Builder:

67

S se afieze , n ordine alfabetic, toi clienii bncii

Dup alegerea opiunii

rezultatul este

Dac dup compilare rspunsul este No Error, rezultatul va fi

S se afieze toate operaiunile bancare n

ordine cresctoare a datei

68

S se afieze toate operaiunile bancare efectuate ntr-o zi

S se afieze conturile unui deponent:

Obs. Adugai legturile persistente n fereastrta Query builder-ului

S se afieze toate operaiunile efectuate de un deponent ntr-un cont;

69

S se afieze toate conturile unui deponent precum i suma total pe care acesta o
are n fiecare dintre conturi;

70

S se afieze toate retragerile efectuate n perioada 01-02-2007 31-03-2007;