Documente Academic
Documente Profesional
Documente Cultură
Restriciile
o coloan dintr-oimplementate
tabel relaional prin clauzele
care conine comenzii SQL CREATE
mai multe valori
pentru o singur linie. Un tablou variabil este asemntor c
TABLE mai sunt numite i r e s t r i c i i n e p r o c e d u r a l e , pentru cu se
o
refer la restricii formalizate prin expresii
tabel ncapsulat, ns este limitat sub aspectul numrului de linii foarte exacte (vezi
capitolul
pe care le4).poate
Implementarea
conine (pentru restriciilor de vezi
detalii, integritate
capitolul se poate face
8). Aceste
tipuri de structuri reprezint de fapt c o n s t r u c t o r i c o l e c t ode
i sub form de reguli active cunoscute de obicei sub numele ri
declanatoare (t r i g g e r e - vezi capitolul 10).
putnd implementa entiti aflate n relaie una-la-mai-multe ce se Aceste restricii sunt
considerate
regsesc, dep robicei,
o c e d u rprin
a l e . normalizare, n dou tabele relaionale
distincte.
Declanatoarele sunt proceduri ce se execut atunci cnd are loc
n ce privete implementarea schemei logice a bazei de date n
un eveniment specific bazei de date ce afecteaz nregistrrile unei
locaii distribuite, soluia n sistemele Oracle se bazeaz pe
anumite tabele. Ele pot fi folosite pentru a implementa reguli sau
p a r t i i i . Astfel, schema de fragmentare a unei baze de date
restricii refereniale mai complexe care nu pot fi formalizate prin
distribuite poate fi implementat n Oracle folosind partiiile.
clauzele comenzii CREATE TABLE. De asemenea, mai pot fi folosite i
Acestea porioneaz tabelele de date dup anumite criterii precizate
pentru a aplica anumite caracteristici de securitate sau anumite
i le poziioneaz n locaXiile stabilite prin schema de alocare.
opiuni de a u d i t a r e . In versiunile Oracle exist, de regul, dou
categorii
Clustere principale de declanatoare la nivel de tabel:
la nivel
Tabelele de fraz
care SQL - se declaneaz
sunt accesate frecvent mpreun, o singur n dat la nivel
general cele
de fraz
aflate SQL;relaie una-la-mai-multe, pot fi stocate fizic mpreun.
ntr-o
la a
Pentru nivel de linie
le stoca n- se declaneaz
acest mod estepentru creat fiecare linie dinspecial
o structur tabel
afectat de fraza SQL executat.
numit c l u s t e r (sau dac vrei ciorchine"), care va pstra n
aceleai locaii liniile legate ntre ele ale ambelor tabele. Scopul
Pentru
const implementarea
n minimizarea logiciide
fluxului aplicaiei,
I/E generat ntr-un sistem Oracle
de interogrile i
sunt disponibile
actualizrile datelor. urmtoarele
Coloanele prin structuri
care esteprocedurale: proce
fcut legtura duri
dintre
stoca
cele t e , ftabele
dou u n c i i formeaz
i p a c h e cheia
t e ( p acluster-ului.
c k a g e - u r i ) .Aceast cheie este
folosit la generarea index-ului clusterului, valorile acesteia fiind
Pr o c e d u r i l e s t o c a t e reprezint blocuri ce cuprind cod surs
stocate o singur dat pentru multiplele tabele ale cror linii sunt
(PL/SQL n cazul Oracle) pstrate n dicionarul bazei de date,
stocate mpreun n cluster.
apelabile din declanatoare sau de ctre eventualele aplicaii
implementate.
Tabele virtuale - view-uri
Ca structur o tabel virtual este n mare parte similar cu o
Fu n c i i l e se aseamn cu procedurile, ns, spre deosebire de
tabel obinuit: este format din linii i coloane. n schimb, dei se
acestea din urm, sunt obligate s returneze anumite valori
pot interoga sau actualiza date, un view nu stocheaz fizic date.
programelor care le apeleaz.
Acestea se gsesc n tabelele pe baza crora s-a creat respectivul
view.Pa c Conceptual,
h e t e l e suntun structuri
view poate maifi neles
complexe ca ofiindc
masc" suprapus
sunt folosite
peste tabelele de baz prin mecanismul unei fraze
pentru a organiza sau reuni procedurile i funciile n grupuri logice. SELECT. Ceea ce
se se stocheaz
Anumite elemente n baz estepachet
dintr-un definiia view-ului,
(variabile, adic interogarea
proceduri, pe
funcii) pot
care se bazeaz, formatul coloanelor, privilegiile
fi declarate publice sau private. Elementele publice sunt accesibile acordate. Spre
deosebire de tabele, view-urile
din afara package-ului, n timp nu pot fiprivate
ce cele indexate.sunt accesibile numai
procedurilor sau funciilor din interiorul package-ului.virtuale pot fi
Din punctul de vedere al proiectrii, tabelele
invocate ca mecanisme pentru maparea schemei externe pe schema
conceptual
Tipuri abstracte implementat
de date prin structura intern a bazei de date. n
acest context,
Tipurile view-urile
abstracte de pot
datefi sunt
folosite
tipu ir pentru
i d e daplicarea
a t e d e fi anumitor
nite de
politici de securitate la nivelul liniilor sau coloanelor din
u t i l i z a t o r i . Ele se bazeaz pe tipurile scalare definite mai sus i tabele.
pot fi folosite Ia definirea coloanelor din tabelele de date relaionale
sauIndecila definirea atributelor obiectelor stocate n t a b e l e l e d e
Un index reprezint o structur utilizat de server-ul bazei de
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 27
1. Log secjuence number - numrul alocat de ervetul Oracle la fiecare nou scriere n grupul redo log.
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 31
Fiiere de date
1 . Procese utilizator
2, 3 - Procese Oracle
ARCH 3 2 - Procese Server
3 - Procese Background
PMON - Process monitor
SMON - System monitor
RECO - Recovery BBWR -
Database writer LGWR -
Log writer LCKn - Parallel
server lock CKPT -
Checkpoint ARCH - Archiver
File Locations
Source...
Enterthe full path of the tile representing the product(s) you want to install:
Pa
tti: F:\stage\products.jar
Browse.
Destination
Available Products
r
Oracle9l Management and Integration 9.2.0.1.0
Installs the management server, management tools, Oracle Her net Directory, Oracle Integration S
services, USities and basic client software. .. J"
Product Languages.
:-
Available Products . - --
' r'i
Select a product to
install. j services, utilities and
Product Languages.
Database Configuration
Instaiiaton Types
0racle9i Database 9.2.0.1.0
Select a database suited to your needs.
*What
General Purpose
type of installation do you want?
r Installs a pre-configured database optimized (or genera! purpose usage
Enterprise Edition (2.86GB)
Provides data management
Transaction Processingfor high-end applications such as high volume on-line tre
environments, query-intensive data warehouse and demancing Internet applications meet
Installs a pre-configured database optimized (or transaction procssin9
r
V '
the avaSabilty and scalability requirements of mission-critical applications.
Data Warehouse
* Standard Edition (2.80GB) -
installs a pre-configured database'optimized for data warehousing
Targeted for workgroup or d(
n inter
r
Customized
s option take
with Orac
tailed Produc:
Installed Products. Previous
Database Identification
An 0racle9i database is uniquely identified by a Global Database Name, typically of the fornl Enter
the Global Database Name for this database.
A database is referenced by at least one Oracle9i instance which is uniquely Identified from ai
Instance on this computer by an Oracle System Identifier (SID). A suggested SID has beet
::
can accept or change to a valueyou prefer. - '
Oracle
L ?OracleOraHome92TN5Listener Started . *
OradeSer viceOR ACLE i Started
<!
Figura 2.12. n final, configurarea ultimelor instrumente printre care i
acelea
p ' " ~ ............................................................................... "legate
' "1 de gestionarea conectrii clienilor din reea la
serverul bazei de date
Dac ntreaga
Figura procedur
2.11. Trebuie s-a ncheiat
specificate cu succes,
parolele pentru atunci putem
conturile
de administrare S Y S i
verifica mai nti din C o n t r o l Pa n e l Ad m i n i s t r a t i v e To o l s
S Y S T E M create implicit
S e r v i c e s (pentru MS Windows 2000) serviciile create pentru baza
10. Ultimul pas presupune iniializarea i configurarea ctorva
de date i mediul aferent ei pe server.
instrumente necesare pentru bunul mers i buna gospodrire
a bazei de date nou- -nscute". Cele mai importante se
refer la O r a c l e N e t C o n fi g u r a t i o n pentru c au n vedere
gestionarea cererilor eventualilor clieni (de pe alte
calculatoare din reea) ai serverului BD (sarcin delegat
serviciului L i s t e n e r ) i configurarea clientului local pentru a
ne putea conecta la baza de date direct de pe maina-server.
De regul, stratul care asigur conectarea i comunicarea cu
serverul BD se bazeaz pe aa-numite adaptoare" pentru
protocoalele de reea cele mai rspndite (TCP/IP, SPX/IPX
etc.), ns clientul local se bazeaz pe un protocol de inter-
comunicare ntre procese, aa nct nu vor fi solicitate
' I Manual al
' Co p yrig ht ( c) 1 98 2, Or acle Co rp o rat io n. All rig ht s
2 08 2 , Configurarea
re s e rve
Figura 2.14. d modului de pornire
Co nne ct e d t o :serviciilor Windows 2000 m
Acestea fiind spuse, putem ncerca o conectare la baza de date
0 rac le 9 i Re le as e 8 - Pro d uct io n
9 .2 .0
jJSe folosind
.1 .r Re le as e
r ve instrumentul
- Pro d uct io n cel mai cunoscut (i, probabil, cel mai
9 .2 .0 .1 .0nepopular), vechiul S Q L P l u s din S t a r t Pr o g r a m s O r a c l e -
SQL > se le ct t ab le _name f ro n us e r_t ab le s ;
Home Application D e v e l o p m e n t . Ecranul de conectare
TABL E_N AM E
cuprinde trei rubrici: n u m e u t i l i z a t o r - u s e m a m e , p a r o l -
BON US p a s s w o r d i n u m e ( s e r v i c i u ) b a z d e d a t e - h o s t s t r i n g .
DEP T
EM P Vom specifica S C O T T pentru utilizator, t i g e rA pentru parol i vom
SAL GRADlsa E necompletat ultima rubric, ceea ce nseamn ** c dorim s ne
SQL > se le ct * f ro m .
d ep t ; V
DEP TN O D Nil H E L 0 C
10
A CCOUN TIN G N EW YORK fu
2 0 RESE ARCH DAL L AS
3 0 SAL ES CH IC AGO ,'f:
i> 0 BOSTON
OPER ATION S
rj
Figura 2.13. Serviciile Oracle
SQL > | <1 1
U
Figura 2.16. Utilitarul SQL Pas
Next
a template
Select Specify thefrom the following
following databaselist to create a database:
Information.
Select Template
An 0racle9l Name_______
database Is uniquely Identified by a Global Database Name, typically of the form "name.domaln*.
Data Warehouse
Global Database Name: JoracTej
Q j General Purpose
A database is referenced
C Transaction Processing by at least one Oracle9i instance which is uniquely Identified from any other instance
on this computer by an Oracle System identifier (SID).
------------------------------------------------
------------------------------------------------
New Database
Show Details... \
Cancel
Figura
Figura 2.20.
2.19. Pasul necesar
Modelele pentru specificarea
de configurare identitii bazei de date
predefinite
Alegem G e n e r a l Pu r p o s e i mergem mai departe (N e x t ). La
fel ca i n cazul instalrii implicite, n pasul urmtor - D a t a b a s e
Select the mode in which you rant your database;to operate by default
I d e n t i fi c a t i o n - se vor solicita numele global al bazei de date i
* Dedicated Server Mode
numele instanei care o client
For each vaconnection
deservi. Numele
the database implicit
will allocate a resource dedicated al acestei
to serving only that ,
instane va fi sugerat pornind de la numele bazei de date.
client. Use.this mode when the number oftotal client connections Is expected to be small or
when Clients will be making persistent, long-running requests to the database.
n pasul urmtor ni se i solicit . imperativ
. ..v ~ modul n care dorii s
c Shared Server Mode
opereze implicit baza deconnections
; Severaiclient date" share a - D a t a bpool
database-allocated a soferesources.
C oUsenn thisemode
c t iwhen
on
more than a small number of users need toconnectto the database simultaneously while
O p i o n s . Dei formularea este destul de neclar, totui, pentru
efficiently utilizing system resources. The Oracle shared server feature will be enabled.
fiecare opiune exist o scurt descriere. Pe scurt, principiul
di She red Con ne stidn s pe ramefers.
colaborrii ntre clieni i serverul Oracle se bazeaz la nivelul
acestuia din urm pe un proces separat ce comunic direct cu
procesul client i intermediaz cererile acestuia asupra bazei de
date. Aceste procese intermediare pot fi alocate separat, cte unul
pentru fiecare conexiune a fiecrui client (modul de dedicat), caz n
care comunicarea se face direct, fr cozi de ateptri i fr riscul
unor timpi mori" la nivelul proceselor client, sau, pentru a
drmui" mai bine resursele serverului (n ceea ce privete RAM-ul
necesar), un singur proces server poate deservi simultan mai muli
clieni, caz n care, atunci cnd apar mai multe cereri simultan,
Elnish
Buffer Cache 63 M Bytes. Buffer Cai on: : 48 MBytes Buffer Cache; . . 32 M Bytes .
-, j-.T
Java Pool M Bytes Java Pool; 20 MBytes Java Pool; . MBytes
20 ~n 20
Oracle Process Size: 40 MBytes Oracle Process Size: 40 M Bytes Oracle Process Size: 40 MBytes
:
Total Memoryfbr Oracle: 177 M Bytes - Total Memory for Oracle; 177 MBytes Total Memory for Oracle: 177 MBytes
- :
-T ^ - yv -yy yy- >\ ''sy.-'* ^ pvip
4
*( ' .. ;' ,4. fgi,
i Close | Close i-v -f . : Close j
{32 *3
.gj
J3 2 UH
|20
m
F l3
jjav
P'"--
1
,t..
aiM
Memory
S&8BS
Typical
Custom Shared
Pool
Buffer Cache:
DBJNAME -7
L?:Zr.
wm Oracle .. v - : ,. x-
r-;~r? jc
-
... ' '-S'vii
r
'i:* - .
legtur
Groups
cu finalizarea acestui proces: File Directory
crearea (fizic) a bazei de
Redo Log
date i/sau salvarea acestei configuraii sub forma unui model
Members: File
(template) care ar putea REDO01.LOG
Name
fi refolosit ulterior pentru specificarea
{0 RAC LE_0AS E }to ra d aiat( D B_N AM E {t
parametrilor unei alte baze de date.
a Database Template
Name:
Description:
Structura de directoare
Dup cum se poate concluziona de altfel i din figura care
prezint variabilele O R AC L E _ B A S E , O R AC L E _ H O M E , D B _ N A M E
i S I D , structura de directoare implicat se prezint astfel (pentru
MS Windows 2000):
rdcina o reprezint directorul O r a c l e , printe pentru toate
fiierele suport sau ale bazelor de date stocate pe server.
Acest director prezint trei subramuri (subdirectoare):
- directorul O r a 9 2 (pentru Oracle9i2) destinat fiierelor
suport ale software-ului Oracle (serverul BD i utilitare)
plus fiierele de configurare ale clientului local etc.;
- directorul a d m i n n care va fi creat cte un subdirector
specific pentru fiecare baz de date local. Un astfel de
subdirector destinat unei BD locale prezint, la rndul lui,
alte cinci subdirectoare b d u m p , c d u m p , c r e a t e , p fi l e ,
u d u m p . Dintre acestea, fiierul de parametri I n i t . o r a ,
spre exemplu, este plasat n p fi l e - ,
- directorul o r a d a t a care va conine Ia rndul su cte un
director dedicat fiecrei BD locale. ntr-un astfel de
FoU*rs ' 't
i -Q ele
54
, i i -Cj admm
Serverul de baze de date
iii; S -D Orede #I
!
1 1 ! j ; ~D bdump fI
* * 1 j-Qedump * vj
! 11
! Cl create
j Ajjdre |D D:\orade\oradata\Orade
! l i D data <1
DEEE3 _jd
{.22CB !gMyConw*w
: 4.22 GB)
r
PrimaOracle
opiune din
enterprise Manager fereastra
Console, Standalone de mai sus ne permite introducerea
parametrilor de configurare
pie Ma^igatoi Obistl.'Tools' ConfigurationaHelpunui nou descriptor de serviciu, dac
acesta nu exist INeKo'i. deja. Dac acesta este CONTROLO deja definit (de exemplu,
I lji| REDO03.LOG
- .CTL
Oracle %
Enterprise ISYSTEM01 DBF
Manager
prin rularea anterioar
Databas
a utilitarului Net Configuration
CONTR0t02.CTl TEMPO 1. DBF
______
Assistant -
vezi paragraful Oracle
2.5), poate fi selectat dinCONTROl03.Cn
es -S
% lista din partea inferioar
kajTOOtSOl.DBF I
Oracle Enterprise Manager is a managementUNDOTBSOl .DBF
care devine disponibil prin view Its
selectarea
description.
Administer
use celei
an Item to which you canCWMLITE01.0eF
Selectfrgm.gBfl.rk to:
the completeDRSYS01.0=
Oracle environment,
de-a doua opiuni
SuSERSOt.DBF on* M*,,
MXDB01.D6F
Add...from your local tnsnames.ora See also: file...
including databases, IASWservers, applications,
.
EXAMPIEOI DBF
!)INDX01.0BF
and services
Mv Documents Hv
Dup aducerea n OEM a Diagnose,
Network bazelor de
Placesmodify, and tune date
H multiple
dorite, ncercarea de
. databases.
OOMOI OBF
RED001.LOG S
tfrOywiy
deschidere a unui nod automat Schedule vatasksduce lasystems
on multiple deschiderea
at varying dialogului de
Monitor database conditions throughout the
Hostname: .. jOra
V k V. "s'" y. .. .
Port Number. 'jl521
r' !'. ' A l L l b :
SID: Oracle
lame: {oracle_Oraj
ghtj Network
general. ferr
^CJDatabases
^ORACLE - sys AS SYSDBA Instance Stale
^instance -r Shutdown
MD Sessions
Locks tfj/t < Open Snow
GResource Consumer d Ail States
yp-C3Resource Plans | '-
Database and Instance Information........................................... . . ................. - -
iQResource Plan Schee]
Host Name: ORA
-^Schema DB Name: ORACLE
Security f >111 Storage DB Version: Orade9i Enterprise Edition Release 9.2.0.1.0 - Production
Distributed t/3 Warehouse ig With the Spatial, OLAP, .
Workspace ^XML Database Q and Oracle Data Mining options
Instance Name: oracle
ORACLE_ORA
Instance Start Time: 11-Feb-2003 11:29:13 AM
Restricted Mode: (no :
Archive Log Mode: NOARCHIVELOG
Conceptele
Din nodul de baz S t o rpentru a g e avem a stabili autentificarea
posibilitatea s unui utilizator
administrm
spre astructurile
avea acces fizice la de o baz
stocare, de date
adic i sspre crem a noi
stabili relaiile de
tablespace-uri,
apartenen
s crem ntre noiobiectele fiiere nstocate n baza de date
noi tablespace-uri sau i n creatorul
tablespace-lor
sunt curile
o n t uexistente,
l i s c h e ms a .redimensionm sau chiar s ndeprtm din
Astfel,
baza pentru
de dateaccesarea aceste fiiere datelor
(ceea dintr-oce nu baz implic,de dedate Oracle
regul, i
trebuie utilizat un cont
tergerea fizic la nivelul sistemului de operare); utilizator care are asociate anumite drepturi
(privilegii) cu privire Ia aciunile sale fa de serverul Oracle sau fa
de obiecteleNetwork stocate
4-0 n baza de date. n mod implicit, printr-un cont
Databases
utilizator devin &4UORACLE - accesibile
sys AS SYSDai Instance toate obiectele din schema asociat.
^Schem
O schem a Securityreprezint
Storage o colecie de obiecte format din tabelele,
Datafiles
{default pi . .
5
,G G'vJ.y ;V:r.v> V.S: v.
_______ ........: ______
o V .- - ... .... ,
Name: MASTER
W Profile: {DEFAULT
Authentication {password
\ _______________:
__________________;
Enter Password:
-----________
Con,m password: |==j
I------ _
ird Now
Figura
: - Tablespaces 2.36. Conectai-v ca SYSTEM
Default:
n urma unei conectri reuite (sperm), nodul corespunztor
bazei de date se va expanda i vei putea regsi astfel un subnod
Status
intitulat sugestiv S e c u r i t y. Acesta conine Unlocked
trei ramuri U s e r s ,
Ro l e s , Pr o fi l e s . Dup cum v nchipuii, nodul cu care vei avea
de furc n continuare este U s e r s .
Fie prin click pe link-ul create users" din dreapta, fie pe butonul
C r e a t e din stnga, selectnd apoi, din noua fereastr afiat,
rubrica u s e r s , putei obine fereastra C r e a t e U s e r. Aceast
fereastr conine, de fapt, un cadru cu mai Cancel multe Show
pagini:
SQL
, Authenllcalion [pass*
ablespaces-
Temporary P
'.F': -TT
T Locked Unlocked
Figura 2.40. Comenzile SQL (DDC) generate pentru a obine" un nou utilizator
Dac, n final, vei obine urmtorul mesaj
Oracle Enterprise Manager
HS_ADMIN_ROLE
Granted:
CONNECT
GESTFACT
RESOURCE
Cancel J Help
Welcome to the Oracle Net Configuration
Assistant. This tool takes you through the
following common configuration steps:
Figura 2.47. Specificarea numelui bazei de date
Choose
Apoi vom specifica (de fapt, vom alege dintr-o list) numele
0 Listener
TCP.
mm
protocolului de transport al reelei, astzi, n majoritatea cazurilor,
, r
Naming Methods configuration
Cancel
Oracle Net Configuration Assistant: Net Service Name Configuration, TCP/IP Pri
Hostname
Cancel
Choose a name for this net service name. The Oracle Net
Configuration Assistant has defaulted the net service name
to be the same as the service name you entered earlier,
but you can change it to be any name you choose.
Cancel I
SQL*Plus
1. ORACLE I iOME = adresa pe disc a directorului rdcin n care s-a instalat serverul.
VINZARI =
(DESCRIPTION =
(ADDRESSJ-IST =
(ADDRESS = (PROTOCOL = TCP)(HOST = xxx.xxx.xxx.xxx)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orei)
)
)
BDSTUD=
(DESCRIPTION =
(ADDRESSJ-IST =
(ADDRESS = (PROTOCOL = TCP)(HOST = xxx.xxx.xxx.xxx)(PORT = 1521))
)
(CONNECT_DATA =
(SID = Oracle)
))
Dac nu introducem un nume valid de serviciu NET, serverul va
ERROR:
ORA-12154: TNS:could not resolve service name n cazul n care
informaiile de conectare au fost specificate corect, iar SQL*Plus a
reuit s se conecteze la server, vom obine fereastra din figura 3.2.
SQL>
Oracle SQL*Plus
0b E<* Swch Options fcjolp
SQL> Q d:/oradata/script2.txt Enter 1 ro crcatvd 1
ualue for conpart_: Financiar
old 2: {11111 ro crootod 1 ,to_date('01/01/1978','dd/nm/yyyy').15080008.'H')
,Enea Silvestra' ,'fcconpart^
new 2: (11111 ,'Enea Silvestra','Financiar',to_date('01/01/1978','dd/nn/yyyy'),15088800,'M')
1 row created.
ro* crtoted 1
row created
Enter ualue for conpart_: 'Contabilitate'
Enter ualue for salariu_uitalie: |
Commit complete.
SL_______________________________________________________________________
S|L>
Figura 3.6.jJJ.
Execuia scriptului din listing 3.2
Figura 3.5. Execuia unui script SQL
Fane C.
INSERT INTO salariai VALUES ('Atomei Maria', Zile_TY(22.21,20,22,23));
Handache U.
Extragerea datelor
SQL> UPDATE locuitori L SETntr-o form lizibil
L.Adresa.Strada-'G.Enescu* necesit utilizarea
WHERE L.Adresa.Strada-CUC 2 rows updated.
funciei TABLE () ce preia ca argument atributul de tip vector i
SQL> SELECT FROM locuitori;
genereaz, ca rezultat al interogrii, cte o nou linie pentru
CMP HUME
fiecare element cruia i s-a atribuit o valoare (chiar i NULL).
Elementele neiniializate
ADRESA(STRAOA, NUMR, BLOC, OP) sunt ignorate. Figura 4.4 prezint
interogarea
11111 tabelei,
Fane C. mai nti dup formatul standard, apoi
ADRESAJTVCG.
SQL> SELECT Enescu', '22 data_type,
column_nawe, BIS'. 'A5', 13) datalength, dataprecision, datascale
2 FROM user_tab_columns
11112 Handache U.
3 WHERE ADRESA_TV('G.
table_naneEnescu, '22 BIS', 'AS', 13)
= 'PERSONAL'
4 / 11113 Croitoru P.
AORESA_TV('AL. T. Neculai', '112', B1', 13)
4.2.3. Colecii
Coleciile sunt seturi de date ce pot fi tratate ca parte a unei singure
nregistrri dintr-o tabel. Exist dou astfel de tipuri de date:
vectori cu mrime variabil '(varying arrays) i tabele ncapsulate
(nested tables). Un vector cu mrime variabil se declar astfel:
CREATE OR REPLACE TYPE <Tip> AS VARRAY ( 12 ) of <TipElemente>
94 Crearea tabelelor i definirea restriciilor
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 93
UPDATE salariai
Adugarea unor nregistrri
SET zilelucr noi n tabela
= Zile_TY(20,22, Compartiment se realizeaz
18,22,20,22,20,22,20,21,22,22)
folosind notaia:
WHERE nume = ' Atomei Maria' ;
NumeTipTabelalncapsulata (NumeTipElement (valAtribl, ....))
Tablourile (Tabelele) ncapsulate reprezint un alt tip de colecie
Ca urmare,
care, spre adugarea
deosebire compartimentului
de vectori, poate Financiar
stoca uncu doi nelimitat de
numr
salariai se va realiza
elemente i ofer astfel:
posibilitatea actualizrii directe a unui anumit
element. Aa cum sugereaz i numele, un tablou ncapsulat
INSERT INTO compartiment VALUES ( 'Financiar',
presupune existena unei tabele sub forma unui atribut al altei
SALARIATI_NT (
tabele. Colecia se declar
SALARIAT_TY('PredaT. astfel: ,
', 2000000)
SALARIAT_TY('Nistor
CREATE OR REPLACE TYPE A. <tip>
' , 2300000)
AS TABLE OF <T-ipElemente>
)
Exemplificm ) ; utiliznd un tip abstract de date, i anume
Salariat_TY, care pstreaz informaii despre un angajat. De
Extragerea datelor presupune utilizarea funciei THE cu formatul:
asemenea, vom defini n tabela COMPARTIMENT un atribut de tip
tablou ncapsulat care va stoca elemente de tip angajat (Salariat
THETY) pentru
(Select fiecare compartiment
<atributTipTabela> fromn<tabelaParinte>)
parte.
ce are rolul Listing 4.2. Tabelnregistrrile
de a aplatiza" ncapsulat definit din tabela pe ncapsulat
baza unui tip iabstract
Null? Type
de a le prezenta
CREATE TYPE sub form
Salariat_TY ASde linii( ca rezultat al interogrii tabelei
OBJECT
OWNERprinte (vezi Nume VARCHAR2(30),
figura 4.7). NOT NULL UARCHAR2(30)
Salariu NUMBER(16,2)
CONSTRAINT
SQL> dese NAME )userconstraints NOT NULL UARCHAR2(30)
CONSTRAINT TVPE / UARCHAR2(1)
TABLE NAME CREATE TYPE SalariatLNT AS TABLE OF SalariatJTY NOT/ NULL UARCHAR2(30)
SEARCH CONDITION CREATE TABLE compartiment ( LONG
R OWNER DenComp VARCHAR2(30), UARCHAR2(30
R CONSTRAINT Salariai
NAME SALARIATI_NT )
UARCHAR2(30
) NESTED TABLE Salariai STQRE AS salariatLnt_tab;____________________________________________
DELETE RULE )
UARCHAR2(9)
STATUS UARCHAR2(8)
DEFERRABLE n listingul de mai sus, la definirea tabelei COMPARTIMENT vom
UARCHAR2(1*
DEFERRED observa o extensie a instruciunii CREATE TABLE, 0 i anume :
UARCHAR2(9)
UALIDATED UARCHAR2(13
GENERATED NESTED TABLE <NumeAtribut> STORE AS <NumeTabelaDeStocare>
)
UARCHAR2( 1
BAD **)
UARCHAR2(3)
RELV Aceast extensie
Figura 4.4. Utilizarea se TABLE
funciei datoreaz() pentrufaptului
interogarea c elementele atributului
coleciilor
UARCHAR2(4)
LAST CHANGE Salariai sunt stocate sub forma unei tabele DATE clasice (vezi figura
INDEXDei
OWNER un
4.6), piccomplet
mai complicat,
separat, un cu vectornumelepoate fi interogat
UARCHAR2(30
precizat numai
n clauza STORE AS.
dup anumite valori (apelm la o subinterogare
INDEX NAME Aceast tabel nu poate fi accesat direct. UARCHAR2(30 n
) clauza FROM,
dup cum urmeaz - vezi figura 4.5);
INUALID )
UARCHAR2(7)
UIEW RELATED SQL> / UARCHAR2(1U
INSERT
MARCA |NUMEPREN INTO |DATAS___________
CQMPART personal (numepren) SALORAR jSALORARCO )fl2')
UflLUES |(COLABORATOR
, j
101 Al * ' PROD 1/24/2003 12:35:57PM 45000 40000 N
ERROR at line 1:
ORA-01400: cannot insert NULL into
(,,F0TflCHEM . Interogare
,, ,,
Figura 4.5. PERS0NflL dup,Vun
,
l1flRCA ,
) al vectorului
anumit element
O limit a acestuiFigura
tip de colecie ine
4.6. Modul dede imposibilitatea
stocare adugrii
al valorilor unei tabele
1
ncapsulate
sau actualizrii valorilor din vector altfel dect prin nlocuirea
ntregului vector cu altul nou:
1. Preluat din documentaia Oracle.
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 95
INSERT INTO
THE (SELECT salariai
FROM compartiment WHERE dencomp=' Financiar' )
NT VALUES(SALARIAT TY(Amariei V. ,2000000));
NN_PERS0NAL_C0LAB0RAT0R COLABORATOR
NNPERSONALDAT ASU COMPART
NNPERSONALMARCA MARCA
NNPERSONALNUMEPREN NUMEPREN
PK_PERSONAL MARCA 1
UN PERSONAL NUEMPREN NUMEPREN 1
SELECT table_name
FROM user_tables ;
SELECT object_name
FROM user_objects
WHERE object_type = 'TABLE' ;
1 row created.
SQL> INSERT INTO personal (marca, numepren) UALUES (101, *A2') ;
INSERT INTO personal (marca, numepren) UALUES (101, A2a)
*
ERROR at line 1:
ORA-OO0Q1: unique constraint (F0TACHEM.PK_PERS0NAL) violated
i n acest caz datele furnizate sunt cu mult peste ceea ce putem gestiona
n acest moment. Cel mai frecvent ne intereseaz numele, tipul, lungimea,
precizia (pentru atribute numerice) i numrul de poziii fracionare (pentru
atributele numerice) ale cmpurilor, ceea ce, n cazul tabelei PERSONAL,
presupune execuia unei frazei SELECT i afiarea unui rezultat ca n figura
4.11.
CONSTRAINT NAHE TABLE NAHE SEARCH CONDITION
);
" I
4 Executat dup comanda de mai sus, comanda INSERT urmtoare;
CREATE TABLE
personal ( marca
INTEGER
CONSTRAINT pk_personal PRIMARY KEY
CONSTRAINT nn_personal_marca NOT
NULL , numepren VARCHAR2(40)
CONSTRAINT nn_personal_numeoren NOT
NULL CONSTRAINT un_personal_nuempren
UNIQUE . compart VARCHAR2(5) DEFAULT 'PROD'
, dataSV DATE DEFAULT SYSDATE
CONSTRAINT nn_personal_datasv NOT NULL ,
salorar NUMBER(16,2) DEFAULT 45000 ,
salorarco NUMBER(16,2) DEFAULT 40000 ,
colaborator CHAR(1) DEFAULT N'
CONSTRAINT nn_personal_colaborator NOT
NULL );
C re_creare_tabele - Notepad
CONSTRAINT NANE COLUMN NAME POSITION
I Frie dit Format View Help
PK_P0NTAJE MARCA 1
1 PK_P0NTAJE C2DATA 2 a
ci
<
104 Oracle. Ghidul dezvoltrii aplicaiilor Crearea tabelelor i definirea restriciilor
profesionale 105
Spre deosebire
. CONSTRAINTdepk^oontaie
restriciile
PRIMARYlaKEYnivel de cmp, cele la nivel de
(marca,data)
nregistrare privescck_pontaje1
, CONSTRAINT simultan dou
CHECK sau mai
((orelucrate = 0 multe atribute.
AND oreco >=0) OR n plus,
(orelucrate >=0 AND oreco = 0))
momentul verificrii lor succed verificrii regulilor la nivel de
, CONSTRAINT ck_pontaje2 CHECK (orelucrate >= orenoapte)
atribut. Tabela PONTAJE prezint trei
, CONSTRAINT ck_pontaje3 CHECK (orelucrate >= oreabsnem)
asemenea restricii:
);
/
_________________________________________________________________
C K P O N TA J E 1 , potrivit creia un angajat este ori n concediu
Aflarea regulilor de validare la nivel de atribut i nregistrare din
(orelucrate = 0 AND oreco >=0), ori la lucru (orelucrate >=0 AND
tabelele PERSONAL i PONTAJE presupune folosirea consultrii:
oreco = 0 ) ;
CKSELECT
PONTAJE2, dup care untable_name,
constraint_name, angajat nu search_condition
poate avea numrul deuser_constraints
FROM ore de
noapte
WHEREsuperior numrului
table__name IN (orelor totale lucrate
' PERSONAL' n ziua
, ' PONTAJE' ) respectiv
(orelucrate >= orenoapte);
AND constraint_type = 'C'
CK PONTAJE3, prin care se evit eroarea de a avea mai multe ore de absene
Rezultatul n SQL*Plus este cel din figura 4.19.
TABLE_HAME SEARCHC0N0ITI0N
CONSTRAINT
PONTAJE
oreco BETWEEN 0 AND 8
nn_persQnal
(orelucrate numepren
- 0 AND oreco NOT
>-) OR (orelucrate NULL
>=0 AND oreco CONSTRAINT
0)
Figura 4.27. Modificarea valorilor atributelor din cheia primar (tabela printe)
este aparent imposibil
Singura modalitate de a evita mesajul anterior const n
actualizarea prealabil a tabelei copil i apoi a celei printe. S
presupunem ns c avem de-a face cu un administrator
ncpnat, care dorete actualizarea n succesiunea PERSONAL -
PONTAJE. Implicit, la creare, restriciile sunt n e a m n b i l e . Pentru
a declara restricia de integritate referenial a tabelei PONTAJE ca
amnabil, se poate proceda n felul urmtor:
ERROEt at lineDe1: exemplu, conducerea firmei emite o not intern prin care
QRA-82891: transaction rolled back
modul
ORA-02292: integrityde generare
constraint a mrcilor angajailor
(PERSONAL.FK_P0NTRJE_PERS0HRL) nu
uiolated - child record se mai face secvenial,
found
ci dup un alt criteriu. Administratorul bazei de date va ncerca s
Figura 4.28. Vigilena serverului fa de restriciile amnate se face simit n momentul
comiterii
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 117
118 Crearea tabelelor i definirea restriciilor
sql
.COLABORATOR CHAR ( 1)
);
din directorul f:\oracle_car-
PERSONAL
PERSONAL
te\cap04_creare_tabele. {
7
n mod normal,
CREATE TABLE PONTAJE (
SELECT-ul
Listing de tabelelor
PONTAJE
4.7. Re-crearea
--PONTAJE
crearedin
arschema
fi trebuit
curent precedat de unul de
MARCA NUMBER ( 5) 1
.DATA DATE (7) tergere, de genul SELECT ' DROP --PONTAJE TABLE ' | | table_name |2 | ' CASCADE ; '
.ORELUCRATE NUMBER ( 2) PONTAJE 3
.ORECO NUMBER ( 2)
column H-Creare_tabele" FORMAT A60 PONTAJE 4
SELECT
____________________________________________________
>
COMMIT;
spool f:\oracle_carte\cap04_creare_tabele\re_creare_default.sql
spool f:\oracle_carte\cap04_creare_tabele\re_creare_notnull.sql
spool off___________________________________________________________________________________
spool f:\oracle_carte\cap04_creare_tabele\re_creare_chei_primare_si_altemative.sql
SELECT 'ALTER TABLE ' || table_name ||' ADD CONSTRAINT pk ' || table_name ||
' PRIMARY KEY ' ||'( ||atr1 ||
CASE WHEN atr2 IS NOT NULL THEN ', ' || atr2 END ||
CASE WHEN atr3 IS NOT NULL THEN * || atr3 END | | ' ) ; '
AS "-Cheile primare
FROM user_constraints uc
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atr1
FROM user_cons_columns
WHERE position = 1) a1 ON uc.constraint_name = a1 .constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atr2
FROM user_cons_columns
WHERE position = 2) a2 ON uc.constraint_name = a2.constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atr3
FROM user_cons_columns
WHERE position = 3) a3 ON uc.constraint_name = a3.constraint_name
WHERE constraint_type = P;
SELECT 'ALTER TABLE ' || table_name ||1 ADD CONSTRAINT unj || table_name ||
|| atr1 ||
CASE WHEN atr2 IS NOT NULL THEN || atr2 END ||
CASE WHEN atr3 IS NOT NULL THEN '_' || atr3 END ||'
UNIQUE* ||'(' ||atr1 ||
CASE WHEN atr2 IS NOT NULL THEN ',' || atr2 END ||
CASE WHEN atr3 IS NOT NULL THEN ',' || atr3 END [ | ' ) ; '
AS "-Cheile alternative"
FROM user_constraints uc
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atr1
FROM user_cons_columns
WHERE position = 1) a1 ON uc.constraint_name = a1 ,constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atr2 FROM
122 Crearea tabelelor i definirea restriciilor
spool off__________________________________________________________________
Cheile primare
--Cheile alternative
spool f:\oracle_carte\cap04_creare_tabele\re_creare_check.sql
COMMIT;
spool off_______________________________________________________________
SELECT 'ALTER TABLE ' || uc_copil.table_name ||' ADD CONSTRAINT ' || constraint_name || '
FOREIGN K E Y ' ||'( ||atrc1 ||
CASE WHEN atrc2 IS NOT NULL THEN ',' || atrc2 END ||
CASE WHEN atrc3 IS NOT NULL THEN ',' || atrc3 END
II ) ' It
' REFERENCES ' || uc_parinte.table_name |j' (' ||atrp1 ||
CASE WHEN atrp2 IS NOT NULL THEN \ ' || atrp2 END ||
CASE WHEN atrp3 IS NOT NULL THEN ',' |[ atrp3 END ' | | ' ) '
AS "-Restricii refereniale"
FROM user_constraints uc_copil
INNER JOIN user_constraints uc_parinte
ON uc copil.r_constraint_name = uc_parinte.constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atrd
FROM user_cons_columns
WHERE position = 1) c1 ON uc_copil.constraint_name = c1 ,constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atrc2
FROM user_cons_columns
WHERE position = 2) c2 ON uc_copil.constraint_name = c2.constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atrc3
FROM user_cons_columns
WHERE position = 3) c3 ON uc_copil.constraint_name = c3.constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atrpl
FROM user_cons_columns
WHERE position = 1) p1 ON uc_parinte.constraint_name = p1 ,constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atrp2
FROM user_cons_columns
WHERE position = 2) p2 ON uc_parinte.constraint_name = p2.constraint_name
LEFT OUTER JOIN
(SELECT constraint_name, column_name AS atrp3
FROM user_cons_columns
WHERE position = 3) p3 ON uc_parinte.constraint_name = p3.constraint_name WHERE
uc_copil.constraint_type = ' R ' ;
C re_creare_ref * Notepad
p dit Format iew Help
8 rows selected.
--Restricii refereniale
ALTER TABLE PONTAJE ADD CONSTRAINT FOREIGN KEY (MARCA) REFERENCES PERSONAL (MARCA) FOREIGN
ALTER TABLE SPORURI ADD CONSTRAINT KEY (MARCA) REFERENCES PERSONAL (MARCA) FOREIGN KEY
ALTER TABLE RETINERI ADD CONSTRAINT (MARCA) REFERENCES PERSONAL (MARCA) FOREIGN KEY (MARCA)
ALTER TABLE SALARII ADD CONSTRAINT REFERENCES PERSONAL (MARCA)
I I
8 rows selected.
I
Figura 4.32. Fiierul text pentru refacerea
restriciilor refereniale
Capitolul 5
Dac valorile enumerate sunt mai multe sau mai puine dect
atributele tabelei PERSONAL, atunci se declaneaz erorile din
figura 5.1. n primul caz, apare o valoare zero inutil, ce nu poate fi
asociat nici unui atribut, iar n al doilea, lipsete valoarea ultimului
atribut (Colaborator).
De asemenea, ordinea enumerrii valorilor trebuie s coincid cu
ordinea n care au fost declarate atributele la crearea tabelei. Pe
parcursul capitolului precedent a fost folosit i un al doilea format,
cel n care se declar atributele ce urmeaz a primi valori n clauza
VALUES. Astfel, n urma comenzii INSERT urmtoare, n linia nou
introdus, atributele Compart, SalOrar, SalOrarCO i Colaborator vor
128 Actualizarea tabelelor prin comenzi SQL
SQL>
Figura 5.1. Cele dou erori cauzate de neconcordana numerelor de valori i de atribute
NEXTUAL
101
SQL> SELECT seq_marca.NEXTUAL FROM dual ;
NEXTUAL
102
SQL> SELECT seqnarca.CURRUAL FROM dual ;
CURRUAL
102
SQL>
session SQL>
Figura 5.3. Clauza CURRVAL fr iniializarea secvenei
Exist ns o soluie pentru aflarea valorii curente din secven
fr a recurge la texTVAL (ceea ce ar echivala cu pierderea unei
valori). Dicionarul de date pstreaz informaii preioase despre
secvenele create n schema curent n tabela virtual
USER_SEQUENCES. Deoarece am declarat, la creare, c renunm la
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 131
SQL>
SQL>SELECT * FROM user_sequences ;
|_________________________________________________________
SEQUENCE_N MIN_UALUE M A X UA LU E INCREMENT_BY C 0 CACHE_SIZE
Figura
L A 5.5.
S T N UConinutul
t ffi E R tabelei PERSONAL dup primul apel al listingului
SEQMARCA
La drept vorbind,101ideea 5555 generrii mrcilor1NY
att0 prin constante
103
(la primii
SQL doi angajai), ct ________________________________________________
i prin secven nu este prea
inteligent. Astfel,
Figura 5.4.dac
Informaiilansm n extrase
despre secven execuie a doua oar scriptul,
din dicionar
avem toate ansele
Succesiunea ca mrcile
de comenzi INSERTs din
fie cele din figura
listingul 5.1 populeaz tabela
5.6.
PERSONAL, folosind toate variantele discutate n acest paragraf,
inclusiv prin apelul la secven. Pentru a evita duplicarea cheii
primare i producerea erorii cu pricina, scriptul ncepe prin
tergerea eventualelor nregistrri.
Listing 5.1. Script de populare a tabelei PERSONAL
RCA NUMEPREN C0HPADATASU
DELETE FROM personal;
SALORAR SAL0RARC0 C
109 Angajat 3 INTO personal
INSERT IT 02-JUL-76
VALUES (101, 'Angajat 1\ 67500
'IT. 66000 N
TO_DATE('12/10/1980', DD/MM/YYYY'),56000, 55000, * N ' ) ; 75000 N
110 Angajat 4 PROD 05-JAN-82 75000
INSERT INTO personal VALUES (102, Angajat 2', CONTA',
111 Angajat 5 IT 12-N0U-77 62500
TO_DATE('12/11 /1978', 'DD/MM/YYYY'), 57500, 56000, 'N');
62000 N
112 Angajat 6 CONTA11-APR-85 71500
INSERT INTO personal VALUES (seq_marca.NextVal, Angajat 3', 'IT, 70000 N
113 Angajat 7 CONTA21-N0U-91
TO_DATE('02/07/1976', 'DD/MM/YYYY'),67500, 61500
66000, ' N ' ) ; 60000 N
114 Angajat 8 PROD 30-DEC-94 54500 52000 N
101 - se folosesc
Angajat 1 valorile
IT implicite ale atributelor Compart,
12-0CT-80 56000 SalOrar, SalOrarCO
55000 siN Colaborator
INSERT INTO personal (marca, numepren, datasv)
102 Angajat 2 CONTA12-N0U-78 57500 56000 N
VALUES (seqjnarca.NextVal, Angajat 4', DATE'1982-01-05');
COMMIT ;
132 Oracle. Ghidul dezvoltrii aplicaiilor profesionale
Actualizarea tabelelor prin comenzi SQL
133
FROM personal
INSERT INTO WHERE
personal VALUES
marca (seq_marca.NextVal,
NOT IN (102,107) 'Angajat T, IT,
DATE'1980-10-12',56000,
UNION 55000, ' N ' ) ;
INSERT INTO personal VALUES (seq_marca.NextVal, 'Angajat 2\ 'CONTA',
SELECT marca, DATE'2003-07-02', 0, 8
DATE'1978-11-12',57500, 56000, 'N');
INSERT INTO FROM
personalpersonal
VALUES (seqjnarca.NextVal, Angajat 3', IT,
WHERE marca IN (102,107)
DATE'1976-07-02',67500, 66000, N') ; ;
INSERT INTO personal (marca, numepren, datasv) VALUES (seq_marca.NextVal, 'Angajat 4',
DATE'1982-01-05');
INSERT INTO personal VALUES (seqjnarca.NextVal, 'Angajat 5, IT,
SQL> INSERT INTO pontaje
DATE'1977-11-12',62500,
2 SELECT62000,
marca, ' N 'DATE
); 1
2003-07-01 *, 8, fl, 0, 0
INSERT INTO personal
3 VALUES
FROM personal(seqjnarca.NextVal, 'Angajat 6, 'CONTA',
DATE'1985-04-11',71500,
4 / 70000, ' N ' ) ;
INSERT INTO personal VALUES (seq_marca.NextVal, 'Angajat 7', 'CONTA',
8 rows
DATE'1991-11-21', created.
61500, 60000, N ' ) ;
INSERT INTO personal VALUES (seq_marca.NextVal, 'Angajat 8', 'PROD',
SQL>
DATE'1994-12-30', SELECT
54500, 52000,* FROM
N ' ) ; pontaje ;
COMMIT;_____________________________________________________________________________
M AR DATA ORELUC ORECO OREN OA ORE ABS
CA RATE PTE N EM
0 1- JUL - 8 0 0 0
18 1 05.1.3.
3 Inserare prin subconsultare
10 2 0 1- JUL - 8 0 0 0
3 JUL -
10 3 0 1- 8 0 0 0
10 400Am
3
1- JULepuizat
- cam8 fugitiv 0subiectul0 populrii
0 cu nregistrri a tabelei
10 500PERSONAL,
3 JUL -
1- 8 0 0
aa c ne grbim s continum 0 cu cea mai stufoas
10 6 0 3
1 - 8 0 0 0
dintre
JUL
10 7 0 - 03 - tabele -8 PONTAJE.
1- JUL 0 Firete,0 i aici putem
0 apela la unul dintre
10 8 0formatele
3
1- JUL - mai 8mult sau 0mai puin 0 clasice0 de mai sus. Ins mult mai
03
atractiv ar fi s adugm dintr-o singur micare cte o linie pentru
fiecare angajat.
Dei 1 iulie 2003 cade ntr-o mari, i marea nu e prea indicat pentru
nceputuri, comanda INSERT urmtoare va avea efectul scontat:
- 7 iulie
2003 INSERT
INTO pontaje
SELECT marca, DATE'2003-07-07',
CASE WHEN marca IN (102,107) THEN 0 ELSE 8 END AS OreLucru,
CASE WHEN marca IN (102, 107) THEN 8 ELSE 0 END AS OreCO,
CASE marca WHEN 103 THEN 4 ELSE 0 END AS OreNoapte,
CASE marca WHEN 105 THEN 2 ELSE 0 END AS OreAbsente FROM personal;
- 8 iulie
2003 INSERT
INTO pontaje
SELECT marca, DATE'2003-07-08', CASE WHEN marca=103 THEN 0 ELSE 8 END AS OreLucru,
CASE WHEN marca=103 THEN 8 ELSE 0 END AS OreCO,
CASE marca WHEN 104 THEN 2 ELSE 0 END AS OreNoapte,
CASE marca WHEN 105 THEN 1 ELSE 0 END AS OreAbsente FROM personal;
DELETE FROM
(SELECT *
FROM sporuri sp INNER JOIN salarii sa
ON sp.marca=sa.marca AND sp.an=sa.an
AND sp.luna=sa.luna WHERE sp.an=2003 AND
sp.luna=9 ) ;
181 2883 7 48 8
182 2883 7 16 32
Presupunem
), c procentul de cretere este difereniat pe
compartimente:
oreco = ( 10% pentru producie, 8% pentru contabilitate i
12% pentru IT (dac
SELECT autorii acestei cri erau contabili, fii convini
SUM (oreco)
c alteleFROM
ar fi fost procentele
pontaje po !). Cea mai banal soluie este format
WHERE EXTRACT
din trei comenzi UPDATE: (YEAR FROM data)=sa.an AND
r EXTRACT (MONTH FROM data) = sa.luna
AND po.marca=sa.marca )
UPDATE
WHERE anpersonal
= 2003 AND luna = 7 ;
SET salorar = salorar * 1.10 WHERE compart = 'PROD' ; UPDATE
Comanda poate fi simplificat, prin calcularea simultan a celor
personal
SET salorar o
dou atribute folosind = singur
salorar *interogare.
1.08 WHERE compart = 'CONTA' ; UPDATE
personal
SET salorar = salorar * 1.12 WHERE compart = 'IT' ;
UPDATE salarii sa
SET (orelucrate, oreco) = (
Nu putem
SELECT totui lua o min de
SUM (orelucrate), cunosctori SQL cu aa o variant
SUM(oreco)
primitiv. Astfel
FROM stau po
pontaje lucrurile dac folosim o structur de tip CASE:
WHERE EXTRACT (YEAR FROM data)=sa.an AND
UPDATE personal
EXTRACT (MONTH FROM data) - sa.luna AND
SET salorar
po.marca=sa.marca
= salorar *
) CASE compart
WHERE an = 2003
WHEN AND lunaTHEN
'PROD' = 7 ; 1.10
WHEN 'CONTA' THEN 1.08
Oricare ar fi varianta,
WHEN 'IT' rezultatul
THEN 1.12ar trebui s fie cel din figura
5.10. ELSE 1
END
Putem chiar
SQL UPDATE salarii exagera,
sa folosind o interogare corelat:
2 SET (orelucrate, oreco) - (
3 SELECT SUH (orelucrate), SUM(oreco)
UPDATE
4 personal
FROM pontaje po pl
5 SET EXTRACT
WHERE salorar =FROM
(YEAR salorar * AND
data)*sa.aii
6 EXTRACT (MONTH FROM data) - sa.luna AND po.raarca-sa.aiarca
7 ) (SELECT CASE compart
8 WHERE an = 2883 AND luna WHEN
-7; 'PROD' THEN 1.10
8 rows updated. WHEN 'CONTA' THEN 1.08
WHEN 'IT' THEN 1.12 ELSE
SQL> SELECT inarca, an, luna,1
orelucrate,
END oreco FROM salarii WHERE luna7
2l FROM personal p2 WHERE pl.marca=p2.marca) ;
UPDATE salarii sa
SET orelucrate = (
SELECT SUM (orelucrate)
FROM pontaje po
WHERE EXTRACT (YEAR FROM data)=sa.an AND
EXTRACT (MONTH FROM data) = sa.luna
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 141
183 2003 7 40 8
184 2803 7 48 8
1 05 2083 7 48 0
s
2083 7 48 8
186
107 2883
UPDATE 7
(SELECT
16
marca,
32
an, luna, orenoapte FROM sporuri)
108 2083 SET orenoapte
7 48 = 8
Oracl< SQL s
FROM pontaje p
i File dit Search Options Help
MARCA
AH LUNA AND EXTRACT
SPUECH ORENOAPTE (MONTH
SPN0APTE ALTESP FROM data)=s.luna
2003 7 )
101
2003
WHERE
7
an=2003 AND luna=7
102
103 2003 7
104 2003 7
105 2003 Valorile
7 nregistrrilor din tabela SPORURI de dinainte i de dup
2003 7
comanda UPDATE sunt cele din figura 5.11.
106
107 2003 7
2003 7
106
18 rows selected -
8 rows updated.
101 2003 7 0
102 2003 7 0
103 2003 7 4
104 2003 7 2
105 2003 7 0
106 2003 7 0
107 2003 7 0 , , *n . *j i f-.
2003 7
108 0
18 rows selected
SQL>
LI___
>
8 rows selected.
SQL> I_____________________________________________________________________________________
UPDATE
sporuri.an, sporuri.luna,
orenoapte, orelucrate, oreco
FROM sporuri INNER JOIN salarii ON
sporuri.an=salarii.an AND
sporuri.luna=salarii.luna
AND sporuri.marca=salarii.marca) s
SET (orelucrate, oreco, orenoapte) =
{SELECT SUM(orelucrate), SUM (oreco), SUM(orenoapte)
FROM pontaje p WHERE p.marca=s.marca AND EXTRACT
(YEAR FROM data)=s.an
AND EXTRACT (MONTH FROM data)=s.luna
ERROR at line 5:
ORA-01776: cannot nodiFy More than one base table through a join uiew
actualizm
15 orenoapteliniile
- tabelei
(SELECT SPORURIpontajeWHERE
SUH(orenoapte)FROH
16 EXTRACT (VEAR FRON data)-sp.an AND
astfel: narca-sp.narca AND
17 EXTRACT (NONTH FROH data) - sp.luna ),
18 spnoapte -
UPDATE
19 ( sporuri sp
SET
20 SELECT spvech =
ROUtd)(SUH(orenoapte
21 FROH personal pe INNER JOIN
*salorar .15 ),-3)
pontaje po ON pe.narca-po.narca
22 (
GROUP BV pe.narca, EXTRACT (VEAR FROH data), EXTRACT (HONTH FROH data)
23 HAUING pe.narca-sp.narca AND EXTRACT (VEAR FROH data)-sp.an
ANDSELECT ROUND((SUM(orelucrate
20 EXTRACT (MONTH FROM data) - sp.luna * salorar * procent_sv ) +
25 ) SUM(oreco * salorarco * procent_sv )) /100,-3) FROM personal pe
26 /
INNER
8 rows updated.
JOIN pontaje po ON pe.marca=po.marca INNER JOIN
SQL> SELECT * transe_sv
FROH sporuri ON
WHERETRUNC{MONTHS_BETWEEN
an-2883 At luna-7; ( DATE'2003-07-
01' , datasv ) / 1 2 , 0 ) >= ani_limita_inf AND
TRUNC(MONTHS_BETWEEN ( DATE' 2003-07-01', datasv
) / 1 2 , 0 ) < ani_limita_sup
GROUP BY pe.marca, EXTRACT (YEAR FROM data),
EXTRACT (MONTH FROM data)
HAVING pe.marca=sp.marca AND
EXTRACT (YEAR FROM data)=sp.an AND EXTRACT (MONTH
FROM data) = sp.luna ),
orenoapte =
(SELECT SUM (orenoapte) FROM pontaje WHERE
marca=sp.marca AND
EXTRACT (YEAR FROM data)=sp.an AND
EXTRACT (MONTH FROM data) = sp.luna ), spnoapte
=
(
SELECT ROUND(SUM(orenoapte * salorar * .15 ) , - 3 ) FROM
personal pe INNER JOIN pontaje po ON pe.marca=po.marca
GROUP BY pe.marca, EXTRACT (YEAR FROM d a t a ) ,
EXTRACT (MONTH FROM data)
HAVING pe.marca=sp.marca AND
EXTRACT (YEAR FROM data)=sp.an AND
EXTRACT (MONTH FROM data) = sp.luna
)
Execuia i rezultatul SQL*Plus pentru aceast comand simt cele
din figura
5.13.
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 145
- 9 iulie 2003
INSERT INTO pontaje
SELECT marca, DATE'2003-07-09', CASE WHEN marca=103 THEN 0 ELSE 8 END AS OreLucru, CASE
WHEN marca=103 THEN 8 ELSE 0 END AS OreCO,
CASE marca WHEN 104 THEN 3 ELSE 0 END AS OreNoapte,
CASE marca WHEN 105 THEN 1 ELSE 0 END AS OreAbsente
FROM personal;
- 10 iulie 2003
INSERT INTO pontaje
SELECT marca, DATE'2003-07-10, CASE WHEN marca=103 THEN 0 ELSE 8 END AS OreLucru, CASE
WHEN marca=103 THEN 8 ELSE 0 END AS OreCO,
CASE marca WHEN 110 THEN 2 ELSE 0 END AS OreNoapte,
0 ALTESP
FROM personal;
- 11 iulie 2003
INSERT INTO pontaje
SELECT marca, DATE'2003-07-11, CASE WHEN marca=103 THEN 0 ELSE 8 END AS OreLucru, CASE
WHEN marca=103 THEN 8 ELSE 0 END AS OreCO,
CASE marca WHEN 110 THEN 3 ELSE 0 END AS OreNoapte,
8 rows selected.
0
SQL> i <
FROM personal;
COMMIT ;_________________________________________________________________________________
Figura 5.13. Un UPDATE ceva mai pretenios
9 rows
(ca selected.
s par o tranzacie mai lung, am recurs la dou comenzi SQL,
dei operaia anterioar se putea face foarte bine printr-una
SQL> SELECT * FROM sporuri;
singur).
In MARCA
fine, putemAN verificaLUNA
situaia la acest
SPUECH moment
OREHQAPTE (vezi figura
SPHQAPTE 5.16).
ALTESP
Dac starea bazei
2001 2 003
de date 2
se va pstra aa cum este prezentat n
figura 5.16 depinde de modul
in careSELECT
SQL> vom ncheia tranzacia:
* FRON salarii; no rows selected
/
SAVEPOINT act_pontaje;
MA DATA ORELU OREC OREHO QREAB
RCA
28( 87- CRATE
6 O
0 APTE8 SNEM
8
11 18-
208 FEB-83 18 0 2 e
288 11- 4 0 4 0
288 12- 8 0 4 0
288 87- fi 0 0 0
280 18- 10 0 2 6
208 87- fi 0 0 8
288 B7- 6 8 0 8
288 11- 4 8 4
288 87- 6 6 6 0
FROH pontaje i ORDER BV marca;
SQL> SELECT 10 rows selected.
DATASQL>
ORELUCRATE
SELECT * FROM sporuri; 0REC0 ORENOAPTE 0REABSNEH
HARCA
MARCO AN LUMA SPUECH 0REN0APTE SPNOOPTE ALTESP
ORELUCRATE
2001 2003 2 28 0
FROH sporuri;
SQL> SELECT
apoi o vom actualiza:
AN LUNA SPUECH ORENOAPTE SPNOAPTE ALTESP
HflRCA
UPDATE salarii SET orelucrate =
2003 2
2001 (SELECT SUM(orelucrate) FROM pontaje WHERE marca =
2003 2
2002 2001 AND TO_CHAR(data, 'yyyy') = 2003 AND TO_CHAR (data,
SQL> SELECT FROH salarii;
'mm') - 2), oreco = (SELECT SUM(oreco) FROM pontaje
no rows selected WHERE marca - 2001 AND TO_CHAR(data,
yyyy') = 2003 AND TO_CHAR(data, mm) = 2) WHERE
MARCA AN LUNA SPUECH ORENOAPTE SPN0APTE ALTESP
marca = 2002 AND an = 2003 AND luna = 2;
2003 2
2001
2003 2 10 49508
n fine, verificm rezultatul tranzaciei noastre i constatm
2002
2002 2003 2 28 0
TEXT
2003 5 17 19 Sk 53.5H2
atunciSELECT
SQL> ntoarce(VEAR
ROUNDEXTRACT anul FROM
urmtor, n timp
SVSDATE) ce TRUNC tot anul
AS Anul,
2curent.
EXTRACTCnd formatul
(MONTH FROMse SVSDATE)
refer la lun (MONTH, MON sau MM), atunci
AS Luna,
3luna furnizat
EXTRACT (DAVeste luna
FROM curent,
SVSDATE) ASns dac data cade" n a doua
Ziua,
k EXTRACT (HOUR FROM SVSTIMESTAMP)
jumtate (dup 15 ale lunii), ROUND ntoarce AS luna
Ora,urmtoare:
5 EXTRACT (MINUTE FROM SVSTIMESTAMP) AS Minutul,
6 EXTRACT (SECOND
SELECT SYS FROM
DATE AS SVSTIMESTAMP) AS Secunda
"Astzi",
7 FROM ROUND(SYSDATE,'YEAR')
DUAL AS Rot_ AN,
8 / TRUNC(SYSDATE, 'YYYY' } AS Trunc_AN,
ROUND(SYSDATE,'MON') AS Rot_LUNA,
TRUNC(SYSDATE, 'MONTH') AS Trunc LUNA,
ROUND(SYSDATE,'DDD' ) AS Rot_ZI,
TRUNC(SYSDATE, 'DDD') AS Trunc ZI
FROM DUAL
AZI Figura
Peste 2a6.15. Funcia EXTRACT
21 12z IDEM
n privina operaiunilor cu datele calendaristice, se cuvine s
18-
ncepem prin a MAV-03 30-JUL-05 (sau
reaminti c, dac o constant 30-JUL-05
o variabil
ntreag) apare Figura
ntr-o 6.17.
expresie cu unin atribut de tip dat,
Somewhere tme
constanta/variabila se va considera a fi un numr de zile. Curios este
Lucrurilestau identic
c lucrurile pot fi
pentru aplicate
atributele desimilar
tip timp: i pentru
atribute/variabile/constante/ expresii de tip timp. Astfel, pentru a
aflaSELECT SYSDATEde
ora exact AS Azi,
peste 71 minute i 100 de secunde de la
momentul curent (cel al"Peste
SYS DATE + 43 AS 43 deinterogrii),
execuiei zile", se poate folosi fraza
SYSTIMESTAMP AS "Acum",
SELECT urmtoare - vezi figura 6.18.
SYSTIMESTAMP + 34 AS "Peste 34 de. . . "
FROM DUAL
SELECT SYSTIMESTAMP AS Ora_exacta,
SYSTIMESTAMP + INTERVAL ' 7 1 ' MINUTE +
Astfel, ne-am atepta ca SYSTIMESTAMP + 34 s calculeze ora
INTERVAL '100' SECOND AS Peste_71min_100sec FROM
exact
DUALde peste 34 secunde sau minute, ns, dup cum se observ
n figura 6.16, 34 este considerat numrul de zile.
SQL> SELECT SYSTIMESTAMP AS Ora_exacta,
2SQL>
SYSTIMESTAMP IHTERUAL
SELECT SVSDATE AS Azi, *71' MINUTE
SVSDATE AS "Peste 43 de zile",
+ 43
3
2 IHTERUAL '100* SECOND
SYSTIMESTAMP AS SVSTIMESTAMP + 34 AS "Peste 34 de..."
AS "Acum".
3 Peste_71nin_1OOsec
FROM DUAL < FR0N DUAL
5 /
4 /
ORA EXACTA PESTE 71MIN 1OOSEC
AZI Peste
18-MAY-03 43 de zile Acun
11.39.46.125000 PestePH
AH -07:00 18-HAY-03 12.S2.26.125000000 34-07:00
de...
Ce se doreste H0HENTUL
Session altered.
SYSDATE
19- B5-2003 11:20:i9
Figura 6.20. Modificarea formatului de afiare a datei
SELECT SYSDATE +
SYSDATE FROM DUAL
SQL>
SQL> SQL>
SELECT
SELECT SELECT nurcepren,
numepren,
numepren, datasu,
datasu,
22 TO_OATE(
MONTHSBETWEENi
MONTHS_BETWEEN(
2 DATE DATE2003-05-01',
* 81/85/2883*, *8D/NM/YVYY* datasu) AS
1 ) AS **1_Hai_Muncitoresc",
2803-05-01 *, datasu)/12 AS NrLuni,
Ani_Fractionari
33 TO CHAR(datasu, 'DO-HW-YVYY*) AS **Data->Sir, i
TRUNC(MONTHS_BETMEEN(
(DATE'2003-05-01
3 - datasu) VEAR(2) DATETO *
MONTH 2003-05-01
AS *, datasu)/12,)
Ani si Luni, AS
TQ_CHA R(salorar, *999999*) AS "Hunar-iSir",
4 Ani_Intregi
EXTRACT (YEAR FROM
5 TO_NUMBER(TO_CHAR(datasu, ((DATE-2003-05-01
*tw*)) AS
1
"Luna (Data->Sir->Nuar)'* - datasu) YEAR(2) TO MONTH))
6 FROM FROM personal ;
ASpersonal
4 Ani
5
7/ FROM personal
N UM EPREN6 / HUMEPREN
DATASU DATASUAN I AN I SI NRLUN LUNI
I ANI AN NTREGI
I
Primul Angajat Nou FRAC 10-07-2003
ION RI -2.2903226 0 Al Doilea
Pr imul Ang aj at No u
Angajat 1Nou
0- JUL - 03
10-07-2003 -.19-2.2903226
0 86 02 2 - 000 00Angajat
00 00 0 - 1 12-10-1980
0
02
270.645161
Al Do ile a Ang a jat 22- 83
1 0- JUL Angajat -.1920 12-11-1978
86 02 2 - 00 00293.645161
00 00 0 - 24 Angajat
6
N o u a jat 1
Ang 1 2- QCT- 8 0321.967742
3 02-07-1976 2 2.5 53 76 3 4+
26 02
00 00 0 00 22
Angajat 4 - 05-01-1982
22
Ang a jat 2 12 -N 021
255.870968 U- 7 8
Angajat2 4.45 70 43 0 1 +
12-11-1977 07
00305.645161
00 0 00 24 - 25 2Angajat
4
Ang a jat 3 0 2- JUL - 76216.677419
6 11-04-1985 2 6.8 30 64 5 2+
18 06
00 00 0 00 26
Angajat 7 - 21-11-1991
26
Ang a jat 4 137.3548390 5- JAN11- 82
Angajat2 1.3 22 58 0 6 +
8 30-12-1994 10
00100.064516
00 0 00 21 - 8 2 1
Ang a jat 5 12 -N 0 U- 7 ? 2 5.4 70 43 0 1 + 04
00 00 0 00 25 - 25
Ang a jat 6 11 -A PR- 85 1 8.0 56 45 1 6 + 06
00 00 0 00 18 - 18
Ang a jat 7 21 -N 0 U- 9 1 1 1.4 46 23 6 6 + 01
00 00 0 00 11 - 11
Ang a jat 8 30 -DE C - 9 II 8 .3 3 87 09 6 8 0 +5
00 00 0 00 08 - 8
04
Figura 6.23. Funcia MONTHS_BETWEEN
Figura 6.24. Intervale obinute prin scdere i numrul de ani extras dintr-un interval
De la Oracle 9i putem beneficia de una dintre mreele cuceriri
ale nucleului SQL, i anume lucrul cu intervale. Astfel, dac dorim s
vedem ci ani i cte luni s-au scurs ntre dou date calendaristice,
6.2.4. Conversii dintr-un tip n altul
pn n Oracle 8i, am avea nevoie de numr de virtuozitare SQL.
DacAcums-ar fi ns,
fcut pe baza tipului
o statistic privind gradul YEAR
INTERVAL de folosire lucrurile
a funciilor
TO MONTH, devin o
sistem,
istoriabanalitate:
Oracle ar (DATE'
fi cosemnat n unul - dintre
2003-05-01' datasv) primele locuri:
YEAR(2) TO CHAR,
TO MONTH. Iar
TOdac
DATEanterior
i TO NUMBER,am folositadic funcia clasice depentru
funciile EXTRACT determinarea
conversie ntre tipurile unei
majore componente a datei calendaristice (ziua, luna sau anul),
de date, numere, iruri de caractere i date calendaristice. aceeai
Astfel, o
funcie
constant de poate
tip datfi aplicat i intervalelor,
calendaristic poate fi definitaa nct
att n maniera
EXTRACT DATE'FROM
(YEAR
2 0 0 3( -(DATE'2003-05-01'
0 5 - 0 1 ' , ct i TO- DATE
datasv) ( ' YEAR(2)
0 1 / 0 5 / 2 TO
0 0 3MONTH) ) va furniza
' , 'DD/MM/YYYY' numrul
). Prima
de ani
variant e maipe care l conine
scurt, ns a intervalul. Zis i fcut:
doua, mai flexibil. Noi am ales ablonul
z i / l u n / a n , dar cei curioi pot consulta documentaia Oracle pentru a se
minuna SELECT numepren,de
de puzderia datasv,
abloane pus la dispoziie de nucleul SQL al
MONTHS_BETWEEN(DATE'2003-05-01', d a t a s v ) / 1 2
acestui produs.
AS Ani_Fractionari,
Operaiunea invers, de transformare a unei date calendaristice n ir
(DATE'2003-05-01' - datasv) YEAR(2) TO MONTH
de caractere, AS se realizeaz prin funcia TO CHAR. Tot TO CHAR face
Ani_si_Luni,
conversia unui numr
EXTRACT (YEAR ntr-un
FROMir de caractere, dup
((DATE'2003-05-01' un ablon
-datasv) YEAR(2)specificat:
TO MONTH) ) AS
SELECT numepren,
Ani1_Mai_Muncitoresc
FROM personal Data->Sir Nunar->Sir Luna (Data->Sir->Numar)
n comunitatea
SELECT SQL, funcia consacrat n privina conversiilor
marca, numepren,
Pe acelai calapod colaborator,
este construit i logica funciei
este CAST.
DECODE Dintre multiplele
(colaborator , posibiliti, urmtoarea fraz SELECT
NUMTODSINTERVAL, numai c, n aceast situaie, o constant
ilustreaz
' N ' ,urmtoarele conversii:
'Angajat cu norma din , numr n ir de caractere, din
intreaga'
numeric poate fi convertit, dup caz, n zile (DAY), ore (HOUR),
tip dat'D' , 'Colaborator',n tip timp i din dat calendaristic n ir de
calendaristic
minute 'Nu
(MINUTE) sau secunde
este specificat ! ! ! ' (SECOND) - vezi figura 6.27:
) AS Tipul_Angajatului
caractere:
FROM personal
SELECT '3 zile cu 7 minute si 5 secunde' AS Descriere,
NUMTODSINTERVAL
SELECT CAST (marca AS C (3,
H A' D
RA(6Y )' ) ASMarca_Sir,
+
Logica este urmtoarea:
NUMTODSINTERVAL (7,AS
primul
'MINUTE')
argument
+
al funciei, colaborator,
CAST (CURRENT_DATE TIMESTAMP) AS Data_Timp,
este comparat
CAST cu prima
NUMTODSINTERVAL
(datasv valoare
(5,
AS VARCHAR2 ( 4 de
'SECOND') referin,
0 ) )AS
ASInterval
Data_Sir 'N'; dac cele dou
valori sunt
FROM
FROM egale,
dual UNION
personal funcia
SELECTreturneaz
'3 zile fara 7irul 'Angajat
minute' , cu norma intreaga' ;
n caz c nu, datelor
se trecerezultatelor
NUMTODSINTERVAL
Tipologia la (3,
verificarea - egalitii
' D A Y ' ) n dintre colaborator
urma conversiei i a
(figura 6.29)
reiese NUMTODSINTERVAL
doua valoare etalonde
i din modul - 'D',(7, 'MINUTE')
iar atunci
aliniere. Astfel, cnd cele dou
coloana Marca valori coincid,
Sir este se
aliniat
FROM dual
returneaz
la ce indic Dac
'Colaborator'.
stnga, ceea faptulvaloarea
c tipul su atributului nu caractere.
este ir de se potrivete
cu nici una dintre valorile specificate, se returneaz ultimul ir 'Nu
Figura 6.25. Conversii
este specificat ! ! ! '. Iat rezultatul - INTERURL
DESCRIERE
MARCA_SIR DATA_TIMP figura 6.30.
O dat cu versiunea 9i, apar, printreDATA_SIRaltele, dou funcii de conversie cu
un 3
cert grad04.30.47.000000
20-MAV-03
zile decu
utilitate.
7 PrimaPMeste NUMTOYMINTERVAL,
minute 10-JUL-03
si 5 secundecare+000000083
convertete
109
un numr ntr-un interval YEAR TO MONTH. Exemplu:
00:07:05.000000000
110 20-MAV-03 04.30.47.000000 3 PM zile fara 7 minute
10-JUL-03 +000000002
20-MAV-03 23:53:00.000000000
04.30.47.000000
101 SELECT '4 ani' AS Descriere, PM 12-0CT-80
102 20-MAY-03 04.30.47.000000
NUMTOYMINTERVAL
Figura 6.27.(4, PM 12-N0U-78
'YEAR')NUMTODSINTERVAL
Funcia AS "Interval"
103 20-MAY-03
FROM dual 04.30.47.080000 PM 02-JUL-76
104 Interogarea
20-MAY-03
UNION urmtoare
04.30.47.000000
SELECT '7 folosete
PM cele dou funcii pentru a
05-JAN-82
105 calcula
l u n i 'datele
20-MAY-03 i orele exactePMde peste
, 04.30.47.000000 4 a n i J u r 7 l u n i i peste 3
12-N00-77
106 z i l e
20-MAY-03 f r 7 m i n
NUMTOYMINTERVAL u t e
04.30.47.000000, relativ la
(7, PM momentul
'MONTH') execuiei:
11-APR-85
107 FROM dual
20-MAY-03 UNION SELECT
04.30.47.000000 PM 21-N0U-91
SELECT
'4 ani si 'Astzi'
7 luni' ,AS Obiectiv, PM
108 20-MAY-03 04.30.47.000000 30-DEC-94
TO_CHAR( SYS DATE,{4,
NUMTOYMINTERVAL 'DD-MM-YYYY
'YEAR') + HH:MI:SS' ) AS Data_Ora
FROM dual UNION
NUMTOYMINTERVAL
Figura 6.29. Folosirea funciei (7, 'MONTH')
SELECT
FROM 'Peste
dual UNION4 ani fara 7 luni ' ,
CAST
Adevrata
SELECT '4 anifor
fara 7aluni'
TO_CHAR(SYSDATE funciei CAST iese la(4,
+ ,NUMTOYMINTERVAL iveal
'YEAR')atunci
- cnd se
NUMTOYMINTERVAL
doreteNUMTOYMINTERVAL
conversia dintr-un (7, 'MONTH' ) ,
tip utilizator
(4, 'YEAR') - 'DD-MM-YYYY HH :
n altul, cu sauM I : S S ' ) fr
FROM
subconsultri NUMTOYMINTERVAL
care extrag seturi (7, 'MONTH')
de nregistrri. Despre aceste
dual dual
FROM
faciliti vom discuta cu alt ocazie.
UNION
6.2.5.
SELECT
Dup Structuri
'Peste
constanta 3 zile alternative:
fara 7 minute'
numeric , DECODE
apare 'YEAR' i CASE ceea ce indic
sau 'MONTH',
TO_CHAR(SYSDATE+NUMTODSINTERVAL
semnifi caia numrului (este an sau lun). Utilitatea (3, 'DAY') -
acestei funcii este
In Oracle exist dou
NUMTODSINTERVAL opiuni
(7, ' Mpentru
I N U T E ' lucrul cu secvene
) , 'DD-MM-YYYY
dat de operaiunile n care poate fi angajat, dintre care cteva sunt
alternative:
HH: MI: SS' )
FROM dual
funcia DECODE, disponibil nc din Oracle 7, i structura CASE, care
exemplificate n interogarea precedent, al crei rezultat se prezint n
e ceva mai cald" (din Oracle 8i i 9i n PL/SQL). Tabela PERSONAL
figura 6.26.
Ceea atributul
conine ce se obine n urma pentru
Colaborator lansriiantiSQL*Plus seamnrespectiv
dac persoana izbitor cu
este angajat cuDESCRIERE
carte de munc, caz Interval
n care valoarea atributului
este 'N', figura 6.28.colaborator
sau este 0BIECTIU DATA
al fimei ORA n afara celor dou
('D').
MARCANUMEPREN 4 ani +000000004-00
COLABORATO 4 ani fara
TIPUL_ANGAJATULUI
valori, laAstzi
un moment dat, valoarea 20-05-2003
poate s fie11:11:12
NULL, ceea ce
7RD
luni +000000003-05
Colaborator
4 ani si
109 Primul AngajatPeste
nseamn Nou Al
fie c situaia
37zilelunifara angajatului
7 minute este
+000000004-07 7 incert,
23-05-2003
luni fie c, pur i
Doilea Angajat
simplu, esteNouvorba
11:04:12 despre4o ani
Peste Nu este
neglijen specificat
fara 7 aluni ?!?
operatorilor. Ne propunem
20-10-2006
110 +000000000-07
s afim,
101 Angajat 1 n dreptul
11:11:12 N fiecrei linii din tabel,
Angajat cu normaunintreaga
mesaj care s indice
102 Angajat 2 persoanei respective.
tipul N Figura 6.26. Angajat
Folosind
Funcia cu norma
funcia
NUMTOYMINTERVAL intreaga
DECODE, se poate scrie:
103AngajatFigura
3 6.28. Expresii
N ce folosesc funcii
Angajat cude conversie
norma numr-interval
intreaga
104Angajat 4 N Angajat cu norma intreaga
105Angajat 5 N Angajat cu norma intreaga
106 Angajat 6 N Angajat cu norma intreaga
107Angajat 7 N Angajat cu norma intreaga
108 Angajat 8 N Angajat cu norma intreaga
Figura 6.30. DECODE i CASE
Din Oracle 8i apare, pe linia alinierii cu SQL-92, structura CASE,
aa c, echivalent frazei de mai sus putem folosi i alte dou soluii:
SPORURI i SALARII,
distincie realizatdin
ntre atributele prin intermediul
PI i cele din P2.celor trei brucanian
Intuiia atribute, ne
Marca, An i c
spune Luna, se poate
primele realiza
apte prin sunt
atribute trei variante:
ale PI. iar celelalte apte ale
6 Sub 10 ani de uechime O Sub
P2. 10 ani de vechime 22 Peste 20 de
tip SQL1: ani de uechime 2h Peste 20 de ani
SELECT * de uechime 26 Peste 20 de ani de
FROM sporuri, salarii uechime 21 Peste 20 de ani de
WHERE sporuri .marca = salarii .marca AND uechime 25 Peste 20 de ani de
sporuri.an = s a l a r i i . a n AND sporuri.lunauechime
= s a l a r18
i i . lUechime
una intre 10 si
20 de ani 11 Uechime intre 10 si
28 de ani 8 Sub 10 ani de uechime
cu INNER JOIN:
SELECT *
FROM sporuri INNER JOIN s a l a r i i
Figura 6.32. CASE/DECODE pe intervale
ON sporuri.marca = s a l a r i i . m a r c a AND
sporuri.an = s a l a r i i . a n AND sporuri.luna = s a l a r i i . l u n a
6.3. Jonciuni
cu NATURAL JOIN: interne
SELECT *
FROM sporuri NATURAL
ntruct JOIN salarii
inta prezentei lucrri este una covritor practic, nu
cheltuim prea mult spaiu cu fundamentarea te eretic a jonciunilor
Care sunt colegii de compartiment ai lui Angajat 2 ?
interne, ca o combinaie dintre produs cartezian i selecie, i nici cu
detalii reclam
Problema legate un
deartificiu
theta-jonciune, echi- jonciune
SQL: joncionarea i jonciune
a dou instane
natural.
ale tabelei Vom lucra,
PERSONAL duppentru nceput,
atributul la modul
compari general,liniilor
i filtrarea cu jonciuni
pentru pe care
una dinleinstane
vom aplica pentru rezolvarea
(numepren = 'Angajat ctorva probleme.este
2'). Operaiunea
posibil folosind dou alias-uri pentru cele dou instane.
Care sunt zilele din iulie 2003 n care Angajat 2 a fost la lucru ?
Informaia
SELECT care ne intereseaz, adic valorile atributului data,
pl. numepren
FROMprecum i pl,
personal condiia
personalprezen
p2 la lucru" - OreLucrate > 0, se afl n
WHERE pl. compart
tabela PONTAJE. = p2n
. compart
schimb,AND p2 . numepren
numele = 'Angajat
celebrului angajat2 ' se afl n
sau tabela PERSONAL. Aa c apelm la jonciune Pn la versiunea 9i,
Oracle s-a ncpnat s foloseasc exclusiv notaia SQL-89:
MAR NUMEfREH GDffrtr DATAS SALORA SALORARC NUMEPR COM DATASU SALDR SALORAR C
ae
CA R OC EN PA AR CO
S
Angajat 2 CONT 12-N0U-78 57588 56660 H 102 Angajat 2 CONT 12-N0U-78 57506 56000 N
1? SELECT A SELECT
pl. numeprendata A
106 Angajat A CONT 11 APR-85 71588 78608 H 102 Angajat 2 CONT 12-HOU- 575 08 56008 N
A A 78 N0U-7S
187 Angajat 7
Angajat 2 FROM CONT
A
CONT
FROMpontaje,
21 NUU-
personal
91
12-HOU-
61588
pl
57588 INNER personal
6 0808
56608
N
H
102 Angajat 2
JOIN
106 personal
Angajat 6 p2 CONT
A
CONT
12
11-APR-0S
57588
71500
56 000 N
70606 H
182 A 78 A
CONT WHERE pontaj78108 e. Nmarca = personal. A marca AND
1 06 Angajat 6 ON 11-APR-
pl.compart 71588 106 Angajat 6 CONT 11-OPR-85 71500 70080 N
187 Angajat 7 A
CONT 85
21 NOV- 61586 = p2.compart
oeoa N 106 Angajat 6 CONT 11-OPfl 85 71500 70000 N
182 Angajat 2 A
CONT 91
12-N0U-78 57560 56080 N 187 Angajat 7d a t a ) = A
CONT
186 Angajat 6 WHERE A p2
CONT 11 . EXTRACT
APR-85 numepren
71508 (YEAR
= N'Anga
78680 FROM
107 j 7
Angajat A
CONT 2 21-H0U-91
0 0 3 AND
21-NDU-91
61580
61500
60008 N
60800 N
1 87 Angajat 7 A
CONT 21-NGO-EXTRACT 61580 68668 N 187 Angajat 7 A
CONT 21-HBU-91 61500 60000 H
(MONTH FROM dMau
a t a )A
IT = 10-JUI-B3
7 AND 555 00
Angajat 1
at 2'
1 Primul Angajat Nousau A
II
IT
91
18-jm-ea
12-0CT-88
55588
56 880 55061
60
N
109 Primul
109 Primul
Angajat
Angajat Nnu IT 10-JUI -83 55508
0D
0D
1 81
1 Angajat 3 IT 02-JUL-76 numepren=
67568 66860'Angajat
N 189 Primul1'Angajat Hau IT 1S-JUL-B3 55580 0D
1 #5 Angajat 5 IT 12-NGV- 62568 62080 H 189 Primul Angajat Nou 17 10-JUL-B3 55500 fl D
189 Primul Angajat Hou IT 77
18-JUL-83 55580 00 1 81 Angajat 1 IT 12-OCT80 56000 55000 N
SELECT pl. numepren
181 Angajat 1
103 Angajat 3
IT
ITDin 9i, Oracle a revenit la sentimente mai bune fa de SQL-92,
12-0CT-88
C2-JIIL-76
56868
67586
55806 N
66160 N
181 Angajat 1
181 Angajat 1
IT 12-0CT-88 56000 55008 N
185 Angajat 5 FROM IT personal
12 HOU- pl INNER
2588 62668 N JOIN personal
101 Angajat 1 p2 ITIT
12-0CT-80
12-OCT-
56800
56800
ssooe N
55080 N
189 Primul Angajat Hau aa nct notaia este mai elegant:
IT
ON
77
18-Jill -83
pl. compart55500
= p2 0D
. 103 Angajat 3
compart AND IT Qfl
62-JllL-76 67500 66000 N
181 Angajat 1 IT 12-0CT-88 56868 55666 N 103 Angajat 3 IT 82-J0L-76 67500 66000 N
183 Angajat 3 IT B2-JUI.-76 7566 66860 N 103 Angajat 3 M 02-JUL-76 675 00 66000 N
185 Angajat 5 p2.numepren=
IT 12-NOU- 2566 'Angajat
62066 H 2'
103 Angajat 3 IT 02-JUL-76 67500 66000 N
189 Primul Angajat Hou IT SELECT
77
10-JUL-03 data
55580 6D 105 Angajat 5 IT 12-H0U-77 62500 62000 N
101 Angajat 1 IT 12-0CT-8B 56886 55601 H 105 Angajat 5 IT 12-N0U-77 62500 62880 N
183 Angajat 3 IT FROM pontaj e INNER JOIN personal
82-JUL-76 67508 66680 H 105 Angajat 5 IT 12-N0U-77 2500 62000 N
105 Angajat 5 Dincolo de notaia diferit, cele trei soluii au acelai principiu de
IT 12-N0U-77
18 JLMON 58588
62506 62000 N 105 Angajat 5 IT 12-N0U-77 62500 62 800 N
118 Al Doilea Angajat Hau PRO pontaje.marca 0 110 Al= personal.marca
Doilea Angajat Nou PROD 111-JUL sesee 0
funcionare, n prima faz, se joncioneaz instana Pl a tabelei
108 Angajat 8
10* Angajat *
D
PRO
D
PRO
30DEC-9*
WHERE
05-JAN-82
5*568
EXTRACT
75868
52BOB N
75888 H (YEAR FROM(MONTH
110 Al Doilea d
Angajat a t
Nou a )
PROD =
03
110 Al Doilea Angajat Nou PROD 10-JUL-03
2 0
10-JUL-B3 0 3
50500
AND
50500
0
EXTRACT
0
D
118 Al Doilea Angajat Hou PRO 18-JUI-83 585 8 8 8 108 Angajat 8 PfiflO 30-DFC-9* 5*5 08 52808 N
PERSONAL cu instana P2 a aceleiai tabele, atributul de joncionare
188 Angajat 8 D
PRO
D
30-DEC-9* FROM 5*588 d a 75660
t a ) N= 168
52600 H 7 AND
1B8 Angajat 0numepren= PROD 'Angajat
30-DEC-9* 5*5 1' 52080 N
00 52880
18* Angajat * PRO 85-JAH-82 75886 Angajat 8 PROD 3Q-DEC-9* 5*506 N
fiind D
D Rezultatul este cel din figura 6.33. SQL*Plus este un
compart.
11 H Al Doilea Angajat Hau PRO 18-JUL-83 5 05 6 0 a 18* Angajat * PROD 05-JAN 82 75000 75006 N
188 Angajat 8 PRO 36-DEC-9* 5*560 52688 H 10* Angajat * PROD 05-JAN-82 75600 75000 N
D
pic derutant,
18* Angajat *
Ba, deoarece
Dmai mult,n
PRO BS-JAN-
82 figur
cnd nu tabele
dou se poate
75 068
face
sunt joncionate dup atribute cu
75008 N 10* Angajat * PROD 05-JAN-82 75600 75000 N
ZIUA
9- JUL-03
Figura 6.33. Jonciunea a dou instane ale tabelei PERSONAL prin atributul compart
10- JUL-03
11- Rezultatul
JUL-03 final al interogrii este cel din figura 6.34. Pentru
eliminarea Angajatului 2 Intersecie
Figura 6.35. din rezultat ar trebui ca n WHERE s fie
prin jonciune
inclus i condiia pl. nume- pren O 'Angajat 2'.
6.4. Reuniune,
SQL> SELECT intersecie, diferen
p1.nunepren
2 FROM personal p1 INNER JOIN personal p2
Discuia
3 ONdin acest paragraf
p1.compart este, in mare
= p2.compart AND parte, de prisos,
p2.nunepren deoarece 2*
= Angajat
pn n acest
/ paragraf am recurs de cteva ori i la reuniune, i la
intersecie.
NUMEPREN
Care sunt angajaii compartimentelor Contabilitate i IT?
Angajat
La
2 cele dou soluii formulate n primul paragraf al capitolului
Angajat
(operatorii SAU logic i IN), putem aduga una ce utilizeaz UNION:
6
SEL E CT * FROM p e rs o nal WH ERE co mp art = ' CON TA'
Angajat
UN
7 ION
SEL E CT * FROM p e rs o nal WH ERE co mp art = ' IT'
Figura 6.34. Colegii de compartiment ai lui Angajat 2 (plus el nsui)
Care sunt zilele din iulie 2003 n care a lucrat mcar unul dintre
oameniiCare
muncii (dezilele
sunt la orae i sate)
n care au Angajat 1 i Primul
lucrat simultan Angajat
Angajat 1 i Primul
Nou Angajat
? Nou?
DacDei
se folosete operatorul
ne este destul UNION,
de greu, srezultatul ar conine
presupunem c nu nou linii, de
tim nimic
corespunztor
existena celor nou zileINTERSECT,
operatorului n care mcar
pe unul dintre
care-1 vomceipomeni
doi a n
venit laSELECT
serviciu:
p o l . data AS Ziua
SEL E CT Dat a
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 183
1- J
JUL-03
JUL-03 L
J0L-03 -
0A-JUL-O3 0
07-JUL-03 3
D8-J0L-03 2- J
D9-JUL-03 U
10- JUL-03 L
11- JUL-03 -
9 rows selected. O
3
B
12 rows selected.
SEL E CT Dat a
FROM po nt aje p o IN N ER JOIN p e rs o nal pe ON p o .marc a= pe .m arc a
WH ERE^ n ume p re n = ' Ang aj at 1 ' OR
184 Interogri SQL
Oracle.
186 Ghidul dezvoltrii aplicaiilor profesionale Interogri185
SQL
nume p re n= ' Primu l Ang a j at No u ' ) AN D TO_CH AR
M ERGE IN TO s alar ii SA USIN G
( d at a, MM / YYY Y ' ) = ' 0 7/ 20 03 '
(SEL
SEL ECTE CT p.ma
EX TRACrc a,T nume
( YEAR FROM
p re n, co mpd atart
a) ,AS a n,
Care EXTRA
o re lucr
suntat eCT AS( MON
zilele Ore n_LTHucr_
care FROM
Aug ,doat
au lucrat rea) AS ASlun a, mar
cosimultan ca, 1 i Primul
Angajat
SUM ( o
Angajat Nou?
Ore _CO_Aug re lucr at e ) AS o re lucr
FROM personal p L EFT OUTER JOINat e ,
s alarSUM
ii s ( o re co ) AS o re co FROM po nt a je
Acum WHputem
ERE
ON EXTRp.m ACaT =( YEAR
arc
recurge sla.marc FROM
a ANdDatan=
operatorul a) = 20303
2 00
INTERSECT: andANluna=
D EXTR 8 ACT
(M ON TH FROM d at a) = 8 GROUP BY EX TRAC T ( YEAR FROM
Ultimele dou rnduri din figura 6.38 corespund celor doi
d at a
SEL ) , d at a AS Ziu a
E CT
angajai fr CT
EXTRA niciMun pontaj pe daugust 2003, lucru indicat de spaiile
FROM po nt a j (e ON
p o TH
IN NFROM
ER JOIN at
pea)rs, oma
nalrcpe
a ON
ce )apar
POp on dreptul coloanelor r e f e r i t o a r e l a o r e l e l u c r a t e i
.marc a = pe .ma rca AN D nume p re n = ' Ang aj at 1'
o r eIN
l eTERS
ON d e.ECT
( SA anconcediu.
= P O. an AN In DSQL*Plus,
SA . luna= Pspaiile
O. lun a AN respective
D S A .m arcsemnific,
a =
pentru
SEL Eacest
CT d atgen
PO. mar ca
a ) de situaii, valori NULL.
FROM po nt a j e pTH
WH
MORCO EN M ATCH
NUMEPREN ED ENN ER JOIN pe rs
o IN COMPA
o nal ORE
pe ON LUCR AUG ORE CO AUG
UPDATE SET SA .o re lucr at e = S A .o re
p o .m arc a = pe . mar ca AN D nume p re n = ' Primu lu crat e + P O.o re
l lucr
Angat e , No u f
aj at
SA181.o re co Angajat
= S A .o re1 co + PO.o re co WH EN N OT
M ATCH
Care 182ED TH
sunt EN
Angajat
zilele din iulie2 2003 n care a lucrat Angajat 1, dar NU a
INSERT
lucrat Primul 183 Angajat(S A . an,
Angajat S A
Nou?3.lu na, S A .m arc a, S A .o re lu crat e ,
184 SA .o re co)
Angajat 4 VALUES ( PO. an, P O.lun a, P O. ma rc a,
185 Angajat PO. 5 o re lucr at e , PO. o re co )
Soluia se bazeaz pe diferen, ns, spre deosebire de standardul
SQLCare 186
n sunt
care Angajat
operatorul 6 folosit estepentru
EXCEPT, n angajat
Oracle pese
187 orele lucrate
Angajat 7 i de concediu fiecare
ntrebuineaz
luna^imie 2003 MINUS: ?
188 Angajat 8
189SEL E CT
Primul Angajat Nou
\S\S^
Folosind d at a AS Ziu a se obine rezultatul din figura 6.37, n care
jonciunea,
110 Al Doilea Angajat Nou
FROM po nt a je p o IN N ER JOIN p e rs o nal pe ON po .ma rca = p e . m arc a
sunt exclui angajaii 109 i 110, deoarece liniile lor din PERSONAL
AN D nume p re n= ' Ang aj at 1' AN D TO_CH AR( d at a,
nu au corespondent
'MM/YYYY') =' 07 n/ 20
PONTAJE.
03
M IN US
SEL E
SEL ECT
CT dp.ma
at a rc a, nume p re n, co mp art , o re luc rat e AS
Ore _L ucr_A
FROM po nt a ugje
, opre
o co
IN NAS
ER Ore _CO_
JOIN p e Aug FROM
rs o nal p e rso
pe ON na l p aIN=N pe
p o .marc ER.ma rc a
JOINANs alar ii s ON p . marc a = s .ma rca
D nume p re n = ' Pr imul Ang aj at No u' AN D an= 20 03 and
luna= 8
Angajat 1 IT 32 0
101
102 Angajat 6.5.
2MARCO Jonciuni
CONTA externe,
NUMEPREN 16 valori
DOMPA ORE LUCRnule
16AUG ORE C0 AUG
103 Angajat 3 IT 24 8
104 Angajat 4
Jonciunea PROD are o larg
extern 32 utilizare 0datorit posibilitii
105 Angajat 5 IT
extragerii, din cele dou tabele 32 0
joncionate, att a liniilor
106 Angajat 6 CONTA 32 0
corespondente, ct i a celor fr corespondent. Standardul SQL-92
107 Angajat 7 CONTA 16 16
introduce
Angajat 8 operatorii
PROD necesari jonciunii
32 externe:
0
108
LEFT OUTER JOIN pentru jonciune extern la stnga,
RIGHT OUTER JOIN pentru jonciune extern la dreapta,
FULL OUTER JOIN pentru jonciune extern total (n ambele direcii).
1 01 Ang aj at 1 72 32 1 04
1 02 Ang aj at 2 40 16 56
1 03 Ang aj at 3 40 24 64
1 04 Ang aj at 4 72 32 1 04
1 05 Ang aj at 5 72 32 1 04
1 06 Ang aj at 6 72 32 1 04
1 07 Ang aj at 7 40 16 56
1 08 Ang aj at 8 72 32 1 04
1 09 Prim ul Ang a jat N o u 24 0 24
1 10 Al Do ile a Ang aj at No u 24 0 24
URCA NUMEPREN 0RE_L_IUL SAL_BAZA_IUL CRE_L_AUG SALBAZAAUG 0re_lul-Aug SalBaza_Iul-Aug
190
Oracle. Ghidul dezvoltrii aplicaiilor profesionale Interogri SQL
189
diferit de NULL.
CASE WH ENDes2asemenea, nuISde
. o re lu crat e N OTmult
N ULLtimp a aprut funcia
TH EN s2 . o re luc rat e EL SE 0 EN
NVL2, ce evalueaz nulitatea unei expresii i returneaz D AS Ore _L ucr_ aug ,
o valoare a
CASE WH EN si. o re luc rat e IS N OT N UL L
unei alte expresii. Sintaxa este: NVL2(expresie_de_test, valoare
TH EN si. o re lucr at e EL SE 0 EN D +
retumat cnd expre- sie de test este nenul, valoare returnat cnd
CASE WH EN s2 . o re luc rat e IS N OT N ULL
expresie de test este nul).
TH ENAstfel, calculm
s2 . o re salariul
luc rat e EL SE 0 de baz pe lunile
iulie i august, ca produs
EN Dntre orele lucrate i salariul tarifar orar:
AS "Ore _L ucr_I ul- Aug "
FROM
SEL p e rsorc
ECT p.ma n al
a, pnume p re n,
L EFT
COAL OUTESERCE JOIN
(s l.osrealar
lucr iiats ie ,0) AS Ore _L _Iul,
ON (s
N VL2 p l.o
.mar cacrat
re lu = sei ,.ma
s l.orc rea luc
ANrat
D si.
e *san=
alo r2ar,
00 3
0)AN D s i. lun a= 7
L EFT OUTAS ER Sal_
JOINBaz s alar ii s 2
a_Iul,
ON ES
COAL p . mar
CE {sca2=. s2 o re.mar
luc rat caeAN , 0D
) ASs 2 Ore
. an=__L 2_aug
00 3 AN
, D s 2 . lun a= 8
N VL2 (s 2 .o re lucr at e , s2 .o re lucr at e *s alo ra r, 0 )
s au o f unc ieAS DESal_
CODE: Baz a_Aug ,
COAL ES CE( s l.o re lucr at e , 0) + COAL ES CE (s 2.o re luc rat e ,0 )
SEL ECT p.AS ma"Ore
rc a, _Iul-
nume Augp re ",n,
DECODE (s i.o re lucr
N VL2 (s l.o re lu crat e , s l.o at ere, N ULL
luc , e
rat 0 *s
, si.o
alo rre luc
ar, 0}rat+e )
AS Ore _L ucr_I ul,
N VL2 (s 2 .o re lucr at e , s2 .o re lucr at e *s alo ra r, 0 )
DECODE (s 2.o
AS "Sal re luc
Baz a_Iul-ratAuge , N"UL L , 0 , s2 .o re lucr at e )
FROM p e rso nAS al p Ore _L ucr_ aug ,
DECODE
L EFT OUT ER (s i.o
JOINre lucr
s alaratiie ,sN l ULL , 0 , si.o re luc rat e ) +
ON DECODE
p .mar ca {s=2 .o s lre lucr at
.marc a eAN
, N DUL L , 0 , s 2.o re luc rat e )
s l.
an= 20 0 3 AS AN"Ore
D s l._L ucr_I 7
luna= ul-LAug
EFT "OUTER JOIN
FROM
s alarp ii
e rso
s 2 n al p
L EFT ONOUTpER JOINa s=alar
. marc s2 ii si
. marc a
ONAN p .Dmar
s2 ca. a= n=2s i 0.ma
03 rc
AN a DAN s2D .si. an=82 00 3 AN D s i.
luna=
luna= 7 L EFT OUTER JOIN s alar ii s 2
ON p . mar ca = s2 .mar ca
Pentru prima funcie ANNVL2
D s2 .an= din 20 interogarea
0 3 AN D s 2.1 deuna=
mai8sus, logica este
urmtoarea: cnd valoarea sl. orelucrate este nenul, funcia
returneaz
Oracle produsul
9i a preluat
sl. din standardele
orelucrate SQLnfuncia
* salorar; caz contrar, zero care,
COALESCE, - vezi
figura 6.41.
pentru problema de fa, se poate aplica identic:
NR ANGAJAT!
10
Figura 6.42. Numrul angajailor
Tabela PERSONAL are drept cheie primar atributul Marca, atribut
ce nu poate avea valori nule; de aceea, la fel de corect este i
soluia:
r
U WHERE T0_CHAR(data, ,MM/VVW ) = '07/20831 AND
5 numepren = 'Angajat 4'
6 /
SUM(ORENOAPTE)
m
5
Figura 6.44. Funcia SUM
Oracle, Ghidul dezvoltrii aplicaiilor profesionale 193
SUM(ORENOAPTE)
11*
SUM(DISTINCTORENOfiPTE)
Funcia cea mai nimerit este AVG (de la AVeraGe, adic medie
aritmetic). Pentru comparabilitate, interogarea urmtoare (figura
6.46) extrage i numrul angajailor IT, i suma salariilor orare ale
acestora:
4 241500 60375
Care este cel mai mare i cel mai mic salariu orar ?
A so s it mo me nt ul f o los iri i f unc iilo r M AX i M IN :
SEL E CT M AX ( SalOr ar) AS Sa l_M AX, M IN ( SalO rar) AS
Sa l_M IN FROM pe rs o nal
SAL_MAX SALMIN
75000 50500
Figura 6.48. Funciile MAX i MIN
Care este ultima zi lucrtoare a lunii iulie 2003 ?
SEL E CT M AX ( Dat a) AS Ult im a_Z i_L ucr at o are _Iul
FROM po nt aje
WH ERE TO_CH AR( d at a, ' MM / YYY Y') = '0 7/ 2 00 3'
din prima tabel s fie mai mare dect cel din a doua. Rezultatul
jonciunii conine 45 de linii (dac nu ne credei, calculai !), ns
graie funciei MAX, va fi selectat numai prima, cea care ne
furnizeaz rspunsul (vezi figura 6.49):
SEL ECT M AX (
' Pe lo cul I ' | |
TO_CH AR( PI.S alOr ar, '9 99 99 99 ' ) | |
', ia r p e lo cul al II- le a ' | |
T0 _CH AR( P2 .SalOr ar, '9 99 99 99 ' )
) AS Tip _To p _M ini_ To p FROM
pe rs o nal p l IN N ER JOIN pe rs o nal p 2 ON
p l.s alo r ar > p 2.s alo r ar
COMPORT NR 0NG0J0TI
CONTO 3
IT il
PROD 3
Figura 6.50. Numrul angajailor din fiecare compartiment
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 197
196 Interogri SQL
UNION
S se SELECT
afieze compart,
situaia orelor lucrate de
RPAD(CHR(123 ] 1fiecare angajat -pecompart
[ ' Subtotal luna iulie
' |2003.
| Ordinea
afirii
este cea a compartimentelor,
compart,32,'-') , n cadrul fiecrui compartiment
angajaii
SUM(orelucrate * salorar) fiind ordonai
FROM personal pe LEFT OUTER JOIN ponta j e po ON
alfabetic.
pe.marca=po.marca
De data aceasta, avem dou atribute de grupare, Compart i
NumePren, plus AND TO CHAR{data,'MM/YYYY' )=' 07/2003'
GROUP BY compart, CHR(254) | | 'Subtotal - compart '
funcia SUM. Dispunerea liniilor n rezultat este asigurat prin clauza
| | compart
ORDER BY:
UNION
SELECT RPAD (CHR (123) , 8,'='),
TO CH AR ( d at a,'M M/ Y YY Y') = '0 7/ 2 00 3'
COMPORT NUMEPREN RPAD (CHR (123) ! 1 ' TOTAL General
UENITBAZA ' , 32, ' = ') ,
GROUP BY co mp art , nume p re n ORDER BY co mp a rt , nume p re n
SUM(orelucrate * salorar)
Angajat
FROM2 personal pe LEFT OUTER JOIN ponta 2300000 j e po ON
CONTA pe.marca=po.marca
CONTA Angajat
Iat6 i rezultatul - figura 6.51. 5148000
AND TO_CHAR(data,'MM/YYYY')=*07/2003'
CONTA Angajat 7 2460000
ORDER BY 1, 2
CONTA { Subtotal - compart CONTA--- 9908000
IT Angajat 1 COMPART NUMEPREN 1*032000 NR ORE L
Celor trei tipuri de nregistrri le corespund trei fraze SELECT,
IT Angajat 3 2700000
conectate prin operatorul UNION. Clauza ORDER BY se plaseaz dup
CONTA
IT Angajat 5 1*500000
IT ultimul SELECT,
CONTA
Primul Angajat Nou coloanele fiind indicate prin poziia (numrul) lor.
1332000
IT Pentru a
< Subtotal asigura ordonarea
CONTA
- compart IT------ corespunztoare,
12561*000 s-a recurs la
PROD Al caracterul
Doilea Angajat IT
ce areNoucodul ASCII, imediat superior lui z, adic 123.
1212000
PROD Rezultatul
Angajat i* IT
este cel din figura 6.52. 5400000
PROD Angajat 8 IT 3921*000
PROD IT
{ Subtotal - compart PROD---- 10536000
PROD
< ------ < TOTAL General------ !
== 33008000
PROD
PROD
Figura
SELECT 6.55. (orelucrate
MAX (SUM Numrul de linii ale produsului
* salorar) cartezian
) AS Venit Baza MAX
200 Interogri SQL
SEL E CT d at a AS Ziu a
FROM po nt aj e p o IN N ER JOIN pe rs o nal p e ON p o .marc a =
p e .marc a
WH ERE nume p re n IN ( ' Ang aj a i' , ' Pri mul Ang a j at N o u' )
GROUP BY Dat a H AV IN G COUN T ( *) = 2
Care sunt zilele din iulie 2003 n care a lucrat Angajat 1, dar NU a
lucrat Primul Angajat Nou ?
Figura 6.57. Tentativ euat de aflare a angajatului cel mai bine pltit
202 Interogri SQL
NUMEPREN SftLORAR
Angajat H 75000
Figura 6.58. Angajatul care are cel mai mare salariu orar
Care sunt angajaii cu cele mai mari dou salarii orare?
Mai greu este cu explicatul. De aceea, figura 6.59 conine cele trei etape
ale execuiei. SELECT-ul cel mai de jos" extrage cel mai mare salariu orar, n
timp ce SELECT-ul intermediar determin penultimul salariu orar.
COUNT(DISTINCTDATA)
18
Figura 6.60. Persoanele cu mai multe zile lucrate dect Primul Angajat Nou - varianta 2
206 Interogri SQL
8064000
8208000
9660000
1080000
0
9000000
10296
000
8784000
7848000
1332000
10 rows selected.
SQL> SELECT po.narca, numepren,
2 SUM (orelucrate * salorar + oreco * salorarco) AS UenitBaza
3 FROM pontaje po INNER JOIN personal pe ON po.narca=pe.marca
4 GROUP BV po.narca, nunepren
5 HAUING SUM (orelucrate * salorar + oreco * salorarco) >= ALL
6 (SELECT SUM (orelucrate * salorar + oreco * salorarco)
7 FROM pontaje po INNER JOIN personal pe ON po.narca=pe.narca
8 GROUP BV po.narca)
9 /
MARCA NUMEPREN UENIT BAZA
SQL>
Figura 6.62. Persoana cu venitul cel mai mare
MARCANUMEPREN COMPA UENIT_BAZA
103Angajat 3 IT 9660000
104Angajat 4 PROD 10800000
105Angajat 5 IT 9000000
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 209
208 Interogri SQL
(SEL E CT M IN (SUM (o re luc rat e * salorar +
SQL> SELECT po.marca,
o re co numepren,
* s alo r arco ) )
2 SUM (orelucrate
FROM p o* ntsalorar
aj e po IN +Noreco
ER JOIN* pe
salorarco)
rso n al p e RS
ON UenitBaza
3 FROM pontaje
po .mapo
rca=INNER JOIN WH
p e . marca personal pe art
ERE co mp ON = po.marca=pe.marca
' CON TA'
4 GROUP BV GROUP
po.narea,
BY pnumepren
o.m are a)
5 HAUING SUM (orelucrate * salorar + oreco * salorarco) >==
6 (SELECT SUM (orelucrate
SQL> SELECT SUM (orelucrate * salorar + oreco
* salorar * salorarco)
+ oreco * salorarco)
7 FROM
2 FROM pontaje po INNER JOIN personal pe po.marca=pe.marca
pontaje po INNER JOIN personal pe ON ON po.marca=pe.marca
8 GROUP BV po.marca)
3 WHERE compart = aCONTAa
9 / 4 GROUP BV po.marea
(SELECT
5 / SUM (orelucrate * salorar + oreco * salorarco)
*
ERRORSUM(0RELUCRATE*SAL0RAR+0REC0*SAL0RARC
at line 6:
ORA-01427: single-row subquery returns more 0) than one row
Figura 6.63. Clauz HAVING incorect n condiiile unei subconsultri multi-linie
82 08 000 10296000 8784000
SQL>
Ce SELECT po.marea,
persoane au venitul numepren, compart,mcar unui angajat al
de baz superior
2 SUM (orelucrate * salorar + oreco * salorarco) AS Uenit_Baza
compartimentului
3 FROM pontajeContabilitate?
po INNER JOIN personal pe ON po.marca=pe.marca
4 WHERE compart <> aCONTAa
De data aceasta,
5 GROUP pentru
BV po.marea, ca un angajat
numepren, comparts fie inclus n rezultat,
venitul su trebuie
6 HAUING s fie superior
SUM (orelucrate sau egal
* salorar mcar* cu
+ oreco al unuia dintre
salorarco) >= ANY
oamenii muncii
7 (SELECT SUM de la contabilitate,
(orelucrate * salorar ceea+ orecoce *reclam folsirea
salorarco)
8 FROM pontaje
operatorului ANY: po INNER JOIN personal pe ON po.marca=pe.narca
9 WHERE compart = CONTA*
10 GROUP
SEL BV. mar
ECT po po.marea)
ca, nume p re n, co mp art ,
11 / SUM ( o re lucr at e * s alo ra r + o re co * s alo ra rco )
AS Ve n it _Baz a
FROM po nt a j e p o INN ER JOIN pe rs o nal pe ON p o .mar ca= p e
.mar ca
WH ERE co mp art < > ' CON TA'
GROUP BY p o .marc a, nume p re n, co mp art
H AVIN G SUM (o re luc rat e * s alo r ar + o re co * s alo rar co) > = AN Y
(SEL E CT SUM (o re luc rat e * s alo r ar + o re co * s alo rar co)
FROM p o nt aj e po INN ER JOIN p e rso na l pe ON
po .ma rca= p e .mar ca WH ERE co mp art - ' CON TA'
GROUP BY p o .marc a)
Capitolul 7
Interogri SQL avansate
Dac precedentul capitol a fost unul de introducere n
mecanismul de interogare al bazelor de date folosind nucleul SQL al
Oracle, n continuare zbovim pre de cteva pagini pentru cteva
delicatese specifice, n general, serverelor de baze de date de
categorie grea. Astfel, vom parcurge: subconsultri declarate n
clauza FROM, interogri simplu i dublu corelate, subconsultri
a ON po.narea
scalare,
pe.Furca
expresii tabel, 3funcii analitice i interogri ierarhice.
ON po.narca - pe.narca
H WHERE nunepren 'Angajat 1* k WHERE nunepren * 'Primul Angajat Nou'
5/ S/
DATA
7.1. Subconsultri
DATA
n clauza FROM
61 -JUL-63 09-JUL-83
Sun paradoxal din partea unor autodeclarai veterani SQL", dar
02-JUL-03 18JUL-03
83-JUL-83 multe din soluiile altminteri 11-JUL-03 interesante se pierd n SQL din pricina
M-JUL-03
07- JUL-63 acestei faciliti care e att de confortabil nct uneori mbie la o
08-JUL-83
89-JUL-03
oarecare lene SQL-ist". Noroc c unele SGBD-uri nu o au
18-JUL-83 implementat... Lsnd gluma la o parte, trebuie recunoscut c i
11-JUL-03 SQL> SELECT 2ILE1.data AS Ziua
81-AUG-63 problemele2 FROHcele mai sngeroase" i pot afla naul n
04-AUG-03 3 (SELECT data
07-AUG-03 subconsultrile definite
FR0H pontaje n clauza
po INNER JOIN personal pe FROM. r
08-AUG-03 5 ON po.narca pe.narca
61-SEP-03 6 WHERE nunepren - 'Angajat 1'} ZILE1 II
02-SEP-83 Care sunt
1 zilele n care au lucrat simultan Angajat 1 i Primul
INNER JOIN
63-SEP-03
80-SEP-83
Angajat Nou?
9
8 (SELECT data
FR0H pontaje po IFttiLR J0IN personal pe
08-SEP-03 Probabil
10 c cele patru soluii din capitolul precedent nu sunt
ON pe.narea - pe.narca
11 WHERE nunepren - 'Primul Angajat Nou') ZILE2
18 rows selected. suficiente,
12 aa c formulm una care s valorifice subconsultri
0N ZILE1 .data *= Z1LE2 .data
13 /
definite n clauza FROM:
ZIUA
SEL ECT ZIL EI. d at a AS Figura
Z iua6.64. Operatorul ANY
89-JUL-63
FROM18-JUL-63
(SEL
11-JUL E
-83CT d at a
FROM p o nt a j e po INN ER JOIN p e rso na l
pe ON po .mar ca = pe .m arc a WH ERE
nume p re n = ' Ang aj at 1 ' ) ZIL EI IN N ER
JOIN
(SEL E CT d at a
FROM p o nt a j e po INN ER JOIN p e rso na l
pe ON po .mar ca = pe .m arc a
WH ERE nume p re n = ' Primu l Ang aj at No u' )
ZIL E2 ON Z IL EI.d at a = Z IL E2 .d at a
Prima subconsultare se materializeaz printr-o tabel temporar
ad-hoc numit ZILEI ce conine zilele lucrate de primul dintre
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 213
SELECT salorar
FROM
(SELECT DISTINCT salorar
FROM personal ORDER BY
salorar DESC )
WHERE ROWNUM <= 2
Figura 7.4. Angajat 3 este cel care are numrul de zile lucrate imediat
peste cel al
Angajatului 7
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 217
Figura 7.6. Primele cinci poziii din topul celor mai bine pltii angajai
SELECT *
FROM personal pel
WHERE numepren <> 'Angajat 2' AND EXISTS (SELECT marca
FROM personal pe2 WHERE numepren = 'Angajat 2'
AND pe2 . compart = pel. compart )
SELECT *
FROM personal pel
WHERE numepren <> 'Angajat 2' AND compart IN (SELECT compart
FROM personal pe2 WHERE numepren = 'Angajat 2'
AND pe2.compart = pel.compart )
SELECT *
FROM personal pel
WHERE 3 >
(SELECT COUNT (DISTINCT salorar)
FROM personal p e 2
WHERE pe2 . salorar > pel. salorar)
ORDERBY salorar DESC
SELECT
(SELECT SUM (orelucrate) FROMpontaje)
AS Total_Ore_Lucrate,
(SELECT SUM (oreco) FROMpontaje) AS Total_Ore_Concediu,
(SELECT SUM (orenoapte) FROMpontaje) AS Total_Ore_Noapte,
(SELECT SUM (po.orelucrate * pe.salorar + po.oreco *
pe.salorarco)
FROM pontai e po INNER JOIN personal pe
ON po.marca=pe.marca) AS Total_Venit_Baza
FROM DUAL
SQL> SELECT
2 (SELECT SUM (orelucrate) FROM pontaje) AS Total_Ore_Lucrate,
3 (SELECT SUM (oreco) FROM pontaje) AS Total_Ore_Concediu,
4 (SELECT SUM (orenoapte) FROM pontaje) AS Total_Ore_Noapte,
5 (SELECT SUM (po.orelucrate * pe.salorar + po.oreco * pe.salorarco)
6 FROM pontaje po INNER JOIN personal pe
7 ON po.narca=pe.marca) AS Total_Uenit_Baza
8 FROM DUAL
9 /
TOTAL ORE LUCRATE TOTAL ORE CONCEDIU TOTAL ORE NOAPTE TOTAL UENIT BAZA
SELECT
(SELECT data
FROM ponta je po INNER JOIN personal
pe ON po.marca = pe.marca WHERE
numepren = 'Angajat 1'
AND po.data=p oO.data) ZILEI,
(SELECT data
FROM ponta j e po INNER JOIN personal pe ON po.marca = pe.marca
WHERE numepren = 'Primul Angajat Nou'
AND po. data=poQ. data ) ZILE2
FROM ponta je poO WHERE zilel=zile2
Figura 7.8. Atributele obinute prin interogri scalare nu pot fi folosite n clauza
WHERE
SELECT DISTINCT
(SELECT data
FROM pontaje po INNER JOIN personal
pe ON po .marca = pe .marca WHERE
numepren = 'Angajat 1'
AND po.data=poO.data) ZILEI,
224 Oracle. Ghidul dezvoltrii aplicaiilor profesionale Interogri SQL avansate223
DATA NR ANGAJATIT0TAL PREZENI PR0CENT_PREZENT A
FROM(SELECT data
01-JUL-03 10 8 80
FROM ponta
(SELECT + j e po INNER JOIN personal pe ON po.marca =
02-JUL-03 pe.marca
FROM pontaWHERE
16 numepren 6= 'Primul Angajat Nou'
je 60
03-JUL-03 AND po.
WHERE TO^CHAR(10 data,'MM/YYYY')
data=poO. data)
6 ZILE2 FROM pont a j e poO WHERE
=' 07/2003') 60
P_IULIE
GROUP BY (SELECT
data data
FROM ponta j e po INNER JOIN personal pe ON po.marca =
pe.marca
Rezultatul este cel din figura 7.9.
WHERE numepren = 'Angajat 1' AND po. data=poO. data) =
(SELECT data
FROM ponta j e po INNER JOIN personal pe
ON po.marca = pe.marca WHERE
numepren = 'Primul Angajat Nou'
AND po.data=poO.data)
SELECT data,
(SELECT COUNT (*) FROM personal) AS Nr_Angajati_Total,
(SELECT COUNT ( * ) FROM pont a j e po WHERE orelucrate
>0 AND po. data = p_iulie. data) AS Prezeni,
( (SELECT COUNT (*) FROM ponta j e po WHERE orelucrate
>0 AND po.data = p_iulie.data) /
(SELECT COUNT (*) FROM personal) ) * 100 AS Procent
Prezenta
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 225
A.
01I-JUL- 10 6 60
03
07-JUL-03 10 6 60
08-JUL-03 10 7 70
09-JUL-03 10 9 90
10-JUL-03 10 9 90
11-JUL-03 10 9 90
SELECT data,
(SELECT COUNT (*) FROM pontaje po WHERE orelucrate
Figura 7.9. Procentul de prezen
>0 AND po . pentru
datafiecare zi lucrtoare
= p_iulie din iulie 2003
. data)
AS Prezenti_Zi_Crt,
S se calculeze
(SELECT parteaCOUNT (*) fiecrui
FROM angajat
ponta j edin totalul orelucrate
po WHERE veniturilor de baz.
>0 AND po . data = p_iulie. data - 1)
Dup calapodul exemplului precedent, folosim dou
AS Prezenti_Zi_Anter,
subconsultri scalare, una care calculeaz totalul general al
(SELECT COUNT (*) FROM pontaj e po WHERE orelucrate >0
veniturilor AND de po. baz
data i o alta
= p_iulie. data)pentru
- (SELECT determinarea
COUNT (*} FROM venitului
angajatuluiponta de pe j e linia curent
po WHERE a tabelei
orelucrate >0 AND PERSONAL
po. data (rezultatul
= p_iulie . se
prezint ca n figura 7.10):
data - 1)
AS Diferena
SELECTFROMmarea, numepren,
(SELECT
(SELECTSUM*(orelucrate
FROM ponta * salorar
j e + oreco * salorareo)
FROM pontaTO_CHAR(data,'MM/YYYY
WHERE j e po INNER JOIN personal r
) ='pe ON
07/2003') P_IULIE
GROUP BY po.marca=pe.marea)
data Total_Venituri,
(SELECT SUM (orelucrate * salorar + oreco * salorareo)
AS Venit_Baza
FROM ponta jeTOTAL po INNERUENJOIN
ITURI UEN I TAN
personal peGAJ
ON PROCEN
AT T
1 09 Prim ul Ang a jat Npo.marca=pe.marca
ou 7 52 04 00 0 13 32 00 0 1.7 7
WHERE pe .marca = personal .marca ) VenitAnga j at,
1 10 Al Do ile a Ang aj at No u ( (SELECT
ROUND 7 52 04
SUM00 (orelucrate
0 12 12 00 0
* salorar + 1.6 1 *
oreco
1 01 Ang aj at 1 7 52 04 00 0 80 64 00 0 1 0.7 2
salorareo) ASVenit_Baza FROM ponta j e po INNER
1 02 Ang aj at 2 7 52 04 00 0 82 08 00 0 1 0.9 1
JOIN personal pe ON po.marca=pe.marca WHERE
1 03 Ang aj at 3 7 52 04 00 0 96 60 00 0 1 2.8 5
1 04 Ang aj at 4 pe .marca = personal 7 52 04 00.marca
0 ) / 00 00 0
1 08 1 4.3 6
1 05 Ang aj at 5 7 (SELECT
52 04 00 0SUM (orelucrate
90 00 00 0 * salorar
1 1.9 7+
1 06 Ang aj at 6 7 52 04 00oreco
0 1*02 salorareo)
96 00 0 1 3.6 9
1 07 Ang aj at 7 7 FROM
52 04 00ponta
0 j e
87po 84INNER
00 0 JOIN personal
1 1.6 8
1 08 Ang aj at 8 7 52 04 00pe0 ON po.marca=pe.marca)
78 48 00 0 1 0.4 4 * 100, 2)
DATA PREZENTI_ZI_CRT PREZENTI_ZI_ANTER AS Procent DIFERENA
01-JUL-03 FROM personal 8 0 8
02-JUL-03 6 8 -2
03-JUL-03 6 6 0
04-JUL-03 6 6 0
07-JUL-03 6 0 6
08-JUL-03 7 6 1
09-JUL-03 9 7 2
10-JUL-03 9 9 0
11-JUL-03 9 9 0
DATA PREZENTI_ZI_CRT PREZENTI_P0NTAJ_ANTER DIFERENTA
226 Interogri SQL avansate
01-JUL-03 8 0 8
02-JUL-03 Pentru prima 6zi din iulie, atributul Prezenti
8 -2 are valoarea
Zi Anter
03-JUL-03 zero, 6 6 0
04-JUL-03 deoarece nu intereseaz
6 eventualele 6pontaje de pe 0 iunie - vezi
07-JUL-03 figura 6 7.11. 6 0 Situaia
08-JUL-03 7 de 7 iulie, deoarece6ziua precedent,
este similar zilei 1 6 iulie, a
09-JUL-03 fost 9 o 7
duminic 2 (zi
10-JUL-03 9
mai nelucrtoare dect celelalte). 9 0
11-JUL-03 Problema este9 mult mai interesant dect
9 0
precedenta, deoarece
raportarea se
face la ziua calendaristic anterioar, dar numai dac aceasta a
fost lucrtoare. De
aceea, a doua subconsultare scalar apeleaz la o subconsultare
SELECT data,
(SELECT COUNT {*) FROM pontaj e po WHERE orelucrate >0
AND po. data = p_iulie . data) AS Prezenti_Zi_Crt,
(SELECT COUNT (*) FROM pont a j e po WHERE orelucrate >0
AND po. data = (SELECT MAX (data) FROM pontaje po2
WHERE orelucrate > 0
AND po2 . data < p_iulie. data)
) AS Prezenti_Pontaj_Anter,
(SELECT COUNT (* ) FROM pontaj e po WHERE orelucrate >0
AND po. data = p_iulie. data) -
(SELECT COUNT (*) FROM pontaje po WHERE orelucrate >0
ANDpo.data= (SELECT MAX (data) FROM pontaj e po2
WHERE orelucrate > 0
AND po2 . data < p_iulie . data) ) AS Diferenta
FROM
(SELECT * FROM pontaje
WHERE TO_CHAR(data,'MM/YYYY')='07/2003') P_IULIE
GROUP BY data
WITH venituri AS
(SELECT po.marca, numepren, SUM (orelucrate * salorar +
oreco * salorarco) AS Venit_Baza FROM ponta je po INNER
JOIN personal pe ON po.marca=pe.marca GROUP BY po.marca,
numepren)
SELECT *
FROM venituri
WHERE venit baza >= 8,000000
Care este angajatul (sunt angajaii) cu cel mai mare venit
(obinut din orele lucrate, plus eventualele concedii de odihn)?
Ciudat, dac dorim s joncionm dou instane ale tabelei ad-
hoc VENITURI, obinem un mesaj de eroare de genul celui din figura
7.13, pe care nu ni l-am putut explica:
WITH venituri AS
(SELECT numepren, SUM (orelucrate * salorar +
oreco * salorarco) AS Venit_Baza FROM pontaj e
po INNER JOIN personal pe ON po.marca=pe.marca
GROUP BY numepren)
SELECT vl. *
FROM venituri vl INNER JOIN
(SELECT MAX (venit_baza) AS venit_baza FROM venituri) vraax
ON vl.venit_baza = vmax.venit_baza
WITH venituri AS
(SELECT numepren, SUM (orelucrate *
salorar+ oreco * salorarco) AS Venit_Baza
FROM ponta j e p o INNER JOIN personal pe
ON po.marca=pe.marca GROUP B Y numepren),
vmax AS
(SELECT MAX (SUM (orelucrate *
salorar + oreco * salorarco)) AS
Venit_Max FROM ponta j e po INNER
JOIN personal pe ON
po.marca=pe.marca GROUP BY numepren)
SELECT numepren, venit_baza
FROM venituri INNER JOIN vmax ON venit_baza = venit_max
SQL> WITH
2 venituri AS
3 (SELECT nunepren, SUM (orelucrate * salorar + oreco * salorarco) AS Uenit_Baza
4 FROM pontaje po INNER JOIN personal pe ON po.marca-pe.narea
5 GROUP BV nunepren),
6 vnax AS
7 (SELECT MAX(SUN (orelucrate salorar + oreco * salorarco)) AS Uenit_Max
8 FROM pontaje po INNER JOIN personal pe ON po.marca-pe.narea
9 GROUP BV nunepren)
1 0 SELECT nunepren, uenit_baza
11 FROM venituri INNER JOIN vnax ON uenit_baza - venit max
12 /
Angajat k 18800000
WITH zile AS
(SELECT po .marca, numepren, COUNT (data) AS Zile_Lucrate FROM
ponta j e po INNER JOIN personal pe ON po.marca=pe.marca WHERE
orelucrate > 0 GROUP BYpo.marca, numepren)
SELECT *
FROM zile
WHERE zile_lucrate >
(SELECT zile_lucrate FROM zile
WHERE numepren = 'Primul Angajat Nou' )
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 229
WITH zile AS
(SELECT po .marca, numepren, COUNT(data) AS ZiIe_Lucrate
FROM ponta je po INNER JOIN personal pe
ON po.marca=pe.marca
WHERE orelucrate > 0
GROUP BY po.marca, numepren) ,
Zilei AS
(SELECT COUNT (data) AS Zile_Lucrate
FROM pontaj e po INNER JOIN personal pe
ON po.marca=pe.marca
WHERE orelucrate > 0 AND numepren = ' Primul Anga j at Nou' )
SELECT * FROM zile WHERE zile^lucrate >
(SELECT zile_lucrate FROM zilei)
7.5.
/
Funcii OLAP
De la versiunea 8i, din care au fost introduse aa-numitele funcii
analitice, este din
ce n ce mai greu de inventariat tot ceea ce ofer Oracle n materie
de SQL dedicat
procesrii analitice on-line (On Line Analytical Processing). Fiecare
nou variant
vine cu exotismul su n materie de funcii din aceast categorie.
COMPART NUMEPREN UENIT_BAZA
SELECT
CASE
WHEN compart IS NULL THEN READ (CHR(123) , 8, ' =' )
ELSE compart END AS compart,
CASE
WHEN compart IS NULL THEN RPAD(CHR( 123) i |
' TOTAL General 32, ' = ')
WHEN numepren IS NULL THEN RPAD{CHR( 123) | |
'Subtotal - compart ' | | c o m p a r t , 3 2 , ' - ' )
ELSE numepren END AS numepren,
SUM(orelucrate * salorar) AS Venit_Baza FROM
personal pe LEFT OUTER JOIN pontaje po
ON pe.marca=po.marca AND TO_CHAR(data, ' M M / Y Y Y Y ' ) = ' 0 7 / 2 0 0 3 '
GROUP BY ROLLUP(compart, numepren)
ORDER BY compart, numepren
CUBE. Dac ns am fi dorit o analiz mai fin, dup trei sau mai
multe criterii, complexitatea rezultatului ar fi crescut simitor.
Atunci cnd se dorete excluderea rndurilor de detaliu" din
rezultat sau a unora dintre subtotaluri, se poate folosi clauza
GROUPING SETS:
SELECT
EXTRACT (MONTH FROM data) AS Luna,
CASE GROUPING (numepren)
WHEN 1 THEN
CASE GROUPING (EXTRACT (MONTH FROM data) )
WHEN 1
THEN CHR ( 1 2 3 ) | |
' T O TA L G E N E R A L '
ELSE CHR ( 1 2 3 ) || '-----Subtotal luna---------'
I | EXTRACT (MONTH FROM data)
END
ELSE
CASE GROUPING (EXTRACT (MONTH FROM d a t a ) )
WHEN 1
THEN CHR ( 1 2 3 ) || ' * Subtotal *' | |
numepren ELSE numepren
END
END AS Numepren,
SUM(orelucrate * salorar) AS Venit_Baza
FROM personal pe LEFT OUTER JOIN pontaj e po
ON pe.marca=po.marca
GROUP BY GROUPING SETS (EXTRACT (MONTH FROM data) , numepren )
ORDER BY EXTRACT (MONTH FROM data) , numepren
SELECT
GROUP BY GROUPING SETS (EXTRACT (MONTH FROM
data) , numepren, () )
ORDER BY. . .
LUNANUMEPREN UENIT_BAZA
7<- - luna----7 33008000
Subtotal Figura 7.18. Un CUBE
8<- - luna----8 13748000
9<-
Clauza GROUPING
Subtotal
- luna----9 se poate folosi dup20240000
aceeai logic expus la
< * exemplul dedicat
Subtotal 81 Doileaoperatorului
Angajat Nou ROLLUP. Pentru a pstra o
1212000
< * dimensiune
Subtotal rezonabil
* Angajat 1 a rezultatului (40 de linii), interogarea
8064000
< * folosete doar
Subtotal dou atribute
* Angajat 2 n clauza GROUP
5520000
BY
< * Subtotal * Angajat 3 7020000
< * Subtotal * Angajat 4 10800000
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 237
{ *
Subtotal * Angajat 5 9000000
< -
*
Subtotal * Angajat
aplicate 6 n fiecare partiie.10296000
linie cu linie Pasul 3 este operaional numai dac
<
Subtotal * Angajat 7 5904000
interogarea prezint la sfrit o clauz ORDER BY, ceea ce atrage ordonarea
< *
Subtotal * Angajat 8 7848000
final a rezultatului n conformitate cu criteriile specificate. Part i iile
< *
Subtotal * Primul Angajat Nou 1332000
reprezint seturi de linii create dup delimitarea grupurilor prin GROUP BY,
SALORAR P0ZIT1E_RANK P0ZITIE_DENSE_RAN
astfel nct pot constitui subiectul oricrei funcii de agregare (SUM,
K
Angajat 4 75000
AVG...). Constituirea 1
unei partiiile realizeaz n funcie 1de valorile unuia
Angajat 6 sau mai multor atribute
71500 sau expresii de 2 atribute. 2
Angajat 3 67500 3 3
Angajat 5 67500
POZIIE NUMEPREN 3 3
SALORAR
Angajat 7 61500 5 4
Angajat 2 57500 6 5
Angajat 1 1 56000
Angajat 4 7 675000
Primul Angajat Nou 2 Angajat
55500 6 8 771500
.Angajat 8 3 54500
Angajat 3 9 867500
Al Doilea Angajat Nou 4 50500
Angajat 5 10 967500
5 Angajat 7 61500
Figura 7.19.
6 Angajat Clauza GROUPING
2 SETS 57580
7 Angajat 1 56800
8 Primul Angajat Nou 55500
7.5.4. Clasamente: RANK i DENSE_RANK
9 Angajat 8 54588
10 Al Doilea Angajat Nou 50500
Numai n acest capitol au fost formulate cel puin trei soluii pentru
extragerea primelor dou, Figuratrei
7.20. Clasamentul
.a.m.d.salariilor
valori orare
dintr-un clasament.
S ne oprim
Interogarea urmtoare pune n eviden orare.
momentan asupra topului salariilor modul Dar, nainte
de lucru al celor
de toate, s presupunem c Angajat 5 primete o mrire
dou funcii - vezi figura 7.21. Valorile egale au acelai ordin n de salariu
orar ambele
cifrat la 5000 dens,
variante, lei, astfel
n timp nct ajunge
ce RANK la nivelul
atribuie Angajatului
n continuare poziiile
3: lund n calcul numrul valorilor egale,
DENSE_RANK nu.
UPDATE personal
SELECT numepren, salorar,
SET salorar = 6 7 5 0 0
RANK{) OVER (ORDER BY salorar DESC) AS Pozitie_RANK,
WHERE numepren = 'Angajat 5' ;
DENSE_RANK() OVER (ORDER BY salorar DESC)
COMMIT ;
AS Pozitie_DENSE_RANK
FROM personal
La modul cel mai simplu, clasamentul salariilor orare se obine
apelnd la o subconsultare n clauza FROM i pseudo-coloana
ROWNUM:
Care sunt cele mai mari trei salarii orare i care sunt fericiii
angajai?
Funciile analitice nu pot fi incluse n clauze WHERE - vezi figura
7.22.
SELECT *
FROM
(SELECT numepren, SUM (orelucrate * salorar +
oreco* salorarco) AS Venit_Baza,
RANK() OVER (ORDER BY SUM (orelucrate * salorar+
oreco * salorarco} DESC) AS Poziie FROM personal INNER
JOIN pontaj e
ON personal.marca = pontaje.marca
GROUP BY numepren)
WHERE poziie <= 5
Angajat 4 10800808 1
Angajat 6 10296000 2
Angajat 5 9720000 3
Figura 7.21. Funciile RANK i DENSE_RANK
Angajat 3 9660000 4
Angajat 7 8784000 5
C0MPA NUMEPREN UENITBAZA POZIIE
CONTA Angajat 6 10296000 1
CONTA Angajat 7 8784000 2
IT Angajat 5 9720000 1
IT Angajat 3 9660000 2
PR0D Angajat 4 10800000 1
PR0D Angajat 8 7848000 2
240 Oracle. Ghidul dezvoltrii aplicaiilor profesionale 241
Interogri SQL avansate
FROM
(SELECT d a t a , C O U N T ( * ) AS Prezeni FROM
ponta je WHERE orelucrate > 0
AND T O _ C H A R ( d a t a , ' M M / YYYY' ) = '
0 7 / 2 0 0 3 ' GROUP BY d a t a )
SELECT data,
Prezeni AS Prezenti_Zi_Curenta,
NVL (LAG (Prezeni, 1) OVER (ORDER BY data) , 0)
AS Prezenti_Zi_Anterioara,
Prezeni - NVL(LAG (Prezeni, 1) OVER (ORDER BY d a t a ) , 0 )
AS Diferena
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 243
Care este cel mai bine pltit angajat din fiecare compartiment?
Funcia FIRST VALUE se plaseaz intr-o subconsultare ce extrage,
pentru fiecare angajat, venitul su de baz i cel mai mare venit de baz
din compartimentul din care face parte. Fraza SELECT principal extrage
numai liniile n care cele dou venituri sunt egale:
n i t , ROUND
S E L E C T n u m e p r e n , v eCREATE (RAT(
IO__TO_RE PORT (venit)
TABLE ierarhie
OVER () * IOC, 2) AS marca INTEGER
Pondere FROM CONSTRAINT nnjerarhiejnarca NOT NULL CONSTRAINT pkjerarhie
PRIMARY KEY
(SELECT numepren, SUM (orelucrate * s a l o r a r +
CONSTRAINT fk_ierarhie_personal REFERENCES personal (marca)
oreco l o r a r c o ) AS Venit FROM ponta j e po
* s aINTEGER
, marca_sef
INNER JOIN personal
CONSTRAINT pe ON po.marca=pe.marca
fk_ierarhie_personal2 REFERENCES personal (marca)
WHERE pe . marca = po . marca GROUP BY
);
numepren )
ORDER BY numepren
INSERT INTO ierarhie VALUES (104, NULL);
INSERT INTO ierarhie VALUES (108, 104);
INSERT INTO ierarhie VALUES (106, 104);
INSERT INTO ierarhie VALUES (105, 104);
INSERT INTO ierarhie VALUES (110, 108);
INSERT INTO ierarhie VALUES (102, 106);
7.6. Interogri ierarhice
INSERT INTO ierarhie VALUES (107, 106);
INSERT INTO ierarhie VALUES (103, 105);
INSERT INTO ierarhie VALUES (101, 105);
Problema structurii
INSERT ierarhice
INTO ierarhie sau103);
VALUES (109, a arborilor este una care a
COMMIT;__________________________________
suscitat discuii cel puin interesante n comunitatea SQL. Din acest
punct de vedere, Oracle s-a plasat lejer, de ani buni, n faa
S lum
concurenei. n discuie
Cum aproapecteva probleme.
ntotdeauna cnd spunem ierarhie ne
referim la organigram, s analizm structura personalului firmei
aa cumCare este nivelul
se prezint ierarhic
n figura 7.27.al fiecrui salariat?
Din parcurgerea figurii 7.27 deducem c sunt patru niveluri
ierarhice: primul este cel al managerului general (Angajat 4), al
doilea, al efilor de compartimente (Angajat 8 - Producie, Angajat 6
- Contabilitate, Angajat 5 - IT), al treilea, pentru plmai (Al Doilea
Angajat Nou, Angajaii 2, 7 i 1) i un ef mai mititel (Angajat 3), iar
pe ultimul nivel, al patrulea, apare un singur om al muncii (probabil
pentru a echilibra singurtatea managerului general) - Primul
Angajat Nou. Altfel spus, ne intereseaz o situaie asemntoare
MARCA NUMEPREN C0MPA NIUEL
SELECT
Oracle. Ghidul dezvoltrii aplicaiilor profesionale 249
directorului general?
Practic, liniile care intereseaz sunt cele nepot" ale
nregistrrii-rdcin, Figura
cea 7.29. efii Angajatului
pentru care Marca 7 Sef IS NULL. Dac inem
cont
eful c directorul
imediat general este
al Angajatului 7 este pecel primul nivel
de nivel ierarhic,
2 din figura atunci
de
mainepoii
sus: si sunt plasai pe nivelul 3:
SEL ECT *
SEL ECT *
n
FROM
FROM
(SEL E CT m arc a, nume p re n, co mp art , L EV EL AS
(SEL E CT ma rc a, nume p re n, co mp art , L EV EL AS
N ive l FROM
N ive l FROM
(SEL E CT p .mar ca, numep re n, co mp a rt ,
(SEL E CT p .mar ca, numep re n, co mp a rt ,
mar ca_s ef FROM pe rs o nal p INN ER JOIN ie r arhie
n
mar ca_s ef FROM pe rs o nal p INN ER JOIN ie r arh ie
i ON p . marc a = i . mar ca)
i ON p .mar ca = i.m arc a)
STA RT WI TH nume p re n = ' Ang a j at 7'
STA RT WITH m arc a_s ef IS N UL L
CON N ECT BY PRIORm ar ca_s ef = mar ca
CON N ECT BY PRIOR marc a
) = marc a_s ef )
WHWH
EREEREnive l = l2= 3
nive
Care
Ssunt
semnului
subordonaii
se afieze
Piramida
Pentruse
egal al
indentare
direci
structura
unconstruiete
ai Angajatului
ierarhic
plus de vizibilitate
laCONNECT atributul
stnga;BY dup
a firmei. 5?
de la Angajat
vom 2afia
n jos, plasnd
numele n stnga cu
angajailor
Marca: angajat urmeaz imediat
fiecare
subordonaii si i subordonaii subordonailor - vezi figura 7.31.
n
n
SEL ECT *
Fiecrui nivel ierarhic i va corespunde un nivel de indentare.
FROM
Funcia
(SEL E CTfolosit pentru
m arc a, nume indentare
p re n, co mp art , este
L EV EL LPAD.
AS n rest, lucruri
cunoscute:
N ive l FROM
(SEL E CT p .mar ca, numep re n, co mp a rt ,
SEL ECT Lmar
PADca_s
AS nume
( ' ',
i ON ppre
ef5FROM
* (L EVpe
n, coa
. marc mp= art
ELrs-o1nal
i . ,nj&rc
) , p INN
L EV EL
) | ER
| nume
JOINpie
a) AS N ive l FROM
rernarhie i
(SEL E CT p .mar ca, numep re n, co mp a rt ,
mar ca_s ef FROM pe rs o nal p INN ER JOIN ie r arh ie i ON