Professional Documents
Culture Documents
Continguts
Llenguatge SQL
1. DML SQL
2. DDL SQL
3. Transaccions i concurrència
SQL hostatjat
1. SQL hostatjat amb Oracle PL/SQL
2. Disparadors
Àlgebra relacional
1. Operacions amb àlgebra relacional
ii
Llenguatge SQL
Estudi del llenguatge ANSI SQL. Utilització del
llenguatge SQL en el SGBDR Oracle.
Contingut
Contingut
Capítol 1. Introducció a SQL ....................................................................................3
1.1. Història d’SQL ............................................................................................................................ 3
1.1.1. Introducció ...................................................................................................................... 3
1.1.2. Versions .......................................................................................................................... 3
1.2. Modes d’utilització ...................................................................................................................... 3
1.3. Elements del llenguatge SQL ..................................................................................................... 4
Capítol 2. DML SQL..................................................................................................6
2.1. Consulta de dades sobre una taula............................................................................................ 6
2.1.1. Sintaxi ............................................................................................................................. 6
2.1.2. Ús d’ÀLIES...................................................................................................................... 8
2.1.3. Càlculs ............................................................................................................................ 8
2.1.4. Condicions de selecció ................................................................................................. 11
2.1.5. Ordenació ..................................................................................................................... 17
2.1.6. Funcions ....................................................................................................................... 19
2.1.7. Agrupacions .................................................................................................................. 34
2.2. Consulta de dades sobre vàries taules .................................................................................... 37
2.2.1. Introducció .................................................................................................................... 37
2.2.2. Producte cartesià de taules .......................................................................................... 38
2.2.3. Combinació de taules ................................................................................................... 40
2.2.4. Obtenir registres que no estan relacionats ................................................................... 42
2.2.5. Auto combinacions........................................................................................................ 43
2.2.6. Sintaxi SQL 1999 .......................................................................................................... 43
2.2.7. Subconsultes ................................................................................................................ 47
2.2.8. Operadors de conjunts.................................................................................................. 53
2.3. Inserció, modificació i eliminació .............................................................................................. 55
2.3.1. Introducció .................................................................................................................... 55
2.3.2. Inserció de dades.......................................................................................................... 55
2.3.3. Modificació de dades .................................................................................................... 58
2.3.4. Eliminació de dades...................................................................................................... 60
2.3.5. Utilització dels valors per defecte.................................................................................. 61
Capítol 3. DDL SQL ................................................................................................62
3.1. Introducció a les sentències de definició .................................................................................. 62
3.1.1. Introducció .................................................................................................................... 62
3.1.2. Creació i esborrat d’una BDR ....................................................................................... 62
3.1.3. Objectes de BD............................................................................................................. 63
3.2. Definició del nivell conceptual: taules i restriccions .................................................................. 63
3.2.1. Creació de taules .......................................................................................................... 64
3.2.2. Modificar l’estructura de taules ..................................................................................... 70
3.2.3. Eliminar l’estructura de taules ....................................................................................... 73
3.2.4. Canviar el nom de taules (Oracle) ................................................................................ 74
3.2.5. Esborrar el contingut d’una taula (Oracle) .................................................................... 74
3.2.6. Restriccions .................................................................................................................. 74
3.3. Definir el nivell intern: índexs.................................................................................................... 85
3.3.1. Introducció .................................................................................................................... 85
3.3.2. Creació d’índexs ........................................................................................................... 86
3.3.3. Índexs basats en funcions ............................................................................................ 87
3.3.4. Llistar els índexs ........................................................................................................... 87
3.3.5. Esborrar índexs............................................................................................................. 87
3.4. Definició del nivell extern: vistes............................................................................................... 87
3.4.1. Introducció .................................................................................................................... 87
3.4.2. Creació de vistes .......................................................................................................... 88
3.4.3. Llistar les vistes............................................................................................................. 90
3.4.4. Esborrar vistes .............................................................................................................. 90
3.5. Definir altres objectes de la base de dades.............................................................................. 91
3.5.1. Introducció .................................................................................................................... 91
3.5.2. Seqüències ................................................................................................................... 91
3.5.3. Sinònims ....................................................................................................................... 94
Capítol 4. Transaccions i concurrència ..................................................................96
4.1. Gestió de transaccions ............................................................................................................. 96
4.1.1. Introducció .................................................................................................................... 96
4.1.2. Transaccions................................................................................................................. 96
4.2. Gestió de la concurrència......................................................................................................... 98
4.2.1. Consistència de lectura................................................................................................. 99
4.2.2. Bloqueig...................................................................................................................... 100
ii
UD2. Llenguatge SQL Introducció a SQL
1.1.1. Introducció
L’any 1970, Codd va introduir el concepte de Base de Dades Relacional, però va portar
un temps el disseny d’un sistema real de gestió de bases de dades relacional (SGBDR o
RDMBS). El primer i que es recorda més és System R (dissenyat per IBM), el qual no
era més que un prototipus, l’objectiu principal del qual era demostrar que amb aquest
sistema era possible construir un Sistema Relacional, que es podia utilitzar en un entorn
real, per solucionar problemes reals. No obstant, va ser Oracle qui el va introduir per
primera vegada en un programa comercial (1979).
Aquest sistema incorporava un llenguatge de dades que permetia fer qualsevol accés a
la base de dades, que es va anomenar SEQUEL (Structured English Query Language).
Posteriorment altres sistemes van adoptar aquest subllenguatge, que es va passar a
anomenar SQL, com a subllenguatge de consulta de dades, que fins avui dia ha patit
diverses modificacions.
La seva utilització dins l’àmbit comercial és realment extensa. Les cases comercials
l’inclouen dins els seus productes i és l’estàndard més important en aquest camp.
SQL és una abreviació de “Structured Query Language” (llenguatge de consulta
estructurat). Amb aquest llenguatge es poden crear operacions relacionals, és a dir,
operacions que permeten definir i manipular una base de dades relacional.
1.1.2. Versions
Nosaltres estudiarem SQL-92. Per tant, quan parlem del llenguatge SQL, ens estarem
referint a la versió SQL-92. En els casos en que es parli de característiques pròpies de
versions posteriors, ja s’indicarà.
3
UD2. Llenguatge SQL Introducció a SQL
A part d’un llenguatge de consulta, en realitat el llenguatge SQL és molt més que això, ja
que té altres funcions a més a més de les de consultar una base de dades. Entre
aquestes hi ha:
DDL. Llenguatge de definició de dades.
DML. Llenguatge de manipulació de les dades.
DCL. Llenguatge de control de dades. Permet indicar restriccions d’accés i seguretat.
A continuació veurem per sobre com fer aquestes tasques, amb varis exemples:
4
UD2. Llenguatge SQL Introducció a SQL
Crear una taula (comanda DDL) que contingui les dades dels productes de l’empresa:
CREATE TABLE producte Nom de la taula
(
codi INTEGER,
nom CHAR(20),
tipus CHAR(20), Nom de les columnes i tipus (domini)
descripcio CHAR(50),
preu REAL,
PRIMARY KEY (codi) Clau primària
);
Valors
Consultar (comanda DML) quins productes són de la fila
cadires:
Nom de la taula
Columnes
SELECT seleccionades
codi, nom
FROM producte
WHERE tipus = ‘cadira’;
Files seleccionades
Nom de la taula
Les operacions a SQL reben el nom de sentències i estan formades per diferents parts
anomenades clàusules.
Quan escrivim sentències del llenguatge SQL, cal tenir present que hi ha unes normes
d’escriptura:
No hi ha distinció entre majúscules i minúscules.
Una sentència sempre acaba amb el símbol ;
Les sentències SQL es poden escriure en vàries línies per facilitar-ne la lectura (molt
recomanable!!)
Per incloure comentaris en el codi SQL, aquests es posen entre /* i */.
5
UD2. Llenguatge SQL DML SQL
2.1.1. Sintaxi
On:
SELECT s’utilitza per determinar les columnes que es volen obtenir.
FROM especifica una llista de taules que s’utilitzen a la consulta.
* significa que se seleccionen totes les columnes.
DISTINCT fa que no es mostrin els valors duplicats.
columna. És el nom d’una columna de la taula que es vol mostrar.
expressió. És una expressió SQL vàlida (una operació, una funció de
totals, etc.)
6
UD2. Llenguatge SQL DML SQL
Exemple 1
DEPT_NUM
---------
10
20
30
40
Exemple 2
Exemple 3
EMPL_DEPT_NUM
-------------
20
30
30
20
30
30
10
20
10
30
20
30
20
10
14 rows selected.
7
UD2. Llenguatge SQL DML SQL
Exemple 4
EMPL_DEPT_NUM
-------------
10
20
30
2.1.2. Ús d’ÀLIES
Quan es consulta una taula, els noms de columnes s’utilitzen com a capçaleres de
presentació. Si aquests noms són massa llargs o críptics es poden canviar amb la
mateixa sentència SQL de consulta, creant un ALIES.
Sintaxi
2.1.3. Càlculs
Aritmètics
Els operadors + (suma), - (resta), * (multiplicació) i / (divisió), es poden utilitzar per fer
càlculs a les consultes. Quan s’utilitzen com expressió en una consulta SELECT, no
modifiquen les dades originals sinó que com a resultat de l’execució del SELECT,
apareix una columna amb el resultat de l’expressió.
La prioritat d’aquests operadors és:
tenen més prioritat la multiplicació i divisió,
després la suma i la resta.
En cas d’igualtat de prioritat es realitza primer la operació que estigui més a l’esquerra
(associativitat per l’esquerra).
Com és lògic, es pot evitar complir aquesta prioritat utilitzant parèntesis; l’interior dels
parèntesis és el que s’executa primer.
Quan una expressió aritmètica es calcula sobre valors NULL, el resultat de l’expressió és
sempre NULL.
Exemple:
SQL> SELECT empl_num, empl_nom, empl_salari, empl_salari*2
2 FROM empl ;
8
UD2. Llenguatge SQL DML SQL
14 rows selected.
Aquesta consulta obté tres columnes. Com es pot veure, la tercera té com a títol,
l’expressió utilitzada. És en aquests casos quan és més freqüent la utilització d’alies.
Exemple:
SQL> SELECT empl_num, empl_nom, empl_salari,
2 empl_salari*2 as doble_salari
3 FROM empl;
14 rows selected.
Els noms d’alies poden portar espais si es posen entre cometes dobles:
SQL> SELECT empl_num, empl_nom, empl_salari,
2 empl_salari*2 as "doble salari"
3 FROM empl;
9
UD2. Llenguatge SQL DML SQL
14 rows selected.
Concatenació
Numero i Nom
-----------------------------------------------------------
7369 - SANCHEZ
7499 - ARROYO
7521 - SALA
7566 - JIMENEZ
7654 - MARTIN
7698 - NEGRO
7782 - CEREZO
7788 - GIL
7839 - REY
7844 - TOVAR
7876 - ALONSO
7900 - JIMENO
7902 - FERNANDEZ
7934 - MUNOZ
14 rows selected.
10
UD2. Llenguatge SQL DML SQL
Es poden realitzar consultes que filtrin les dades de sortida de les taules. Per això
s’utilitza la clàusula WHERE. Aquesta clàusula permet col·locar una condició que han de
complir tots els registres, els que no la compleixin no apareixeran en el resultat.
Exemple: Seleccionar el número, nom i ofici dels empleats.
SQL> select empl_num, empl_nom, empl_ofici
2 from empl;
Exemple: Seleccionar el número, nom i ofici dels empleats que són directors.
SQL> select empl_num, empl_nom, empl_ofici
2 from empl
3 Where empl_ofici='DIRECTOR';
Sintaxi
11
UD2. Llenguatge SQL DML SQL
Operadors de comparació
Es poden utilitzar tant per comparar números com per comparar textos i dates. En el cas
dels textos, les comparacions es fan en ordre alfabètic.
Operadors lògics
Operador Significat
Retorna CERT si les
AND expressions de la seva esquerra
i dreta són les dues certes.
Retorna CERT si qualsevol de
OR les expressions de la seva
esquerra i dreta són certes.
Inverteix la lògica de l’expressió
que està a la seva dreta. Si era
NOT
cert, mitjançant NOT passa a
ser fals.
14 rows selected.
12
UD2. Llenguatge SQL DML SQL
Operador BETWEEN
on:
expressió1 és una expressió avaluable de la que es vol
comprovar si està dins els rang definit entre expressió2 i
expressió3.
[NOT] és opcional. S’utilitza per indicar que es vol
seleccionar tots els registres que no tenen valors entre
expressió2 i expressió3.
expressió2 és una expressió avaluable que indica el límit
inferior del rang de valors.
expressió3 és una expressió avaluable que indica el límit
superior del rang de valors.
Exemple: Obtenir tots els empleats que tenen un salari entre 100000 i 200000.
SQL> select empl_num, empl_nom, empl_salari
2 from empl
3 where empl_salari between 100000 and 200000;
7 rows selected.
Exemple: Obtenir tots els empleats que no tenen un salari entre 100000 i 200000.
SQL> select empl_num, empl_nom, empl_salari
2 from empl
3 where empl_salari not between 100000 and 200000;
13
UD2. Llenguatge SQL DML SQL
7 rows selected.
Operador IN
Permet obtenir registres que tenen (o no tenen) valors dins una llista.
SINTAXI
expressió1 [NOT] IN (llistaValors)
on:
expressió1 és una expressió avaluable de la que es vol
comprovar si està dins la llistaValors.
[NOT] és opcional. S’utilitza per indicar que es vol
seleccionar tots els registres que no tenen valors dins la
llistaValors.
llistaValors és una llista de valors.
Exemple: Obtenir els empleats que són director o president.
SQL> select empl_num, empl_nom, empl_ofici
2 from empl
3 where empl_ofici IN ('DIRECTOR','PRESIDENT');
14
UD2. Llenguatge SQL DML SQL
10 rows selected.
Operador LIKE
S’utilitza sobretot amb textos. Permet obtenir registres que tenen alguna columna que es
vol que compleixi una condició textual.
SINTAXI
expressió1 [NOT] LIKE cadena
on:
expressió1 és una expressió avaluable de la que es vol
comprovar si és com cadena.
[NOT] és opcional. S’utilitza per indicar que es vol
seleccionar tots els registres que no tenen valors que
compleixen cadena.
cadena és un valor textual. Aquest valor textual pot
incloure dos símbols especials:
Operador Significat
Indica que on hi hagi aquest
símbol s’interpreta com si hi
%
hagués 0 o més caràcters en
aquella posició.
Indica que on hi hagi aquest
símbol s’interpreta com
_
exactament un caràcter
qualsevol.
NOTA: quan es fan comparacions amb cadenes textuals la diferència entre minúscules i
majúscules és significativa.
15
UD2. Llenguatge SQL DML SQL
Exemple: Obtenir tots els empleats que el seu nom acabi amb EZ.
SQL> select empl_num, empl_nom
2 from empl
3 where empl_nom like '%EZ';
EMPL_NUM EMPL_NOM
---------- ----------------
7369 SANCHEZ
7566 JIMENEZ
7902 FERNANDEZ
Exemple: Obtenir tots els empleats que el seu nom tingui 3 caràcters i comenci amb GI.
SQL> select empl_num, empl_nom
2 from empl
3 where empl_nom like 'GI_';
EMPL_NUM EMPL_NOM
---------- ----------------
7788 GIL
Operador IS NULL
16
UD2. Llenguatge SQL DML SQL
Precedència d’operadors
De vegades les expressions que podem arribar a crear en instruccions de selecció són
molt extenses i és difícil saber quina part de l’expressió és la que s’avalua primer.
En la següent taula s’indica la precedència dels operadors:
Ordre Operador
1 * /
2 + -
3 ||
4 > < >= <= <>
5 IS [NOT] NULL, [NOT] LIKE, IN
6 [NOT] BETWEEN
6 NOT
7 AND
8 OR
2.1.5. Ordenació
L’ordre inicial dels registres obtinguts per una instrucció SELECT té relació amb l’ordre
en que es van introduir les dades. Per tal d’ordenar en base a criteris mes interessants,
s’utilitza la clàusula ORDER BY.
En aquesta clàusula es col·loca una llista de camps que indica la forma d’ordenar.
S’ordena primer pel primer camp de la llista, si hi ha coincidències pel segon, si també hi
ha coincidències pel tercer, i així successivament.
Es poden col·locar les paraules ASC o DESC (per defecte sempre és ASC). Aquestes
paraules indiquen l’ordenació que es vol fer (ASCendent o DESCendent,
respectivament).
17
UD2. Llenguatge SQL DML SQL
Exemple: Obtenir l’ofici, nom i salari dels empleats que tenen un salari superior a
200000, ordenat ascendentment per ofici i nom.
SQL> SELECT empl_ofici,empl_nom,empl_dept_num
2 FROM empl
3 WHERE empl_salari>200000
4 ORDER BY empl_ofici,empl_nom ASC;
7 rows selected.
Exemple: Obtenir l’ofici, nom i salari dels empleats que tenen un salari superior a
200000, ordenat ascendentment per ofici i descendentment per nom.
SQL> SELECT empl_ofici,empl_nom,empl_dept_num
2 FROM empl
3 WHERE empl_salari>200000
4 ORDER BY empl_ofici,empl_nom DESC;
7 rows selected.
1
Per indicar quines expressions es volen ordenar es pot fer indicant l’expressió o bé el número d’expressió tenint
en compte l’ordre en què han estat escrites. Exemple: …ORDER BY empl_nom; o bé … ORDER BY 1;
18
UD2. Llenguatge SQL DML SQL
2.1.6. Funcions
SQL no incorpora funcions específiques pel tractament dels diferents tipus de dades.
Aquestes funcions doncs, són pròpies de cada SGBD. Nosaltres, com que estudiem el
SGBD Oracle veurem les funcions que incorpora que permeten realitzar càlculs
avançats, o bé facilitar l’escriptura de certes expressions. Totes les funcions reben dades
per poder operar (paràmetres) i retornen un resultat (que depèn dels paràmetres passats
a la funció). Els paràmetres es passen entre parèntesi:
nomFunció [(paràmetre1[, paràmetre2,...])]
Funcions de caràcters
Exemples:
SQL> SELECT lower('Hola Món')
2 FROM dual;
LOWER('H
--------
hola món
UPPER('H
--------
HOLA MÓN
INITCAP(
--------
Hola Món
19
UD2. Llenguatge SQL DML SQL
Funcions de transformació
Funció Descripció
RTRIM(text) Elimina els espais a la dreta del
text.
RTRIM(text,car) Elimina el conjunt de caràcters car
de la dreta del text.
Elimina els espais a l’esquerra del
LTRIM(text)
text.
Elimina el conjunt de caràcters car
LTRIM(text,car)
de l’esquerra del text.
Elimina els espais en blanc a la
TRIM(text)
dreta i esquerra de text.
Elimina del text els caràcters
indicats.
TRIM(caràcters FROM text)
Exemple: TRIM(‘s’ FROM
‘supers’) retorna ‘uper’.
Obté els m següents caràcters del
text a partir de la posició n (si m
SUBSTR(text,n[,m])
no s’indica s’agafen des de n fins
al final.
LENGTH(text) Obté la mida del text.
Obté la posició en la que es troba
el text que es vol trobar en el text
inicial. Es pot començar a buscar
a partir d’una posició inicial
concreta i fins i tot indicar el
INSTR(text,textATrobar número d’aparició del text que es
[,inici[,nAparició]]) vol trobar.
Exemple: si busquem la lletra ‘a’ i
posem 2 en el paràmetre
nAparició, retorna la posició de la
segona lletra ‘a’ del text.
Si no ho troba retorna 0.
Buscar el text textATrobar en un
REPLACE(text, determinat text (paràmetre text) i
textATrobar, nouText) un cop trobat el canvia pel
nouText.
Omple el text a l’esquerra (LPAD)
LPAD(text,ampladaMàxima, o a la dreta (RPAD) amb el
caràcterOmplir) caràcter indicat per ocupar
RPAD(text,ampladaMàxima, l’amplada indicada.
caràcterOmplir) Si el text és més gran que
l’amplada indicada, es retalla.
Exemples:
SQL> SELECT RTRIM('hola món ')
2 FROM dual;
RTRIM('H
--------
hola món
20
UD2. Llenguatge SQL DML SQL
MISSATGE
--------------------
hola
MISSATGE
--------------------
hola món
MISSATGE
--------------------
món
MISSATGE
--------------------
hola món
MISSATGE
--------------------
món
MISSATGE
--------------------
món
LONGITUD
----------
8
POSICIO
----------
6
21
UD2. Llenguatge SQL DML SQL
POSICIO
----------
10
CANVI
-----------
hola a tots
NOM
----------
***SANCHEZ
****ARROYO
******SALA
***JIMENEZ
****MARTIN
*****NEGRO
****CEREZO
*******GIL
*******REY
*****TOVAR
****ALONSO
****JIMENO
*FERNANDEZ
*****MUNOZ
14 rows selected.
NOM
----------
SANCHEZ***
ARROYO****
SALA******
JIMENEZ***
MARTIN****
NEGRO*****
CEREZO****
GIL*******
REY*******
TOVAR*****
ALONSO****
JIMENO****
FERNANDEZ*
MUNOZ*****
22
UD2. Llenguatge SQL DML SQL
14 rows selected.
23
UD2. Llenguatge SQL DML SQL
Funcions numèriques
Arrodoniments
Funció Descripció
Arrodoneix el número n al següent número amb
ROUND(n,decimals) el nombre de decimals indicat més proper.
Ex: ROUND(8.239, 2) 8.24
Retorna el numero n només amb el nombre de
TRUNC(n,decimals) decimals indicat.
Ex: ROUND(8.239, 2) 8.23
Obté l’enter immediatament més petit o igual que
FLOOR(n) n.
Ex: FLOOR(8.6) 8
Obté l’enter immediatament més gran o igual que
CEIL(n) n.
Ex: FLOOR(8.6) 9
Matemàtiques
Funció Descripció
Retorna el residu de dividir m entre n.
MOD(m,n)
Ex: MOD(7, 5) 2
Retorna el numero m elevat a la potència n.
POWER(m,n)
Ex: POWER(2,3) 8
Obté l’arrel quadrada de n.
SQRT(n)
Ex: SQRT(2) 1.41421356
Retorna -1 si n és negatiu; 0 si n és 0 i 1 si n és positiu.
Ex: SIGN(-2.3) -1
SIGN(n)
SIGN(0) 0
SIGN(2.3) 1
Calcula el valor absolut de n.
ABS(n)
Ex: ABS(-2.3) 2.3
Calcula en, és a dir, l’exponent amb base e del número n.
EXP(n)
Ex: EXP(2) 7.3890561
Calcula el logaritme naperià de n.
LN(n)
Ex: LN(2) 0.693147181
Calcula el logaritme amb base m de n.
LOG(m,n)
Ex: LOG(10,100) 2
Calcula el sinus de n (n ha d’estar amb radiants)
SIN(n)
Ex: SIN(0) 0
Calcula el cosinus de n (n ha d’estar amb radiants)
COS(n)
Ex: COS(0) 1
Calcula la tangent de n (n ha d’estar amb radiants)
TAN(n)
Ex: TAN(0) 0
Altres
Funció Descripció
Mida en bytes que usa Oracle per emmagatzemar el
VSIZE(valor) valor.
Ex: VSIZE(200000) 2
24
UD2. Llenguatge SQL DML SQL
Permeten definir els valors a utilitzar en el cas que les expressions agafin el valor NULL.
Funció Descripció
Si el valor és NULL, retorna el valor
substitut; altrament retorna valor.
NVL(valor,substitut)
Ex: NVL(234, 5) 234
NVL(NULL, 6) 6
Si el valor NO és NULL retorna el valor
NVL2(valor,substitut1, substitut1; altrament retorna substitut2.
substitut2) Ex: NVL2( 234, 5, 6 ) 5
NVL2( NULL, 5, 6 ) 6
Retorna NULL si valor1 = valor2;
NULLIF(valor1,valor2) altrament retorna valor1
Ex: NULLIF(2,2) NULL
Retorna valor1 si aquest NO és NULL; si
ho és retorna el valor2, si aquest NO és
NULL. Si són NULL el valor1 i el valor2,
COALESCE(valor1,
valor2, retorna el valor3 si aquest NO és NULL, i
[,valor3...]) així successivament.
Si tots els valors indicats són NULL retorna
un error.
Ex: COELESCE(NULL,2,3) 2
Les dates s’utilitzen molt en totes les bases de dades. Oracle proporciona dos tipus de
dades per gestionar dades, els tipus DATE i TIMESTAMP. En el primer cas
s’emmagatzema una data concreta (que fins i tot pot contenir l’hora), en el segon cas
s’emmagatzema un instant de temps concret que pot tenir fins i tot fraccions de segon.
Cal tenir en compte que als valors de tipus data se’ls hi pot sumar números i s’entendria
que aquesta suma és de dies. En general es pot operar amb números (sumes, restes,
multiplicacions i divisions). Si té decimals llavors se sumen dies, hores, minuts i segons.
25
UD2. Llenguatge SQL DML SQL
Calcular dates
Funció Descripció
ADD_MONTHS(data, n) Afegeix n mesos a la data actual.
MONTHS_BETWEEN(data1,data2) Obté la diferència en mesos de les
dues dates.
NEXT_DAY(data, dia) Indica quin és el dia resultant
d’afegir a la data el dia indicat. El
dia pot ser el text ‘Dilluns’,
‘Dimarts’, ‘Dimecres’, ... (si la
configuració està en català) o el
número de dia de la setmana
(1=dilluns, 2=dimarts,...)
LAST_DAY(data) Obté l’últim dia del mes al que
pertany la data. Retorna un valor
DATE.
EXTRACT(valor FROM [DATE] Extreu un valor d’una data. El valor
data) pot ser day (dia), month (mes),
year (any), etc. La data s’ha
d’indicar com a yyyy-mm-dd.
La paraula DATE només cal posar-
la quan el valor de la data és un
valor constant.
GREATEST(data1, data2,...) Retorna la data més moderna de la
llista.
LEAST(data1, data2,...) Retorna la data més vella de la
llista.
ROUND(data [,‘format’]) Arrodoneix la data al valor d’aplicar
el format a la data. El format pot
ser:
‘YEAR’. Fa que la data
mostri l’any sencer.
‘MONTH’. Fa que la
data mostri el més
sencer més proper a la
data (tenint en compte
les quinzenes)
‘HH24’. Arrodoneix
l’hora a les 00:00 més
properes.
‘DAY’. Arrodoneix al
primer dia de la setmana
més proper.
TRUNC(data [,‘format’]) Igual que l’anterior però trunca la
data en comptes de fer un
arrodoniment.
26
UD2. Llenguatge SQL DML SQL
27
UD2. Llenguatge SQL DML SQL
ADD_MONT
--------
11/05/06
Exemple: Obtenir els mesos que han passat des de l’11/11/1785 a l’11/11/2005.
SQL> SELECT MONTHS_BETWEEN('11/11/2005','11/11/1785')
2 FROM dual;
MONTHS_BETWEEN('11/11/2005','11/11/1785')
-----------------------------------------
2640
NEXT_DAY
--------
21/12/05
/* Versió 2 */
NEXT_DAY
--------
21/12/05
Exemple: Obtenir l’últim dia del mateix mes que la data 14/12/2005.
SQL> SELECT LAST_DAY('14/12/2005')
2 FROM dual;
LAST_DAY
--------
31/12/05
EXTRACT(DAYFROMDATE'2005-12-14')
--------------------------------
14
EXTRACT(MONTHFROMDATE'2005-12-14')
----------------------------------
12
28
UD2. Llenguatge SQL DML SQL
EXTRACT(YEARFROMDATE'2005-12-14')
---------------------------------
2005
GREATEST('
----------
14/12/2005
LEAST('11/
----------
11/11/2005
ROUND(TO
--------
01/01/06
ROUND(TO
--------
01/12/05
29
UD2. Llenguatge SQL DML SQL
ROUND(TO
--------
12/12/05
TRUNC(TO
--------
01/01/05
TRUNC(TO
--------
01/12/05
TRUNC(TO
--------
12/12/05
Funcions de conversió
Oracle és capaç de convertir dades automàticament per tal que l’expressió final tingui
significat. En aquest sentit són fàcils les conversions de text a número i viceversa.
Exemple:
SQL> SELECT 5 + '3'
2 FROM dual;
5+'3'
----------
8
SQL> SELECT 5 || '3'
2 FROM dual;
5|
--
53
També succeeix això amb la conversió de text a data. De fet és la forma habitual
d’assignar dates.
Però de vegades voldrem realitzar conversions explícites.
TO_CHAR
TO_CHAR(valor [, format])
30
UD2. Llenguatge SQL DML SQL
Obté un text a partir d’un número o una data. S’utilitza especialment amb dates (ja que
de número a text se sol utilitzar de forma implícita).
Dates
En el cas de les dates s’indica el format de conversió, que és una cadena que pot
incloure aquests símbols (en una cadena de text):
Símbol Significat
YY Any en format de dues xifres.
YYYY Any en format de quatre xifres.
MM Mes en format de dues xifres.
MON Les tres primeres lletres del mes.
MONTH Nom complert del mes.
DY Dia de la setmana amb tres lletres.
DAY Dia complet de la setmana.
DD Dia en format de dues xifres.
Q Semestre.
WW Setmana de l’any.
D Dia de la setmana (de l’1 al 7).
DDD Dia de l’any.
AM Indicador AM.
PM Indicador PM.
HH12 Hora de 1 al 12.
HH24 Hora de 0 a 24.
MI Minuts (de 0 a 59).
SS Segons (de 0 a 59).
SSSS Segons des de mitjanit.
/., Posició dels separadors.
Exemple:
SQL> SELECT TO_CHAR(SYSDATE, 'DD MONTH YYYY, DAY HH24:MI:SS')
2 FROM dual;
TO_CHAR(SYSDATE,'DDMONTHYYYY,DAYHH24
------------------------------------
10 DESEMBRE 2005, DISSABTE 14:57:06
Números
Per convertir números a text s’utilitza aquesta funció quan es volen unes característiques
especials. En aquest cas en el format es poden utilitzar aquests símbols:
31
UD2. Llenguatge SQL DML SQL
Símbol Significat
9 Posició del número.
0 Posició del número (mostra zeros).
$ Format dòlar.
L Símbol local de moneda.
. Posició del decimal.
, Posició del separador de milers.
Exemple:
SQL> SELECT TO_CHAR(346545.4, '000,000.00L')
2 FROM dual;
TO_CHAR(346545.4,'000
---------------------
346,545.40€
TO_NUMBER
TO_NUMBER(valor [, format])
Converteix text a números. Es pot indicar el format de la conversió utilitzant els mateixos
símbols que els comentats anteriorment.
TO_DATE
TO_DATE(valor [, format])
Converteix text a data. Es pot indicar el format de la conversió utilitzant els mateixos
símbols vistos anteriorment.
Exemple:
SQL> SELECT TO_DATE('14/12/2005', 'DD/MM/YY') AS DATA
2 FROM dual;
DATA
--------------------
14/12/05
Funcions condicionals
CASE
És una instrucció incorporada a la versió 9 d’Oracle que permet establir condicions de
sortida (a l’estil si-llavors-altrament del pseudocodi).
32
UD2. Llenguatge SQL DML SQL
Sintaxi
CASE expressió WHEN valor1 THEN resultat1
[ WHEN valor2 THEN resultat2 ....
...
ELSE resultatElse
]
END
El funcionament és el següent:
S’avalua l’expressió indicada.
Es comprova si aquesta expressió és igual al valor del primer WHEN. Si és així,
retorna el primer resultat (qualsevol valor menys Nul).
Si l’expressió no és igual al valor 1, llavors es comprova si és igual que el
segon. Si és així s’escriu el resultat 3. Si no és així continua amb el següent
WHEN.
El resultat indicat a la zona ELSE només s’escriu si l’expressió no val cap valor
dels indicats.
Exemple: Seleccionar el número, nom, ofici, codi departament i salari dels empleats que
tenen com ofici EMPLEAT.
SQL> select empl_num, empl_nom, empl_ofici, empl_dept_num, empl_salari
2 from empl
3 where empl_ofici='EMPLEAT';
4 rows selected.
Exemple: Seleccionar el número, nom, ofici, codi departament i salari dels empleats que
tenen com ofici EMPLEAT i augmentar amb 10000 el salari si pertanyen al departament
10, disminuir amb 10000 si pertanyen al departament 20 i no fer res en els altres casos.
SQL> SELECT empl_num, empl_nom, empl_ofici,
2 CASE empl_dept_num
3 WHEN 10 THEN empl_salari + 10000
4 WHEN 20 THEN empl_salari - 10000
5 ELSE empl_salari
6 END AS "Increment salari", empl_salari
7 FROM empl
8 WHERE empl_ofici='EMPLEAT';
33
UD2. Llenguatge SQL DML SQL
[,valorPerDefecte]
)
Exemple:
SQL> SELECT empl_num, empl_nom, empl_ofici,
2 DECODE(empl_dept_num, 10, empl_salari + 10000,
3 20, empl_salari - 10000,
4 empl_salari) AS "Increment salari",
5 empl_salari
6 FROM empl
7 WHERE empl_ofici='EMPLEAT';
4 rows selected.
2.1.7. Agrupacions
És molt habitual crear consultes en les que es vol agrupar les dades per tal de realitzar
càlculs en vertical, és a dir, calculats a partir de dades de diferents registres.
Per poder fer aquestes agrupacions s’utilitza la clàusula GROUP BY que permet indicar
en base a quins registres es fa l’agrupació.
Amb GROUP BY la sintaxi de la instrucció SELECT queda d’aquesta forma:
SELECT llistaExpressions
FROM llistaTaules
[WHERE condicionsSeleccio_I_CondicionsCombinació]
[GROUP BY llistaCampsPerAgrupar]
[HAVING condicionsSeleccioDeGrups]
[ORDER BY llistaCampsOrdenació];
A la clàusula GROUP BY, s’indiquen les columnes per les que s’agrupa. La funció
d’aquest apartat és crear un únic registre per cada valor diferent en les columnes del
grup.
Si per exemple agrupem en base a les columnes plantilla_hospital_codi i
plantilla_sala_codi de la taula plantilla, es crearà un únic registre per cada hospital i sala
diferents:
SQL> select plantilla_hospital_codi, plantilla_sala_codi
2 from plantilla
3 group by plantilla_hospital_codi, plantilla_sala_codi;
34
UD2. Llenguatge SQL DML SQL
10 rows selected.
7 rows selected.
35
UD2. Llenguatge SQL DML SQL
EMPL_OFICI SUM(EMPL_SALARI)
---------- ----------------
ANALISTA 780000
DIRECTOR 1075750
EMPLEAT 539500
PRESIDENT 650000
VENEDOR 747500
Com es pot veure, en l’exemple se sumen les quantitats per cada grup.
HAVING
De vegades es vol restringir el resultat d’una expressió agrupada, com per exemple:
SQL> SELECT empl_ofici, SUM(empl_salari)
2 FROM empl
3 WHERE SUM(empl_salari)>700000
4 GROUP BY empl_ofici;
36
UD2. Llenguatge SQL DML SQL
La raó d’aquest error és perquè Oracle sempre executa primer el WHERE i llavors els
grups; i per tant aquesta condició del WHERE no la pot fer pel fet de que encara no hi ha
els grups fets.
Per això s’executa la clàusula HAVING, que s’executa després de fer els grups.
S’utilitzaria d’aquesta forma:
SQL> SELECT empl_ofici, SUM(empl_salari)
2 FROM empl
3 GROUP BY empl_ofici
4 HAVING SUM(empl_salari)>700000;
EMPL_OFICI SUM(EMPL_SALARI)
---------- ----------------
ANALISTA 780000
DIRECTOR 1075750
VENEDOR 747500
Això no significa que no puguem utilitzar la clàusula WHERE quan fem agrupacions. Per
exemple, aquesta consulta si que seria vàlida:
SQL> SELECT empl_ofici, SUM(empl_salari)
2 FROM empl
3 WHERE UPPER(EMPL_OFICI)<>'DIRECTOR'
4 GROUP BY empl_ofici
5 HAVING SUM(empl_salari)>700000;
EMPL_OFICI SUM(EMPL_SALARI)
---------- ----------------
ANALISTA 780000
VENEDOR 747500
En definitiva, l’ordre d’execució de la consulta marca el que es pot utilitzar amb el WHERE
i el que es pot utilitzar amb HAVING.
Passes en l’execució d’una instrucció d’agrupació per part del gestor de bases de dades:
Seleccionar les files desitjades utilitzant WHERE. Aquesta clàusula eliminarà
files en base a la condició indicada.
S’estableixen els grups indicats en la clàusula GROUP BY.
Es calculen els valors de les funcions de totals (COUNT, SUM, AVG,...)
Es filtren els grups que compleixen la clàusula HAVING.
El resultat s’ordena en base a l’apartat ORDER BY.
2.2.1. Introducció
És molt normal que en una consulta es necessitin dades que es troben distribuïes en
diferents taules. Les bases de dades relacionals es basen, com hem vist, en que les
dades es distribueixen en relacions que es poden relacionar mitjançant un atribut. Aquest
atribut és el que permet combinar les dades de les relacions.
37
UD2. Llenguatge SQL DML SQL
Per exemple, si tenim una relació de departaments amb clau primària dept_codi i una
altra relació d’empleats que es refereix als empleats que treballen a cada departament,
segur que (si el disseny està ben fet) a la relació d’empleats hi haurà el DNI de l’empleat
(empl_dni) per saber a quin departament pertany l’empleat.
Si per exemple, es vol obtenir una llista de les dades dels departaments i dels empleats,
es podria fer de la següent forma:
SELECT dept_codi, dept_nom, dept_loc, empl_dni, empl_nom, …
FROM dept, empl ;
La sintaxi és correcta ja que es pot indicar més d’una taula a l’apartat de la clàusula
FROM. Però això produeix un producte cartesià (mateix significat que l’operador de
producte cartesià de l’àlgebra relacional) i apareixeran tots els registres dels empleats
relacionats amb tots els registres de departament.
d1 e1
e1
d2 e2
e3
d3 e4
e5
DEPT EMPL
38
UD2. Llenguatge SQL DML SQL
Exemple:
SQL> SELECT dept_num,dept_nom,empl_num,empl_nom
2 FROM dept, empl;
56 rows selected.
39
UD2. Llenguatge SQL DML SQL
Com es pot observar a l’exemple anterior, el producte cartesià entre dues taules no té
molta utilitat. Cal discriminar el producte per tal que només ens doni com a resultat els
departaments relacionats amb els seus empleats. A aquesta discriminació se l’anomena
combinació (join) de taules.
En general nosaltres tindrem diferents opcions per treballar amb múltiples taules:
Combinacions de taules (joins).
Subconsultes (subqueries).
Combinacions especials.
Combinacions d’igualtat
Sintaxi:
SELECT <columnes de les taules de la clàusula from>
FROM taula1 [alies1],taula2 [alies2],..., taulaN [aliesN]
WHERE [{taula1|alies1}.]columna = [{taula2|alies2}.]columna
[ AND [{taulaX|aliesX}].columna =
[{taulaY|aliesY}].columna ...]
Exemple:
SQL> SELECT dept_num, dept_nom, empl_num, empl_nom
2 FROM empl, dept
3 WHERE dept_num = empl_dept_num;
14 rows selected.
40
UD2. Llenguatge SQL DML SQL
DOCTOR_NOM
----------------
Cajal R.
PLANTILLA_NOM HOSPITAL
---------------- --------
Rivera G. 923-5411
Carlos R. 923-5411
Combinacions de no igualtat
Són aquelles combinacions on la condició de combinació no conté l’operador d’igualtat.
Exemple 1: obtenir els treballadors de la plantilla que no treballen a l’hospital ‘La Paz’.
SQL> select plantilla_nom
2 from plantilla, hospital
3 where plantilla_hospital_codi <> hospital_codi and
4 hospital_nom = 'La Paz';
PLANTILLA_NOM
----------------
Diaz B.
Hernandez J.
Karplus W.
Amigo R.
Frank H.
41
UD2. Llenguatge SQL DML SQL
Amb aquesta sintaxi s’obtenen els registres relacionats entre les taules i a més a més els
registres no relacionats de la taula2.
Exemple:
SQL> SELECT dept_num, dept_nom, empl_nom
2 FROM dept, empl
3 WHERE empl_dept_num(+) = dept_num
4 ORDER BY dept_num;
En aquest cas surten els relacionats i els de la segona taula que no estan relacionats
amb cap de la primera.
Exemple:
SQL> SELECT dept_num, dept_nom, empl_nom
2 FROM dept, empl
3 WHERE empl_dept_num = dept_num(+)
4 ORDER BY dept_num;
42
UD2. Llenguatge SQL DML SQL
14 rows selected.
Una auto combinació s’utilitza quan ens trobem davant una relació reflexiva (relació
d’una columna d’una taula amb una columna de la mateixa taula).
Exemple: Obtenir el codi i nom d’empleat, juntament amb el codi i nom del seu director.
SQL> SELECT e.empl_num, e.empl_nom,
2 d.empl_num "Codi Director", d.empl_nom "Nom director"
3 FROM empl e, empl d
4 WHERE e.empl_dir = d.empl_num;
12 rows selected.
En la versió SQL 1999 es va crear una nova sintaxi per consultar varies taules. La raó va
ser la de separar les condicions de combinació de les condicions de selecció de
registres.
SINTAXI:
SELECT taula1.columna1, taula1.columna2,...
taula2.columna1, taula2.columna2,...
FROM taula1
[CROSS JOIN taula2] |
43
UD2. Llenguatge SQL DML SQL
(taula1.columa=taula2.columna)] ;
CROSS JOIN
S’utilitza per fer un producte cartesià entre les taules.
Exemple :
SELECT empl_nom, dept_num
FROM empl CROSS JOIN dept;
És equivalent a:
SELECT empl_nom, detp_num
FROM dept, empl ;
NATURAL JOIN
Estableix una relació d’igualtat entre les dades de les taules a partir de les columnes que
tinguin el mateix nom en les dues taules.
Si no hi ha columnes que tinguin el mateix nom en les dues taules, es produirà un
producte cartesià.
Si les columnes que tenen el mateix nom tenen tipus de dades diferents, dóna un error.
Exemple 1: Suposem que tenim les taules:
EMPL(empl_num, empl_nom, dept_num)
DEPT(dept_num, dept_nom)
EMPL_NOM DEPT_NOM
---------------- --------------
SANCHEZ Investigacio
ARROYO Vendes
SALA Vendes
JIMENEZ Investigacio
MARTIN Vendes
NEGRO Vendes
CEREZO Comptabilitat
GIL Investigacio
REY Comptabilitat
TOVAR Vendes
ALONSO Investigacio
JIMENO Vendes
FERNANDEZ Investigacio
MUNOZ Comptabilitat
14 rows selected.
És equivalent a:
SQL> SELECT empl_nom, dept_nom
FROM empl e, dept d
WHERE e.dept_num = d.dept_num;
Exemple 2: Es vol fer la mateixa consulta que a l’exemple 1, però ara que només mostri
els empleats dels departaments de vendes i de comptabilitat.
44
UD2. Llenguatge SQL DML SQL
És equivalent a:
SQL> SELECT empl_nom, dept_nom
FROM empl e, dept d
WHERE e.dept_num = d.dept_num
AND dept_nom IN (‘Vendes’, ‘Comptabilitat’);
JOIN USING
Permet establir relacions indicant quina columna (o columnes) comuns a les dues taules
cal utilitzar per fer la combinació.
Exemple: Suposem que tenim les taules:
EMPL(empl_num, empl_nom, dept_num) i DEPT(dept_num, dept_nom)
EMPL_NOM DEPT_NOM
---------------- --------------
SANCHEZ Investigacio
ARROYO Vendes
SALA Vendes
JIMENEZ Investigacio
MARTIN Vendes
NEGRO Vendes
CEREZO Comptabilitat
GIL Investigacio
REY Comptabilitat
TOVAR Vendes
ALONSO Investigacio
JIMENO Vendes
FERNANDEZ Investigacio
MUNOZ Comptabilitat
14 rows selected.
És equivalent a:
SQL> SELECT empl_nom, dept_nom
FROM empl e, dept d
WHERE e.dept_num = d.dept_num;
JOIN ON
45
UD2. Llenguatge SQL DML SQL
EMPL_NOM DEPT_NOM
---------------- --------------
SANCHEZ Investigacio
ARROYO Vendes
SALA Vendes
JIMENEZ Investigacio
MARTIN Vendes
NEGRO Vendes
CEREZO Comptabilitat
GIL Investigacio
REY Comptabilitat
TOVAR Vendes
ALONSO Investigacio
JIMENO Vendes
FERNANDEZ Investigacio
MUNOZ Comptabilitat
14 rows selected.
És equivalent a:
SQL> SELECT empl_nom, dept_nom
FROM empl e, dept d
WHERE empl_dept_num = dept_num;
PLANTILLA_NOM HOSPITAL
---------------- --------
Rivera G. 923-5411
Carlos R. 923-5411
Combinacions externes
La última possibilitat és obtenir combinacions externes (outer joins). Per fer-ho utilitzarem
la següent sintaxi:
SQL> SELECT empl_nom, dept_nom
2 FROM empl RIGHT OUTER JOIN dept ON empl_dept_num = dept_num;
EMPL_NOM DEPT_NOM
---------------- --------------
SANCHEZ Investigacio
46
UD2. Llenguatge SQL DML SQL
ARROYO Vendes
SALA Vendes
JIMENEZ Investigacio
MARTIN Vendes
NEGRO Vendes
CEREZO Comptabilitat
GIL Investigacio
REY Comptabilitat
TOVAR Vendes
ALONSO Investigacio
JIMENO Vendes
FERNANDEZ Investigacio
MUNOZ Comptabilitat
Produccio
15 rows selected.
És equivalent a:
SQL> SELECT empl_nom, dept_nom
2 FROM empl, dept
3 WHERE empl_dept_num (+) = dept_num;
2.2.5. Subconsultes
Fins ara hem utilitzat la clàusula WHERE per definir els subconjunts de dades que
desitgem.
A més a més, hem utilitzat SQL per relacionar un valor d’una columna amb una constant
o un grup de constants.
S’utilitzen les subconsultes quan es desconeixen els valors de les constants.
47
UD2. Llenguatge SQL DML SQL
Sintaxi:
SELECT llistaExpressions
FROM taula
WHERE expressió operador
(SELECT llistaExpressions
FROM taula);
Es pot col·locar el SELECT dins de les clàusules WHERE, HAVING o FROM. L’operador
pot ser >, <, >=, <=, <>, =, IN, ANY, ALL.
Exemple:
Per obtenir el salari mig de la plantilla d’empleats:
SQL> SELECT AVG(plantilla_salari)
2 FROM plantilla;
AVG(PLANTILLA_SALARI)
---------------------
230210
Per obtenir el nom dels empleats que tenen un salari superior a la mitja, hauríem
d’anotar el valor anterior a un paper i després fer:
SQL> SELECT plantilla_nom
2 FROM plantilla
3 WHERE plantilla_salari > 230210;
PLANTILLA_NOM
----------------
Hernandez J.
Karplus W.
Frank H.
48
UD2. Llenguatge SQL DML SQL
PLANTILLA_NOM
----------------
Hernandez J.
Karplus W.
Frank H.
Exemple: Retornar la informació sobre els empleats que guanyen més que qualsevol
empleat del departament 30.
SELECT *
FROM empl
WHERE empl_salari > (SELECT MAX(empl_salari)
FROM empl
WHERE empl_dept_num = 30);
49
UD2. Llenguatge SQL DML SQL
Exemple: Retornar la informació sobre els empleats que tenen el mateix treball que
l’empleat SALA i guanyen més que l’empleat MARTIN.
SQL> SELECT empl_nom, empl_ofici, empl_salari
2 FROM empl
3 WHERE empl_ofici =
4 (SELECT empl_ofici
5 FROM empl
6 WHERE empl_nom = 'SALA')
7 AND empl_salari >
8 (SELECT empl_salari
9 FROM empl
10 WHERE empl_nom = 'MARTIN');
El motiu de l’error és el d’utilitzar un operador d’una sola fila amb una subconsulta de
varies files.
no rows selected
No hi ha cap empleat que es digui PERE, per tant, la subconsulta no torna cap fila. La
consulta externa agafa els resultants de la subconsulta (valor nul) i els utilitza dins la
seva clàusula WHERE. La consulta externa no troba cap empleat amb ofici igual a NUL i
no torna cap fila. Si hi hagués ofici amb valor NUL, tampoc es tornaria la fila com a
resultat, ja que la comparació de dos valors nuls dóna un altre valor nul (ni cert ni fals),
per tant la condició WHERE no és certa.
50
UD2. Llenguatge SQL DML SQL
Exemple: Retornar tots els treballadors de la plantilla de l’hospital que no són Infermera i
que el seu salari sigui inferior al de qualsevol Infermera.
SQL> SELECT plantilla_nom, plantilla_funcio, plantilla_salari
2 FROM plantilla
3 WHERE plantilla_salari < ANY
4 (SELECT plantilla_salari
5 FROM plantilla
6 WHERE plantilla_funcio = 'Infermera')
7 AND plantilla_funcio <> 'Infermera';
PLANTILLA_SALARI
PLANTILLA_NOM PLANTILLA_ PLANTILLA_SALARI ----------------
---------------- ---------- ---------------- 226200
Bocina G. Infermer 183800 200500
Amigo R. Intern 221000 162600
Nunez C. Intern 221000 221900
252200
< ANY significa menys que el valor màxim de la subconsulta
> ANY significa més que el valor mínim de la subconsulta
= ANY és equivalent a IN.
Exemple: Obtenir el nom i el salari dels empleats que tenen el salari igual a algun dels
empleats del departament 20.
SQL> SELECT empl_nom, empl_salari
2 FROM empl
3 WHERE empl_salari = ANY (SELECT empl_salari
4 FROM empl
5 WHERE empl_dept_num = 20);
EMPL_NOM EMPL_SALARI
---------------- -----------
SANCHEZ 104000
ALONSO 143000
JIMENEZ 386750
GIL 390000
FERNANDEZ 390000
Exemple: Retornar tots els treballadors de la plantilla de l’hospital que no són Infermera i
que el seu salari sigui inferior al de qualsevol Infermera.
SQL> SELECT plantilla_nom, plantilla_funcio, plantilla_salari
2 FROM plantilla
3 WHERE plantilla_salari < ALL
4 (SELECT plantilla_salari
5 FROM plantilla
6 WHERE plantilla_funcio = 'Infermer')
7 AND plantilla_funcio <> 'Infermer'
PLANTILLA_SALARI
PLANTILLA_NOM PLANTILLA_ PLANTILLA_SALARI ----------------
---------------- ---------- ---------------- 275000
Rivera G. Infermera 162600 183800
51
UD2. Llenguatge SQL DML SQL
EMPL_NOM EMPL_SALARI
---------------- -----------
REY 650000
52
UD2. Llenguatge SQL DML SQL
Exemple: Obtenir els empleats amb el mateix ofici i salari que JIMENEZ
SELECT empl_nom
FROM empl
WHERE (empl_ofici, empl_salari)=
(SELECT empl_ofici, empl_salari
FROM empl
WHERE UPPER(empl_nom) = 'JIMENEZ');
Unió
Aquest operador equival a l’operació UNIÓ de l’àlgebra relacional.
La clàusula UNION permet afegir el resultat d’un SELECT a un altre SELECT. Per poder-
ho fer, les dues instruccions han d’utilitzar el mateix número i tipus de columnes.
SQL> SELECT empl_nom
2 FROM empl
3 UNION
4 SELECT plantilla_nom
5 FROM plantilla;
EMPL_NOM
----------------
ALONSO
ARROYO
Amigo R.
Bocina G.
CEREZO
Carlos R.
Diaz B.
FERNANDEZ
Frank H.
GIL
Hernandez J.
Higueras D.
JIMENEZ
JIMENO
Karplus W.
53
UD2. Llenguatge SQL DML SQL
MARTIN
MUNOZ
NEGRO
Nunez C.
REY
Rivera G.
SALA
SANCHEZ
TOVAR
24 rows selected.
El resultat és una taula que tindrà els noms dels empleats i empleats de plantilla.
És a dir, UNION crea una sola taula (temporal) amb les files de les dues consultes. Si hi
ha files repetides, només apareixeran una vegada. Per mostrar duplicats s’utilitza UNION
ALL enlloc de UNION.
Per defecte, s’ordena el resultat per la primera columna seleccionada.
Intersecció
De la mateixa forma, la paraula INTERSECT permet fer la intersecció dues consultes
SELECT de manera que el resultat seran les files que estiguin a les dues consultes.
Aquest operador equival a l’operació INTERSECCIÓ de l’àlgebra relacional.
Diferència
Amb MINUS es fa la diferència de dues consultes SELECT de manera que apareixeran
els registres del primer SELECT que no estiguin en el segon.
Aquest operador equival a l’operació DIFERÈNCIA de l’àlgebra relacional.
Exemple:
SQL> SELECT empl_nom
2 FROM empl
3 MINUS
4 SELECT plantilla_nom
5 FROM plantilla;
EMPL_NOM
----------------
ALONSO
ARROYO
CEREZO
FERNANDEZ
GIL
JIMENEZ
JIMENO
MARTIN
MUNOZ
NEGRO
REY
SALA
SANCHEZ
TOVAR
14 rows selected.
Es poden utilitzar aquests operadors de forma niuada (una unió on el resultat es utilitzat
amb la diferència amb un altre SELECT, per exemple). En aquest cas cal posar
parèntesis per indicar quina operació es fa primer:
(SELECT....
54
UD2. Llenguatge SQL DML SQL
....
UNION
SELECT....
...
)
MINUS
SELECT.... /* Primer es fa la unió i després la diferència */
2.3.1. Introducció
Dins del llenguatge de manipulació de dades SQL (DML SQL) també hi trobem les
instruccions per poder manipular les dades que contenen les taules de la base de dades.
En totes aquestes consultes, normalment l’única dada retornada pel SGBDR (en el
nostre cas Oracle) és el nombre de registres que s’han modificat.
Per poder afegir dades a una taula es fa mitjançant la instrucció INSERT. La seva
sintaxi bàsica és:
INSERT INTO taula [(llistaDeCamps)]
VALUES (valor1, [valor2, valor3, ...)];
On:
taula indica la taula on volem inserir el nou registre de dades.
llistaDeCamps és una dada opcional i serveix per indicar en quins camps volem
inserir noves dades.
Després de la paraula clau VALUES s’indiquen els valors dels camps del nou registre
que volem afegir a la taula.
La llistaDeCamps no és obligatori indicar-la. En aquest cas hem d’indicar la llista de
valors de tots els camps de la taula i en el mateix ordre que apareixen en la definició de
la taula.
Si indiquem la llistaDeCamps llavors permet indicar només els valors d’uns quants
camps de la taula. Els valors que no indiquem s’omplen amb el seu valors per defecte
(DEFAULT en la definició dels camps de la taula) o bé amb NULL. Si hi ha algun camp
que té una restricció NOT NULL, es produirà un error si no indiquem cap valor per aquell
camp.
Exemple: Volem inserir un nou departament a la taula DEPT. Observem abans quina és
la definició de la taula:
SQL> desc dept
Name Null? Type
----------------------------------------- -------- -------------------------
DEPT_NUM NOT NULL NUMBER(2)
DEPT_NOM VARCHAR2(14)
DEPT_LOC VARCHAR2(13)
Si només volem inserir les dades del NUM i el NOM del departament ho podem fer així:
SQL> INSERT INTO dept(dept_num,dept_nom)
2 VALUES (50,'Informatica');
55
UD2. Llenguatge SQL DML SQL
1 row created.
SQL> SELECT *
2 FROM dept;
Es pot veure com en la columna DEPT_LOC del nou departament hi ha com a valor
NULL, ja que no s’ha indicat aquest valor en la instrucció INSERT i a més a més no hi
havia cap restricció sobre la columna DEPT_LOC que indiqués que no es puguin inserir
valors NULL en aquesta columna.
56
UD2. Llenguatge SQL DML SQL
Exemple: Si volem inserir totes les dades d’un nou departament ho podem fer així:
SQL> INSERT INTO dept
2 VALUES (50,'Informatica','Olot');
Exemple: Si no indiquem les dades d’alguna de les columnes que tenen alguna restricció
d’integritat, donaria un error semblant a aquest:
SQL> INSERT INTO dept(dept_nom,dept_loc)
2 VALUES ('Informatica','Olot');
INSERT INTO dept(dept_nom,dept_loc)
*
ERROR at line 1:
ORA-01400: no es pot inserir NULL a ("MNICOLAU"."DEPT"."DEPT_NUM")
Errors d’inserció
Els errors més habituals que es poden produir quan s’insereixen o es modifiquen dades
són els següents:
Falta un valor obligatori per una columna NOT NULL.
Un valor duplicat viola la restricció d’unicitat.
Es viola una restricció de clau forana.
Es viola una restricció CHECK.
El tipus de dades no coincideix.
El valor és massa gran per la columna.
Inserció de valors especials
Quan es fa la inserció d’una nova fila a una taula es poden utilitzar funcions (les
mateixes que hem vist quan estudiàvem les consultes de selecció).
Per exemple:
INSERT INTO empl (empl_num, empl_nom, empl_ofici, empl_dir,
empl_datalt, empl_salari, empl_comissio,
empl_dept_num)
VALUES (800, 'JORDI','ANALISTA',7258,
SYSDATE,200000,NULL,
10);
57
UD2. Llenguatge SQL DML SQL
Exemple: Suposem que hem creat una taula nova que contindrà les dades dels empleats
que són Analistes i que la volem omplir a partir d’una consulta feta a la taula EMPL.
En primer lloc és necessari que la nova taula estigui creada. Suposem que la taula que
creem és la següent:
CREATE TABLE empl_analistes
(
num NUMBER(4) PRIMARY KEY,
nom VARCHAR(16),
dept NUMBER(2),
foreign key(dept) references dept(dept_num)
)
La consulta que ompliria la taula amb tots els analistes de la taula EMPL seria:
INSERT INTO empl_analistes (num,nom,dept)
SELECT empl_num, empl_nom, empl_dept_num
FROM empl
WHERE UPPER(empl_ofici)='ANALISTA';
Podem modificar / actualitzar les dades dels registres d’una taula amb la instrucció
UPDATE.
Sintaxi:
UPDATE taula
SET columna1 = valor1 [,columna2 = valor2...]
[WHERE condició]
On:
taula indica la taula on volem fer alguna modificació de les dades dels seus
registres.
A partir de la paraula SET s’indiquen les assignacions de les noves dades per cada una
de les columnes on hem de canviar valors.
La condició WHERE és opcional i permet indicar quines seran les files que es veuran
afectades per l’actualització de dades.
Exemple: Actualitzar a Barna el camp dept_loc d’aquells departaments que estan ubicats
a Barcelona.
SQL> UPDATE dept
2 SET dept_loc='Barna'
3 WHERE UPPER(dept_loc)='BARCELONA';
Exemple: Actualitzar el salari i la comissió dels empleats que guanyen menys de 200000
amb un 10% més.
SQL> UPDATE empl
2 SET empl_salari=empl_salari*1.10, empl_comissio=empl_comissio*1.10
3 WHERE empl_salari<200000;
En el primer exemple s’assigna un nou valor utilitzant una constant de tipus cadena. En
el segon exemple, el nou valor que s’assigna s’obté a partir d’una operació de producte.
En general, el nou valor que assignem es pot obtenir de qualsevol forma per complexa
que sigui, fins i tot a partir de subconsultes.
Exemple: Assignar als empleats del departament 10 el mateix departament que l’empleat
Fernandez.
SQL> UPDATE empl
2 SET empl_dept_num=(
3 SELECT empl_dept_num
58
UD2. Llenguatge SQL DML SQL
4 FROM empl
5 WHERE UPPER(empl_nom)='FERNANDEZ'
6 )
7 WHERE empl_dept_num=10;
Aquest tipus d’actualitzacions només són vàlides si la subconsulta retorna un únic valor i
a més a més que sigui compatible amb el tipus de dades de la columna a actualitzar.
S’ha de tenir molt en compte que les actualitzacions no es poden saltar les regles
d’integritat que tinguin les taules.
59
UD2. Llenguatge SQL DML SQL
On:
FROM és opcional en algun SGBDR, com Oracle.
Cal tenir en compte que l’eliminació d’un registre no pot provocar error d’integritat i que la
opció d’integritat ON DELETE CASCADE (veure els apunts de DDL, on es parla de la
creació de claus foranes) fa que no només s’esborrin els registres que compleixen la
condició de la taula indicada, sinó tots els registres relacionats amb els que s’eliminen.
Si no s’especifica la condició del WHERE, s’eliminaran totes les files de la taula.
Exemple: Esborrar els empleats del departament 20 que guanyen menys que l’empleat
amb el millor sou del departament 30.
SQL> DELETE FROM empl
2 WHERE empl_dept_num = 20 and empl_salari<(
3 SELECT MAX(empl_salari)
4 FROM empl
5 WHERE empl_dept_num=30
);
60
UD2. Llenguatge SQL DML SQL
Es pot utilitzar la paraula DEFAULT dins una instrucció INSERT o UPDATE com a valor
d’una columna si es vol utilitzar el valor per defecte de la columna en la instrucció
d’inserció o modificació.
Aquesta opció és nova a partir de l’estàndard SQL:1999.
Permet que l’usuari controli on i quan s’ha d’aplicar el valor per defecte.
Exemple: utilització de DEFAULT en una inserció
INSERT INTO dept (dept_num, dept_nom, dept_loc)
VALUES (33,’Enginyeria’,DEFAULT);
61
UD2. Llenguatge SQL DDL SQL
3.1.1. Introducció
Per poder treballar amb BD relacionals, el primer que cal fer és definir-les. Veurem les
instruccions de l’estàndard SQL92 per crear i esborrar una base de dades relacional i per
inserir, esborrar i modificar les diferents taules que la composen.
En aquest apartat també veurem com es defineixen els dominis, les restriccions i les
vistes.
La senzillesa del SQL92 fa que:
Per crear bases de dades, taules, dominis, restriccions, índexs i vistes s’utilitza la
sentència CREATE.
Per modificar taules i dominis s’utilitzi la sentència ALTER.
Per esborrar bases de dades, taules, dominis, restriccions, índexs i vistes s’utilitza la
sentència DROP.
Cal tenir molta cura en utilitzar una sentència DDL, ja que aquestes no poden ser
anul·lades (a diferencia de les sentències d’actualització de dades).
62
UD2. Llenguatge SQL DDL SQL
On:
nom_esquema: nom que es vol que tingui l’esquema
AUTHORIZATION usuari: indicar l’usuari de l’esquema (l’esquema tindrà el nom de
l’usuari).
llista_elements_esquema: sentències de creació de taules, vistes, dominis, etc.
Exemple:
CREATE SCHEMA AUTHORIZATION ususari1
CREATE TABLE producte
(color VARCHAR(10) PRIMARY KEY, quantitat NUMBER)
CREATE VIEW producte_view AS
SELECT color, quantitat FROM producte WHERE color = 'vermell'
GRANT select ON producte_view TO usuari1;
On:
llista_elements_esquema: només poden ser sentències de creació de taules, vistes
i assignació de permisos.
3.1.3. Objectes de BD
La majoria dels SGBDR tenen varis objectes que es poden definir en una BD. Molts
d’ells estan definits en l’estàndard SQL, però altres no. Nosaltres estudiarem el cas
particular dels objectes que podem crear en BD Oracle, èmfasi amb la seva definició
segons l’estàndard ANSI SQL.
Una base de dades Oracle pot tenir varies estructures de dades, cadascuna de les quals
s’ha de descriure en el disseny de la base de dades de manera que es pugui crear
durant la fase de creació del desenvolupament de la BD.
Els tipus d’objectes que es poden crear amb Oracle són:
Objecte Descripció
Taula Unitat bàsica d’emmagatzematge formada per files i columnes.
Vista Representa lògicament subconjunts de dades d’una o més taules.
Seqüència Generador de valor numèric.
Índex Millora el rendiment d’algunes consultes.
Sinònim Noms alternatius a objectes.
63
UD2. Llenguatge SQL DDL SQL
On definicióColuma és:
nomColumna {tipusDades|domini} [DEFAULT expr]
On:
nomColumna: és el nom de la columna.
tipusDades: és la mida i tipus de dades de la columna
• domini: és el domini dels valors admesos per la columna (Oracle no té
dominis).
Amb Oracle, per executar aquesta sentència cal tenir privilegi CREATE TABLE.
64
UD2. Llenguatge SQL DDL SQL
Regles de nomenclatura
Els noms de les taules i columnes han de seguir les següents regles estàndard:
• Han de començar per una lletra.
• Només poden tenir els caràcters A-Z, a-z, 0-9, _ (subguió), $ i # (aquests
últims, no és recomanat utilitzar-los).
• Els noms no han de duplicar el nom d’un altre objecte del mateix esquema.
Recomanacions:
• Utilitzar noms descriptius per taules i altres objectes de la BD.
L’opció DEFAULT
Sintaxi:
DEFAULT (literal|expr|funció|NULL)
A una columna se li pot assignar un valor per defecte utilitzant l’opció DEFAULT. Aquesta
opció evita que s’introdueixin valors nuls a les columnes si s’insereix una fila sense un
valor per la columna. Si no s’especifica DEFAULT, llavors val NULL.
El valor per defecte pot ser un literal, una expressió o una funció SQL, com SYSDATE
(que dóna la data del sistema) i USER (que indica qui és l’usuari), però el valor no pot
ser el nom d’una altra columna o una pseudocolumna, com NEXTVAL o CURRVAL (que
s’explicaran més endavant). Si s’indica una expressió, el tipus d’aquesta ha de ser igual
al tipus de dades de la columna.
Exemple de creació de taula
CREATE TABLE departament
(
dept_num NUMBER(3)
dept_nom VARCHAR2(14),
dept_loc VARCHAR2(13)
);
Taules de la BD Oracle
Les taules d’usuari són les taules creades per l’usuari, com per exemple,
departament. Hi ha un altre conjunt de taules i vistes a la BD Oracle coneguda com el
diccionari de dades. Aquest conjunt de taules el crea i manté el servidor Oracle i conté
informació sobre la BD.
Totes les taules del diccionari de dades són propietat de l’usuari SYS. L’usuari no
accedeix gairebé mai a les taules de base, ja que la informació que contenen no és fàcil
65
UD2. Llenguatge SQL DDL SQL
d’entendre. Per tant, els usuaris normalment accedeixen a vistes del diccionari de dades,
on la informació es mostra amb un format més senzill d’entendre. La informació que es
guarda al diccionari de dades inclou noms dels usuaris, privilegis dels usuaris, noms
d’objectes de la BD, restriccions de taules i informació d’auditoria.
Hi ha quatre categories de vistes del diccionari de dades; cadascuna té un prefix diferent
que indica la seva utilitat:
Prefix Descripció
USER_ Vistes amb informació sobre els objectes propietat de l’usuari.
ALL_ Vistes amb informació sobre totes les taules accessibles per
l’usuari.
DBA_ Vistes restringides i només hi poden accedir persones amb el rol
DBA.
V$ Vistes de rendiment dinàmiques, rendiment del servidor de BD,
memòria i bloqueig.
• USER_OBJECTS
• USER_CATALOG
66
UD2. Llenguatge SQL DDL SQL
Tipus de dades
Per cada columna cal escollir entre algun domini definit per l’usuari o algun dels tipus de
dades predefinits següents:
Descripció ANSI SQL ORACLE SQL
Text de CHARACTER(n) CHAR(n)
longitud fixe CHAR(n) n: entre 1 (per defecte) i
2000
Text de CHARACTER VARYING(n) VARCHAR2(n)
longitud CHAR VARYING(n) n: entre 1 i 4000
variable
Text de NATIONAL CHARACTER(n) NCHAR(n)
longitud fixa NATIONAL CHAR(n)
per caràcters NCHAR(n)
nacionals
Text de NATIONAL CHARACTER NVARCHAR2(n)
longitud VARYING(n)
variable per NATIONAL CHAR VARYING(n)
NCHAR VARYING(n)
caràcters
nacionals
Text gran LOB LONG (fins a 2GB) i CLOB (fins a
4GB)
Cadena de BIT(n) RAW(n) (fins a 2000B)
bits de LONG RAW (fins a 2GB)
longitud fixe BLOB (fins a 4GB)
BFILE (a un fitxer extern; fins a
4GB)
Cadena de BIT VARYING(n) RAW(n) (fins a 2000B)
bits de LONG RAW (fins a 2GB)
longitud BLOB (fins a 4GB)
variable BFILE (a un fitxer extern;
fins a 4GB)
Números de NUMERIC(p,s) p: precisió (total de dígits).
longitud variable DECIMAL(p,s) De 1 a 38
NUMBER(p,s) s: escala (dígits a la dreta
de la coma decimal). De -
84 a 127
Números enters INTEGER
INT
SMALLINT
Números de FLOAT(p)
coma flotant DOUBLE PRECISION
REAL
Data i hora DATE DATE
YEAR (0001..9999) Valors de data i hora entre
MOTNH (01..12) 4712 a.C i el 31-12-9999
DAY(01..31) d.C
TIME
HOUR (00..23) TIMESTAMP
MINUT(00..59)
Any, mes, dia, hora, minut,
67
UD2. Llenguatge SQL DDL SQL
Amb Oracle, una columna d’aquest tipus no pot formar part de la clau, ni d’un
índex.
Només hi pot haver una columna d’aquests tipus a una mateixa taula.
• Data i hora
DATE
Les dades d’aquest tipus van entre cometes simples ‘ ‘ (igual que les
dades textuals).
El separador entre el dia, el mes i l’any pot ser una barra de divisió (/),
una guió (-) i altres símbols.
SYSDATE és una funció d’Oracle que permet obtenir la data actual del
sistema.
TIMESTAMP
Dominis
Creació de dominis
68
UD2. Llenguatge SQL DDL SQL
A part dels dominis representats pels tipus de dades predefinits, SQL92 ofereix la
possibilitat de treballar amb dominis definits per l’usuari.
Per crear un domini s’utilitza la sentència CREATE DOMAIN. La seva sintaxi és:
CREATE DOMAIN nomDomini [AS] tipusDades
[DEFAULT expr] [restriccionsDomini];
Quan es defineixi una columna, per exemple amb nom ciutat, dins la taula
departament, no s’hauria de definir amb tipus CHAR(20), sinó de tipus domCiutats.
Això assegura, segons el model relacional, que només farem operacions sobre la
columna ciutat amb altres columnes que tenen aquest mateix domini definit per
l’usuari. No obstant, SQL92 no té les eines per assegurar que les comparacions que fem
siguin entre els mateixos dominis definits per l’usuari.
Per exemple, si tenim una columna amb els noms dels treballadors definida sobre el
tipus de dades CHAR(20), SQL permet comparar-la amb la columna ciutat, tot i que
semànticament no tingui sentit. En canvi, segons els model relacional, aquesta
comparació no s’hauria de permetre.
Esborrar dominis
Per esborrar un domini s’utilitza la sentència DROP DOMAIN. La seva sintaxi és:
DROP DOMAIN nomDomini {RESTRICT|CASCADE};
On:
• RESTRICT fa que el domini només s’esborri si no s’utilitza a cap lloc.
Modificar dominis
Per modificar un domini s’utilitza la sentència ALTER DOMAIN. La seva sintaxi és:
ALTER DOMAIN nomDomini {acció_modif_domini|
acció_modif_restricció_domini};
On:
• acció_modif_domini pot ser:
69
UD2. Llenguatge SQL DDL SQL
Exemple: afegir una ciutat (Olot) al domini que hem creat abans.
ALTER DOMAIN domCiutats DROP CONSTRAINT ciutatsValides;
Amb això s’ha esborrat la restricció del domini. Ara cal afegir la nova restricció:
ALTER DOMAIN domCiutats ADD CONSTRAINT ciutatsValides
CHECK (VALUE IN (‘Barcelona’,’Tarragona’,’Lleida’,’Girona’,’Olot’));
Després de crear una taula, és possible que calgui canviar la seva estructura per
qualsevol motiu (ens hem oblidat d’una columna, el tipus de dades d’una columna no és
correcte, etc.). Per poder fer aquestes tasques, s’utilitza la sentència ALTER TABLE.
Per tant, amb ALTER TABLE es pot:
• Afegir una nova columna.
• Si afegim una nova columna a una taula que ja té files de dades, totes les files
inicialment tindran valor NUL per aquesta nova columna.
70
UD2. Llenguatge SQL DDL SQL
• Es pot disminuir la mida d’una columna només si aquesta conté només valors
nuls o si la taula no té files.
• Es pot convertir una columna CHAR amb VARCHAR2 o convertir una columna
VARCHAR2 amb CHAR només si la columna conté valors nuls o si no canvia
la mida.
• Cal tenir present que un canvi en el valor per defecte només afecta a les
insercions posteriors al canvi.
71
UD2. Llenguatge SQL DDL SQL
Quan s’indica aquesta clàusula no s’eliminen realment les columnes de destí de cada fila
de la taula (no es restaura l’espai de disc utilitzat per aquestes columnes). Per tant, el
temps de resposta és menor que si s’executés la sentència DROP. Les columnes no
utilitzades es consideren esborrades, tot i que les seves dades estiguin a les files de la
taula.
Un cop una columna està marcada com a no utilitzada, no s’hi pot accedir. Una consulta
SELECT * no dóna dades de les columnes no utilitzades. Tampoc es mostren en el
llistat de la comanda DESCRIBE. Fins i tot, es pot afegir una nova columna a la taula
amb el mateix nom que la no utilitzada.
La informació de SET UNUSED es guarda a la vista del diccionari
USER_UNUSED_COL_TABS.
72
UD2. Llenguatge SQL DDL SQL
Sintaxi:
ALTER TABLE nomTaula
SET UNUSED (nomColumna);
O bé
• Només pot eliminar una taula el seu creador o un usuari amb privilegi DROP
ANY TABLE.
73
UD2. Llenguatge SQL DDL SQL
La sentència RENAME permet canviar el nom d’una taula, una vista, una seqüència o un
sinònim.
Sintaxi:
RENAME nomVell TO nomNou;
Esborrar els continguts d’una taula o truncar una taula elimina totes les files de la taula i
allibera l’espai que ocupa aquesta taula.
Sintaxi:
TRUNCATE TABLE nomTaula;
Cal ser-ne propietari o tenir permisos DELETE TABLE per poder truncar una taula.
Amb SQL hi ha la sentència DELETE que també permet eliminar totes les files d’una
taula, però no allibera l’espai de disc ocupat. La sentència TRUNCATE és més ràpida que
DELETE per eliminar files, ja que:
• TRUNCATE és una sentència del llenguatge de definició de dades i no genera
informació de rollback (“tornar enrere”).
3.2.6. Restriccions
Introducció
Les restriccions són normes que es fan complir a les dades. En el cas d’Oracle, es
poden utilitzar les restriccions per:
• Forçar regles sobre les dades d’una taula quan s’insereix, actualitza o elimina
una fila de la taula. La restricció s’ha de complir per tal que es faci
correctament l’operació.
74
UD2. Llenguatge SQL DDL SQL
Definició de restriccions
Podem definir les restriccions mentre es crea una taula o després de crear la taula.
La sintaxi per definir les restriccions mentre es crea la taula és:
CREATE TABLE [esquema.]nomTaula
(
columna tipus [DEFAULT expr] [restriccióColumna],
...
[restriccióTaula] [,...]
);
On:
• restriccióColumna : restricció d’integritat com a part de la definició de
columna. Fa referència a una única columna.
Les restriccions també es poden afegir a una taula després d’haver-la crear i també es
poden desactivar temporalment.
On:
• nomRestricció : és un nom que podem donar a la restricció (molt
recomanat!)
On:
• nomRestricció : és un nom que podem donar a la restricció (molt
recomanat!)
75
UD2. Llenguatge SQL DDL SQL
Podem veure les restriccions definides a una taula consultant a la taula del diccionari de
dades USER_CONSTRAINTS.
La restricció NOT NULL
La restricció NOT NULL assegura que la columna no conté valors nuls. Cal recordar que
no es pot definir a nivell de taula; tant sols a nivell de columna
Les columnes sense aquesta restricció poden tenir valors nuls per defecte.
76
UD2. Llenguatge SQL DDL SQL
Exemple:
CREATE TABLE empleat
(
codi NUMBER(6),
nom VARCHAR2(30) NOT NULL,
cognom VARCHAR2(30),
sou NUMBER(8,2),
comissio NUMBER(2,2),
dataAlta DATE CONSTRAINT NN_empleat_dataAlta NOT NULL,
...
);
Com es pot veure a l’exemple, s’aplica la restricció NOT NULL a les columnes nom i
dataAlta. En el primer cas no s’ha especificat cap nom de restricció, per la qual cosa
Oracle li donarà un nom que tindrà la forma indicada anteriorment. En el segon cas s’ha
donat el nom NN_empleat_dataAlta a la restricció, on NN indica NOT NULL, empleat
indica la taula sobre la que s’estableix la restricció i dataAlta la columna on s’inclou la
restricció.
La restricció UNIQUE
Amb una restricció d’integritat de clau UNIQUE es garanteix que no pot haver-hi dues
files d’una taula que tinguin valors duplicats en una columna o conjunt de columnes
indicat.
La columna (o conjunt de columnes) inclosa a la definició de la restricció UNIQUE
s’anomena clau única. Si la restricció UNIQUE està formada per més d'una columna, el
grup de columnes s’anomena clau única composta.
Les restriccions UNIQUE permeten l’entrada de valors nuls a no ser que també defineixi
restriccions NOT NULL per les mateixes columnes.
Exemple:
CREATE TABLE empleat
(
codi NUMBER(6),
nom VARCHAR2(30) NOT NULL,
cognom VARCHAR2(30),
email VARCHAR2(40) CONSTRAINT UK_empleat_email,
sou NUMBER(8,2),
comissio NUMBER(2,2),
dataAlta DATE CONSTRAINT NN_empleat_dataAlta NOT NULL,
...
);
Es poden crear restriccions UNIQUE a nivell de columna o de taula, però les restriccions
UNIQUE compostes només es poden crear a nivell de taula.
NOTA: En el cas d’Oracle, si es crea un índex únic, crea automàticament una restricció
UNIQUE a la columna o les columnes on s’hagi definit l’índex.
La restricció PRIMARY KEY
Una restricció PRIMARY KEY crea una clau primària per la taula. Només es pot crear
una clau primària per cada taula.
La restricció PRIMARY KEY és una columna o conjunt de columnes que identifica de
forma única a cada fila d’una taula. Definint aquesta restricció es defineixen
implícitament les restriccions NOT NULL i UNIQUE.
77
UD2. Llenguatge SQL DDL SQL
Exemple:
CREATE TABLE departament
(
codi NUMBER(3),
nom VARCHAR2(30) CONSTRAINT NN_dept_nom NOT NULL,
localitat VARCHAR2(20),
CONSTRAINT PK_dept PRIMARY KEY(codi)
...
);
Es poden crear restriccions FOREIGN KEY a nivell de columna o de taula, però les
restriccions FOREIGN KEY compostes només es poden crear a nivell de taula.
A l’exemple es defineix una restricció FOREIGN KEY a la columna codiDept de la taula
empleat, utilitzant la sintaxi a nivell de taula.
La clau forana també es pot definir a nivell de columna, sempre que la restricció es basi
en una única columna. La sintaxi es diferencia en que no hi ha les paraules FOREIGN
KEY.
Exemple:
CREATE TABLE empleat
(
...
codiDept NUMBER(3) CONSTRAINT FK_empleat_codiDept
REFERENCES departament(codi),
...
);
78
UD2. Llenguatge SQL DDL SQL
Quan definim una clau forana hem dit que estem establint una regla d’integritat
referencial. Quan vam estudiar el model relacional, vam veure que la integritat referencial
podia provocar problemes en certs casos. Concretament, en l’eliminació o actualització
de files de la taula principal.
• Eliminació de files a la taula principal
Oracle no té cap mecanisme directe per solucionar això, com passa amb el
cas anterior. La única solució que es pot adoptar en aquest cas és la
implementació de disparadors (triggers).
Cal tenir present que amb Oracle, que per defecte no es permet l’actualització o la
supressió de les dades a les que es fa referència.
Exemple 1: eliminar les files de la taula empleat si s’esborra la fila de qui depèn a la
taula departament.
CREATE TABLE empleat
(
...
codiDept NUMBER(3) CONSTRAINT FK_empleat_codiDept
REFERENCES departament(codi) ON DELETE CASCADE,
...
);
Exemple 2: posar a null el valor de la columna codiDept a les files de la taula empleat
si s’esborra la fila de qui depèn a la taula departament.
CREATE TABLE empleat
(
...
codiDept NUMBER(3) CONSTRAINT FK_empleat_codiDept
REFERENCES departament(codi) ON DELETE SET NULL,
...
);
La restricció CHECK
La restricció CHECK defineix una condició que ha de complir cada fila.
79
UD2. Llenguatge SQL DDL SQL
Una mateixa columna pot tenir vàries restriccions CHECK que fan referència a la columna
en la seva definició. No hi ha límit en el número de restriccions CHECK que es poden
definir en una columna.
Exemple:
On:
• nomRestricció : és un nom de la restricció.
80
UD2. Llenguatge SQL DDL SQL
Consideracions:
• Es pot afegir una restricció NOT NULL a una columna que ja existeix utilitzant
la clàusula MODIFY de la sentència ALTER TABLE.
Exemple: afegir restricció clau forana a la taula empleat que indiqui que ha d’existir un
director com empleat vàlid a la taula empleat.
On:
• columna: és el nom de la columna/es afectada/es per la restricció
81
UD2. Llenguatge SQL DDL SQL
Produeix aquest error perquè hi ha claus foranes d’altres taules o de la mateixa que fan
referència a la clau primària de la taula curs.
Per solucionar aquest problema, s’hauria d’utilitzar la sentència:
ALTER TABLE curs DROP PRIMARY KEY CASCADE;
ERROR en línea 1:
ORA-12991: se hace referencia a la columna en una restricción
de multicolumna
La solució passa també per esborrar amb cascada:
ALTER TABLE curs DROP(dataIni) CASCADE CONSTRAINTS;
Amb aquesta sentència s’esborra la restricció CHECK que hi havia sobre la columna
dataIni.
Desactivació de restriccions
Es poden desactivar restriccions sense esborrar-les ni tornar a crear-les.
Sintaxi:
ALTER TABLE [esquema.]nomTaula
DISABLE CONSTRAINT nomRestricció [CASCADE];
On:
• nomRestricció : és un nom de la restricció.
Consideracions:
• Es pot utilitzar la clàusula DISABLE tant dins la sentència CREATE TABLE com
dins ALTER TABLE.
Exemple:
ALTER TABLE empleat
DISABLE CONSTRAINT PK_empleat CASCADE;
Activació de restriccions
Es poden desactivar restriccions sense esborrar-les ni tornar a crear-les.
82
UD2. Llenguatge SQL DDL SQL
Sintaxi:
ALTER TABLE [esquema.]nomTaula
ENABLE CONSTRAINT nomRestricció;
Consideracions:
• Si s’activa una restricció, s’aplica a totes les dades de la taula, que s’han
d’ajustar a la restricció.
• Es pot utilitzar la clàusula ENABLE tant dins la sentència CREATE TABLE com
dins ALTER TABLE.
Exemple:
ALTER TABLE empleat
ENABLE CONSTRAINT PK_empleat;
Els possibles tipus de restricció que es poden mostrar per constraint_type són:
Restricció constraint_type
NOT NULL C (is NOT NULL)
UNIQUE U
PRIMARY KEY P
FOREIGN KEY R
CHECK C
83
UD2. Llenguatge SQL DDL SQL
84
UD2. Llenguatge SQL DDL SQL
3.3.1. Introducció
Els índexs són objectes d’esquema que fan que el SGBD acceleri les operacions de
consulta i ordenació sobre els camps als que l’índex fa referència. Si no es té un índex a
una columna per la qual es fa una consulta o ordenació, l’operació en qüestió fa una
exploració completa de la taula.
Per tant, un índex proporciona accés directe i ràpid a les files d’una taula. El seu objectiu
és reduir la necessitat de fer operacions d’E/S de disc utilitzant un accés indexat per
trobar les dades ràpidament. En el cas d’Oracle, utilitza i manté els índexs
automàticament i, un cop creat l’índex, l’usuari no ha de fer cap operació sobre l’índex.
Es guarden a part de la taula a la que fa referència, el que permet crear-los i esborrar-los
en qualsevol moment (són independents lògica i físicament de la taula).
Els índexs gestionen una llista ordenada per la que el SGBD pot accedir-hi per facilitar la
cerca de les dades. Cada vegada que s’afegeix un nou registre, els índexs afectats
s’actualitzen per tal que la seva informació estigui actualitzada en tot moment. D’aquí ve
el problema de que quants més índexs hi hagi, té un cost major pel SGBD afegir
registres, però més ràpides són les instruccions de consulta.
La majoria dels índexs es creen de forma implícita, com a conseqüència de les
restriccions PRIMARY KEY (que obliga a crear un índex únic sobre els camps clau),
UNIQUE (crea també un índex únic) i FOREIGN KEY (crea un índex amb possibilitat de
repetir valors, índex amb duplicats). Aquests índexs són obligatoris, i gairebé sempre els
crea el mateix SGBD.
Cal tenir en compte que quan s’esborra un índex també s’esborren els índexs que en
depenen.
Una etiqueta d’índex es pot considerar com una taula de dues columnes, tal i com es
mostra a continuació:
CLAUS REGISTRE
ÍNDEX
85
UD2. Llenguatge SQL DDL SQL
• Índex no únic: el pot crear l’usuari. Per exemple, es pot crear un índex de
columna FOREIGN KEY per fer una combinació dins una consulta per millorar
la velocitat de recuperació de les files.
Sintaxi:
CREATE [UNIQUE] INDEX nomIndex
ON nomTaula (columna [ASC|DESC] [,columna [ASC|DESC]...] );
Exemple:
SQL> CREATE INDEX i_empleat_nom_ofici ON empl (empl_nom, empl_ofici);
A l’exemple es crea un índex pels camps nom i ofici. Això no és el mateix que fer un
índex per cada camp. Aquest tipus d’índex l’utilitza el SGBD quan es cerquen o ordenen
empleats utilitzant els dos camps a la vegada.
És aconsellable crear índexs en columnes que:
• Tinguin una gran quantitat de valors.
• Una o més columnes s’utilitzen juntes habitualment dins una clàusula WHERE o
dins una condició de combinació.
• Formen part de llistats de consultes de grans taules sobre les que gairebé
sempre es mostren com a molt el 4% de les files.
• S’espera que la majoria de les consultes recuperaran més del 2-4% de les files
de la taula.
86
UD2. Llenguatge SQL DDL SQL
Aquest tipus d’índexs tenen sentit si en les consultes s’utilitzen exactament aquestes
expressions (en l’exemple UPPER(empl_nom)). Si no s’utilitza aquesta expressió però,
per exemple, s’utilitza empl_nom a la condició de la consulta, no s’utilitzarà l’índex.
Oracle tracta els índexs amb columnes marcades DESC com índexs basats en funcions.
Les columnes marcades DESC s’ordenen descendentment. Per defecte un índex es crea
de tipus ASC.
Amb Oracle, per veure la llista d’índexs que hi ha creats s’utilitza la vista USER_INDEXES
del diccionari de dades.
La vista USER_IND_COLUMNS del diccionari de dades mostra la llista de columnes que
utilitzen els índexs.
Exemple:
SQL> SELECT INDEX_NAME, INDEX_TYPE, TABLE_NAME
2 FROM USER_INDEXES;
Exemple:
INDEX_NAME TABLE_NAME COLUMN_NAME DESC
------------------- --------------- ------------------------------- ----
I_NOM_EMPLEAT EMPL EMPL_NOM ASC
Els índexs no es poden modificar. Per canviar-lo, cal esborrar-lo i tornar-lo a crear.
Sintaxi:
DROP INDEX nomIndex;
3.4.1. Introducció
Hem vist que una taula representa un concepte del món real:
Gent diferent pot veure una taula conceptualment diferent.
No tothom té necessitat d’accedir a totes les dades de la taula.
De vegades convé amagar certa informació a determinats usuaris
87
UD2. Llenguatge SQL DDL SQL
Usuaris Treballadors
privilegiats Dades Generals
Vistes
Sintaxi:
CREATE [OR REPLACE] VIEW vista [(alies1[, alies2...]]
AS consultaSELECT
[WITH CHECK OPTION [CONSTRAINT restricció]]
[WITH READ ONLY [CONSTRAINT restricció]]
on:
OR REPLACE. Si la vista ja existeix, la canvia per l’actual.
vista. El nom de la vista.
alies1, alies2,… Llista d’àlies que s’estableixen per les columnes que
retorna la consulta SELECT amb la que es basa la vista. El número d’àlies ha
de coincidir amb el número de columnes que retorna el SELECT.
WITH CHECK OPTION. Només permet fer operacions d’actualització
(INSERT, UPDATE) si es compleix les condicions de selecció de la consulta
88
UD2. Llenguatge SQL DDL SQL
que defineix la vista (les condicions del WHERE). La restricció que segueix a
aquesta secció és el nom que se li dóna a aquesta restricció CHECK OPTION.
WITH READ ONLY. Fa que la vista sigui només de lectura.
Exemple: Creació d’una vista que contingui les dades dels empleats que són venedors.
SQL> CREATE VIEW Venedor(Numero, Nom, Data_alta, Salari)
2 AS
3 SELECT empl_num, empl_nom, empl_datalt, empl_salari
4 FROM empl
5* WHERE UPPER(empl_ofici) = 'VENEDOR';
Ara podem fer una consulta SELECT sobre la vista Venedor com si fos una taula:
SQL> SELECT * FROM venedor;
Com que la vista no té cap tipus de restricció especial a part de les pròpies que té la
taula sobre la que es basa la vista, podem executar la següent instrucció:
En la consulta anterior s’ha modificat la vista afegint la restricció WITH CHECK OPTION. Si
ara volem inserir un registre nou a la vista:
SQL> INSERT INTO Venedor
2 VALUES (26,'PERE PINATELL','30/03/1980',200000);
INSERT INTO Venedor
*
ERROR at line 1:
ORA-01402: violació de la clàusula where d'una vista WITH CHECK
OPTION
89
UD2. Llenguatge SQL DDL SQL
NOM
------------
La Paz
Amb Oracle, la vista del diccionari de dades USER_VIEWS permet mostrar una llista de
totes les vistes que té l’usuari actual. És a dir, per saber quines vistes es tenen creades,
cal executar:
SQL> SELECT *
2 FROM USER_VIEWS;
La columna TEXT d’aquesta vista conté la sentència SQL que es va utilitzar per crear la
vista (sentència que és executada cada vegada que s’invoca a la vista).
90
UD2. Llenguatge SQL DDL SQL
3.5.1. Introducció
A part dels objectes de la base de dades estudiats fins ara, els SGBDR incorporen altres
objectes d’esquema. En el cas d’Oracle, podem definir aquests altres objectes:
• Seqüències
• Sinònims
3.5.2. Seqüències
Introducció
Una seqüència serveix per generar automàticament números enters únics. S’acostumen
a utilitzar per generar valors per columnes que s’utilitzen com a clau primària forçada
(clau on el seu valor real no interessa, només serveixen per identificar els registres d’una
taula).
No tots es SGBD tenen la possibilitat de generar seqüències o bé si ho fan els hi donen
un nom diferent (per exemple, amb Access o MySQL es parla del tipus Autonumèric
quan es vol obtenir un valor de seqüència automàtic).
Amb Oracle, és una rutina interna la que genera i augmenta (o disminueix) la seqüència
de números. Les seqüències es guarden independentment de la taula, i per tant, la
mateixa seqüència es pot utilitzar per diferents taules.
Creació de seqüències
Sintaxi:
CREATE SEQUENCE nomSeqüència
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n|NOMAXVALUE}]
[{MINVALUE n|NOMINVALUE}]
[{CYCLE|NOCYCLE}]
[{CACHE n|NOCACHE}]
on:
• nomSeqüència : és el nom que es dóna a l’objecte seqüència.
• MAXVALUE: serveix per indicar el valor màxim que pot agafar la seqüència. Si
no s’especifica, agafa el valor NOMAXVALUE que permet arribar fins a 1027(per
seqüència ascendent).
• MINVALUE: serveix per indicar el valor mínim que pot agafar la seqüència. Si
no s’especifica, agafa el valor NOMINVALUE que permet arribar fins a 10-26 (per
seqüència descendent).
91
UD2. Llenguatge SQL DDL SQL
Exemple: Definir una seqüència perquè generi els valors de la columna EMPL_NUM
SQL> CREATE SEQUENCE seq_empl_num
2 INCREMENT BY 1
3 START WITH 8000
4 MAXVALUE 99999;
Sequence created.
En aquest exemple, destacar la columna LAST_NUMER que indica quin serà el proper
número que donarà la seqüència.
1 row created.
92
UD2. Llenguatge SQL DDL SQL
7566 JIMENEZ
7654 MARTIN
7698 NEGRO
7782 CEREZO
7788 GIL
7839 REY
7844 TOVAR
7876 ALONSO
7900 JIMENO
7902 FERNANDEZ
7934 MUNOZ
1000 Pere
4000 Manel
25 PERE PI
8001 PERE PINATELL
• Dins la llista de columnes SELECT d’una subconsulta que està dins una
sentència INSERT.
• Dins una sentència SELECT amb clàusules GROUP BY, HAVING o ORDER BY.
Modificar seqüències
Si la seqüència arriba a MAXVALUE, la seqüència no generarà més valors i es produirà
un missatge d’error que indicarà que la seqüència supera MAXVALUE. Per poder
continuar utilitzant la seqüència, es pot modificar amb ALTER SEQUENCE.
Sintaxi:
ALTER SEQUENCE nomSeqüència
[INCREMENT BY n]
[{MAXVALUE n|NOMAXVALUE}]
[{MINVALUE n|NOMINVALUE}]
[{CYCLE|NOCYCLE}]
[{CACHE n|NOCACHE}]
93
UD2. Llenguatge SQL DDL SQL
Esborrar seqüències
Sintaxi:
DROP SEQUENCE nomSeqüència;
Cal ser el propietari de la seqüència o tenir privilegi DROP ANY SEQUENCE per esborrar-
la.
3.5.3. Sinònims
Introducció
Un sinònim és un nom que s’assigna a un objecte qualsevol. Normalment és un nom
menys descriptiu que l’original per tal de facilitar l’escriptura del nom de l’objecte en les
expressions on s’utilitza.
No tots els SGBD permeten la creació de sinònims.
Creació de sinònims
Sintaxi:
CREATE [PUBLIC] SYNONYM nomSinonim
FOR nomObjecte;
on:
• PUBLIC: crea un sinònim accessible per tots els usuaris.
Consideracions:
• El nom d’un sinònim privat ha de ser diferent de tots els altres objectes
propietat del mateix usuari.
Synonym created.
94
UD2. Llenguatge SQL DDL SQL
Esborrar sinònims
Sintaxi:
DROP SYNONYM nomSinònim;
95
UD2. Llenguatge SQL Transaccions i concurrència
4.1.1. Introducció
4.1.2. Transaccions
COMMIT
La instrucció COMMIT fa que els canvis realitzats per la transacció siguin definitius i
irrevocables. Només cal utilitzar aquesta instrucció si estem d’acord amb els canvis. Cal
estar completament segur d’executar COMMIT ja que les instruccions executades poden
afectar a milers de registres. A més a més el tancament correcte de la sessió produeix el
COMMIT, tot i que sempre convé executar explícitament aquesta instrucció per tal
d’assegurar-nos del que fem.
Hi ha alguns SGBDR (com Oracle) que ofereixen mecanismes que permeten validar les
transaccions de forma automàtica sense haver-ho d’indicar de forma explícita.
96
UD2. Llenguatge SQL Transaccions i concurrència
Amb l’SQL *Plus, es pot configurar la variable AUTOCOMMIT. El valor d’aquesta es pot
comprovar amb el SHOW, de la següent forma:
SQL > SHOW AUTOCOMMIT;
Per defecte el valor d’AUTOCOMMIT és OFF, és a dir, no es guarden el canvis fins que
no es faci un COMMIT. En cas de voler validar automàticament els canvis fet, s’ha
d’escriure la següent ordre (des de la línia de comandes):
SQL > SET AUTOCOMMIT ON;
ROLLBACK
Aquesta instrucció permet tornar a l’estat anterior a l’inici de la transacció, normalment
l’últim COMMIT, la última instrucció DDL o DCL o a l’inici de sessió.
Anul·la definitivament els canvis, motiu pel qual cal estar també molt segur d’executar
aquesta operació.
Exemple de transacció:
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(1000,’Pere’,10);
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(2000,’Joan’,20);
COMMIT;
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(3000,’Albert’,10);
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(4000,’Manel’,40);
ROLLBACK;
En l’exemple anterior s’afegeixen els empleats Pere i Joan, però no l’Albert i en Manel, ja
que la instrucció de validació COMMIT s’executa abans de la instrucció d’inserció de
l’empleat Albert.
97
UD2. Llenguatge SQL Transaccions i concurrència
SAVEPOINT
Aquesta instrucció permet establir un punt de retorn dins una transacció. El problema
d’utilitzar conjuntament ROLLBACK/COMMIT és que un COMMIT ho accepta tot i un
ROLLBACK ho anul·la tot.
SAVEPOINT permet senyalar un punt entre l’inici i el final de la transacció. La seva
sintaxi és:
...instruccions DML...
SAVEPOINT nom
...instruccions DML...
Exemple:
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(1000,’Pere’,10);
SAVEPOINT Pere;
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(2000,’Joan’,20);
SAVEPOINT Joan;
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(3000,’Albert’,10);
ROLLBACK TO Pere;
INSERT INTO empl(empl_num, empl_nom, empl_dept_num)
VALUES(4000,’Manel’,40);
COMMIT;
98
UD2. Llenguatge SQL Transaccions i concurrència
99
UD2. Llenguatge SQL Transaccions i concurrència
Exercici 1:
Un usuari A selecciona totes les dades de la taula EMPL.
A continuació, un usuari B esborra tots els empleats que són ANALISTA.
A continuació, l’usuari A torna a seleccionar totes les dades de la taula EMPL. Quines
dades veu?
Tot seguit, l’usuari B selecciona totes les dades de la taula EMPL. Quines dades veu?
Per què es produeix aquesta situació? Quines solucions es poden aplicar per solucionar
el problema?
Exercici 2:
Un usuari A vol incrementar un 20% el salari de l’empleat ALONSO.
A continuació, un usuari B vol incrementar un 10% el salari de l’empleat ALONSO.
Què passa? Com es soluciona aquesta situació?
4.2.2. Bloqueig
Els bloquejos són mecanismes que eviten una interacció destructiva entre les
transaccions que accedeixen a les mateixes dades.
Com bloqueja dades Oracle?
El bloqueig que fa Oracle es fa automàticament i no necessita que l’usuari faci res. El
bloqueig implícit es produeix per les instruccions SQL segons sigui necessari, en funció
de l’acció que es faci. Aquest bloqueig es produeix per totes les instruccions SQL menys
la instrucció SELECT.
Els usuaris també poden bloquejar dades manualment, el que s’anomena bloqueig
explícit.
100
UF1. Llenguatges SQL:
DCL i extensió
procedimental
M10. Administració de Bases
de Dades
Contingut
Capítol 1. SQL hostatjat........................................................................................3
1.1. Introducció.................................................................................................................... 3
1.2. PL/SQL......................................................................................................................... 3
1.2.1. Blocs PL/SQL .................................................................................................... 3
1.2.2. Tipus de blocs ................................................................................................... 4
1.3. Identificadors, variables i constants ............................................................................. 5
1.3.1. Identificadors ..................................................................................................... 5
1.3.2. Variables ........................................................................................................... 6
1.3.3. Constants .......................................................................................................... 7
1.3.4. Els atributs %TYPE i %ROWTYPE......................................................................... 7
1.3.5. Exemples de variables i constants.................................................................... 7
1.4. Operadors .................................................................................................................... 9
1.5. Instruccions de control de flux ..................................................................................... 9
1.5.1. Instrucció IF...................................................................................................... 9
1.5.2. Instrucció CASE ............................................................................................... 11
1.5.3. Instruccions iteratives...................................................................................... 12
1.5.4. Exemples......................................................................................................... 13
1.6. Cursors....................................................................................................................... 14
1.6.1. Introducció ....................................................................................................... 14
1.6.2. Processament de cursors................................................................................ 14
1.6.3. Declaració de cursors...................................................................................... 14
1.6.4. Obrir el cursor.................................................................................................. 14
1.6.5. Instrucció FETCH ............................................................................................. 14
1.6.6. Tancar el cursor .............................................................................................. 15
1.6.7. Atributs dels cursors........................................................................................ 15
1.6.8. Variables de registre ....................................................................................... 16
1.6.9. Cursors i registres ........................................................................................... 17
1.6.10. Utilització avançada de cursors .................................................................... 19
1.7. Excepcions................................................................................................................. 20
1.7.1. Introducció ....................................................................................................... 20
1.7.2. Captura d’excepcions...................................................................................... 20
1.7.3. Excepcions predefinides ................................................................................. 21
1.7.4. Excepcions sense definir................................................................................. 22
1.7.5. Funcions amb excepcions............................................................................... 23
1.7.6. Excepcions d’usuari ........................................................................................ 23
1.8. Subprogrames............................................................................................................ 23
1.8.1. Introducció ....................................................................................................... 23
1.8.2. Procediments .................................................................................................. 24
1.8.3. Funcions .......................................................................................................... 25
1.8.4. Eliminar funcions ............................................................................................. 27
Capítol 2. SQL hostatjat avançat (PL/SQL avançat).........................................28
2.1. Introducció.................................................................................................................. 28
2.2. Paquets ...................................................................................................................... 28
2.2.1. Parts d’un paquet ............................................................................................ 28
2.2.2. Creació de l’especificació d’un paquet............................................................ 28
2.2.3. Creació del cos d’un paquet............................................................................ 29
2.2.4. Avantatges dels paquets ................................................................................. 29
2.3. Triggers ...................................................................................................................... 29
2.3.1. Elements dels triggers..................................................................................... 31
2.3.2. Quan s’ha d’executar el trigger? ..................................................................... 31
2.3.3. Tipus de trigger ............................................................................................... 31
2.3.4. Triggers de fila................................................................................................. 32
2.3.5. Referències NEW i OLD.................................................................................. 32
2.3.6. IF INSERTING, IF UPDATING i IF DELETING............................................... 33
2.3.7. Triggers INSTEAD OF..................................................................................... 33
2.3.8. Exemples......................................................................................................... 35
2.3.9. Administració de triggers................................................................................. 36
ii
UD3. SQL hostatjat SQL hostatjat
Fins ara hem estudiat i treballat amb la base de dades de forma interactiva, és a dir,
l’usuari introdueix una sentència SQL i el SGBD dóna la resposta de forma immediata.
Aquesta forma de treballar no és la millor, tot i que l’SQL és un llenguatge bastant senzill
de treballar, no tots els usuaris coneixen ni tenen perquè conèixer aquest llenguatge.
Per tant, el millor és programar les sentències SQL, utilitzant un llenguatge de
programació.
Així que, les sentències SQL que treballen de forma hostatjada (també es diu que es
treballa de forma integrada, immersa, etc.) utilitzen aquestes sentències en un programa
escrit en un llenguatge de programació.
Nosaltres estudiarem l’SQL immers amb Oracle, que incorpora un gestor PL/SQL
(Procedural Language Extension) en el servidor de la base de dades i en les principals
eines (Forms, Reports, etc.).
El llenguatge PL/SQL té totes les característiques pròpies dels llenguatges de tercera
generació: gestió de variables, estructura modular (procediments i funcions), estructures
de control (alternatives, iteratives, etc.), control d’excepcions, etc.
Els programes creats amb PL/SQL es poden emmagatzemar a la base de dades com
qualsevol altre objecte d’aquesta. D’aquesta manera es facilita a tots els usuaris
autoritzats de la base de dades que hi puguin accedir.
Hi ha un seguit d’avantatges quan es treballa amb PL/SQL:
Facilitar la distribució del treball.
La instal·lació i manteniment del programa.
Reducció del cost de treball.
A més a més, cal destacar que els programes PL/SQL s’executen en el servidor.
1.2. PL/SQL
Sintaxi:
[DECLARE
<declaracions>]
3
UD3. SQL hostatjat SQL hostatjat
BEGIN
<cos del bloc: instruccions >
[EXCEPCION
<gestió de les excepcions (errors) >]
END;
on:
DECLARE indica la zona de declaracions, és a dir, on es declaren els
objectes locals necessaris (variables, constants, etc.). És un paràmetre
opcional i a més a més de la clàusula DECLARE es poden utilitzar IS/AS, per
procediments i funcions.
BEGIN zona on hi ha el conjunt d’instruccions que s’han d’executar.
EXCEPTION zona opcional per tractar les excepcions que es produeixen
(errors).
4
UD3. SQL hostatjat SQL hostatjat
Sintaxi:
[DECLARE
<declaracions>]
BEGIN
<cos del bloc: instruccions >
[EXCEPCION
<gestió de les excepcions (errors) >]
END;
PROCEDIMENT
Bloc que s’emmagatzema al servidor i s’executa cada vegada que s’invoca.
Sintaxi:
PROCEDURE nomProcediment [(par1, par2, ...)] IS
[<declaracions locals>]
BEGIN
<cos del bloc: instruccions >
[EXCEPCION
<gestió de les excepcions (errors) >]
END [nomProcediment];
FUNCIÓ
Similar a un procediment, amb la diferència de que es passa un paràmetre (com a
mínim) i retorna un valor.
Sintaxi:
FUNCTION nomFunció [(par1, par2, ...)] RETURN tipusDades IS
BEGIN
…
RETURN valor;
[EXCEPTION]
END;
1.3.1. Identificadors
Els identificadors s’utilitzen per donar nom als objectes que intervenen en un programa i
són: variables, constants, cursors, excepcions, procediments, funcions, etiquetes, etc.
Amb PL/SQL, els identificadors tenen les següents característiques:
Poden tenir fins a 30 caràcters, començant sempre per una lletra i pot anar
seguida per més lletres, números, signe dòlar ($), coixinet (#) i el subguió (_).
No es diferencia entre majúscules i minúscules.
Es poden saltar algunes de les regles anteriors posant l’identificador entre
cometes.
5
UD3. SQL hostatjat SQL hostatjat
1.3.2. Variables
Amb PL/SQL es poden declarar variables i s’utilitzen entre altres coses per
emmagatzemar temporalment una dada i manipular valors emmagatzemats
anteriorment. Aquestes variables també es poden utilitzar amb SQL i sentències de
procediment.
Les variables PL/SQL s’han de declarar dins la secció corresponent i sempre abans de la
seva utilització, és a dir, dins la secció DECLARE.
Sintaxi:
nom_variable tipus [NOT NULL] [{:=|DEFAULT} valor]
on:
nom_variable => identificador de la variable.
tipus => el tipus de dades de la variable (els veurem més endavant).
NOT NULL => força que la variable sempre tingui un valor. Sempre que es
declari una variable amb NOT NULL cal inicialitzar la variable. En general
però, hem d’inicialitzar totes les variables.
TIPUS DE DADES DE VARIABLES PL/SQL
ORACLE SQL Descripció
CHAR(n) Text de longitud fixa
VARCHAR2(n) Text de longitud variable
LONG Text de més de 32767 caràcters
NUMBER(p,s) Números decimals de coma fixa
BOOLEAN Emmagatzema els valor TRUE i
FALSE.
DATE Emmagatzema dates.
TIMESTAMP Emmagatzema dates i hores.
ROWID Emmagatzema identificadors de fila.
6
UD3. SQL hostatjat SQL hostatjat
1.3.3. Constants
Sintaxi:
nom_constant CONSTANT tipus := valor
La finalitat d’utilitzar aquests atributs quan es declaren variables és per declarar variables
que siguin del mateix tipus que altres objectes que ja estan definits. És a dir, la variable
“hereda” el tipus i la longitud de l’objecte, però no els atributs NOT NULL, ni valors per
defecte.
%TYPE
Aquest atribut permet declarar una variable del mateix tipus que una altra, o que una
columna d’una taula. Per tant, declara una variable basada amb altres que ja han estat
declarades abans, o en la definició d’una columna d’una taula.
Per exemple, si volem declarar una variable anomenada var_nom que sigui del mateix
tipus de dades que el nom d’un empleat que tenim a la nostra base de dades,
concretament a la taula EMPL, llavors ho faríem com segueix:
...
var_nom empl.empl_nom%TYPE;
...
%ROWTYPE
Aquest atribut crea una variable de registre on els seus camps es corresponen amb les
columnes d’una taula o vista de la base de dades.
...
var_empl empl%ROWTYPE;
...
A l’hora de declarar les variables cal tenir en compte on es declaren i com: si declarem la
variable local pel bloc on ha estat declarada i/o global per tots els blocs.
EXEMPLE 1: Declara una variable en un bloc pare i és accessible pel bloc fill.
DECLARE /* Bloc pare */
var1 NUMBER;
BEGIN
var1 := 10;
DBMS_OUTPUT.PUT_LINE('El valor de la variable 1 es '||var1);
DECLARE /* Bloc fill */
var2 NUMBER;
BEGIN
var2 := 20;
DBMS_OUTPUT.PUT_LINE('El valor de la variable 2 es '||var2);
var2 := var1;
DBMS_OUTPUT.PUT_LINE('Ara el valor de la variable 2 es'||var2);
END; /* FI bloc fill */
END; /* FI bloc pare */
EXEMPLE 2: Declara una variable en un bloc fill i no és accessible pel bloc pare.
DECLARE
var1 NUMBER;
BEGIN
var1 := 10;
7
UD3. SQL hostatjat SQL hostatjat
8
UD3. SQL hostatjat SQL hostatjat
On:
SELECT selecciona els camps de la taula que volem consultar.
INTO guarda amb variables PL/SQL declarades prèviament, el valor dels
camps corresponents. Hi ha d’haver tantes variables com camps hi hagi en el
SELECT.
FROM nom de la taula a consultar.
WHERE clàusula que controla la condició o condicions que ha de complir
un registre d’una taula.
3. S’utilitza l’atribut %TYPE per declarar les variables PL/SQL corresponents; ja que han
de ser del mateix tipus de dades que els camps de la taula.
L’exemple, per tant és:
DECLARE
var_num empl.empl_num%TYPE;
var_nom empl.empl_nom%TYPE;
var_sal empl.empl_salari%TYPE;
codi NUMBER;
BEGIN
SELECT empl_num, empl_nom, empl_salari
INTO var_num, var_nom, var_sal
FROM empl
WHERE empl_num = &&codi;
DBMS_OUTPUT.PUT_LINE (' ');
DBMS_OUTPUT.PUT_LINE ('COD NOM SALARI');
DBMS_OUTPUT.PUT_LINE ('=============================');
DBMS_OUTPUT.PUT_LINE (var_num||' '||var_nom||' '||var_sal);
END;
/
1.4. Operadors
Amb PL/SQL es poden utilitzar tots els operadors de SQL: els aritmètics (+-*/),
condicionals (> < != <> >= <= OR AND NOT) i de concatenació (||).
3
A més amés, PL/SQL afegeix l’operador de potencia **. Exemple: 4**3 és 4 .
1.5.1. Instrucció IF
IF SIMPLE
IF condició THEN
instruccions
END IF;
Exemple:
IF departament = 134 THEN
salari := salari * 13;
departament := 123;
END IF;
9
UD3. SQL hostatjat SQL hostatjat
IF-THEN-ELSE
IF condició THEN
instruccions1
ELSE
instruccions2
END IF;
Exemple:
IF saldo>90 THEN
DBMS_OUTPUT.PUT_LINE(‘Saldo més gran del que s’esperava.’);
ELSE
IF saldo>0 THEN
DBMS_OUTPUT.PUT_LINE(‘Saldo menor del que s’esperava’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Saldo NEGATIU’);
END IF;
END IF;
10
UD3. SQL hostatjat SQL hostatjat
Exemple:
IF saldo>90 THEN
DBMS_OUTPUT.PUT_LINE(‘Saldo més gran del que s’esperava.’);
ELSIF saldo>0 THEN
DBMS_OUTPUT.PUT_LINE(‘Saldo menor del que s’esperava’
ELSE
DBMS_OUTPUT.PUT_LINE(‘Saldo NEGATIU’);
END IF;
CASE variable
WHEN expressió1 THEN resultat1
WHEN expressió2 THEN resultat2
...
[ELSE resultatElse]
END;
Exemple:
text:= CASE actitut
WHEN 'A' THEN 'Molt bona'
WHEN 'B' THEN 'Bona'
WHEN 'C' THEN 'Normal'
WHEN 'D' THEN 'Dolenta'
ELSE 'Desconeguda'
END;
Cal tenir present que la instrucció CASE serveix per retornar un valor i no per executar
una instrucció.
Una altra possibilitat d’utilitzar el CASE és:
CASE
WHEN condició1 THEN resultat1
WHEN condició2 THEN resultat2
...
[ELSE resultatElse]
END;
Aquest segon format facilita l’escriptura de sentències CASE més complexes. Per
exemple:
aprovat:=CASE
WHEN actitut='A' AND nota>=4.5 THEN TRUE
WHEN nota>=5 AND (actitut='B' OR actitut='C') THEN TRUE
WHEN nota>=7 THEN TRUE
ELSE FALSE
END;
11
UD3. SQL hostatjat SQL hostatjat
BUCLE LOOP
Instrucció que conté instruccions que es repeteixen indefinidament (bucle infinit).
Comença amb la paraula LOOP i acaba amb END LOOP i dins hi ha les instruccions que
es repetiran.
Òbviament no té sentit utilitzar un bucle infinit. Per això hi ha la instrucció EXIT que
permet sortir el bucle. Quan Oracle troba aquesta instrucció, el programa continua a
partir de la següent instrucció després de l’END LOOP.
El més normal és col·locar EXIT dins d’una instrucció IF per tal d’establir una condició de
fi del bucle. També es pot utilitzar la instrucció EXIT juntament amb la instrucció WHEN
seguida d’una condició. Si la condició és certa, acaba el bucle, altrament es continua
iterant.
LOOP
instruccions
...
EXIT [WHEN condició]
END LOOP;
Exemple:
DECLARE
c NUMBER := 1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(c);
EXIT WHEN c = 10;
c := c + 1;
END LOOP;
END;
BUCLE WHILE
WHILE condició LOOP
instruccions
END LOOP;
Exemple:
DECLARE
c NUMBER :=1;
BEGIN
WHILE c <= 10 LOOP
DBMS_OUTPUT.PUT_LINE(c);
c := c + 1;
END LOOP;
END;
12
UD3. SQL hostatjat SQL hostatjat
BUCLE FOR
S’utilitza per bucles amb comptador, bucles que fan un recorregut un cert nombre de
vegades. S’utilitza una variable (comptador) que no ha d’estar declarada al DECLARE,
sinó que es declara automàticament en el mateix FOR i s’elimina quan acaba.
S’indica el valor inicial de la variable i el valor final (l’increment anirà d’un en un). Si s’usa
la clàusula REVERSE, llavors el comptador compte des del valor màxim fins al mínim
restant 1.
Sintaxi:
FOR comptador IN [REVERSE] mínim..màxim LOOP
instruccions
END LOOP;
Exemple:
FOR i IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE(i);
END LOOP;
1.5.4. Exemples
Programar un script amb PL/SQL que escrigui tres vegades la paraula HOLA i deu
vegades la paraula ADÉU.
DECLARE
i NUMBER;
BEGIN
i:=1;
WHILE i<=13 LOOP
IF i<4 THEN
DBMS_OUTPUT.PUT_LINE(‘HOLA’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘ADEU’);
END IF;
i:=i+1;
END LOOP;
END;
/
Programar un script amb PL/SQL que escrigui la taula de multiplicar d’un número entrat
per teclat.
DECLARE
inici NUMBER :=0;
fi NUMBER :=10;
resultat NUMBER :=0;
BEGIN
FOR i IN inici..fi LOOP
resultat := i * &&var_num;
DBMS_OUTPUT.PUT_LINE(i||' * ' || &&var_num || ' ='||resultat);
END LOOP;
END;
/
13
UD3. SQL hostatjat SQL hostatjat
1.6. Cursors
1.6.1. Introducció
Els cursors representen consultes SELECT SQL que retornen més d’un resultat i que
permeten l’accés a cada fila de la consulta. Això significa que el cursor sempre té un
punter a una de les files del SELECT que representa el cursor.
Sintaxi:
CURSOR nom IS instruccióSELECT;
Sintaxi:
OPEN cursor;
14
UD3. SQL hostatjat SQL hostatjat
Sintaxi:
CLOSE cursor;
Quan es tanca el cursor s’allibera la memòria que ocupa i s’impedeix que s’utilitzi.
Per poder processar de forma adient els cursors es poden utilitzar uns atributs que
retornen CERT o FALS segons la situació actual del cursor. S’utilitzen indicant el nom
del cursor i immediatament després el nom del cursor.
Exemple: cursorDepartaments%ISOPEN
%ISOPEN
Retorna CERT si el cursor ja està obert.
%NOTFOUND
Retorna CERT si la última instrucció FETCH no ha retornat cap fila.
15
UD3. SQL hostatjat SQL hostatjat
Exemple:
DECLARE
CURSOR cursorDepartaments IS
SELECT dept_nom, COUNT(*) AS “Empleats”
FROM dept, empl
WHERE empl_dept_num = dept_num
GROUP BY dept_nom;
v_nom DEPT.dept_nom%TYPE;
v_empleats NUMBER;
BEGIN
OPEN cursorDepartaments;
LOOP
FETCH cursorDepartaments INTO v_nom, v_empleats;
EXIT WHEN cursorDepartaments%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_nom || ‘,’ || v_empleats);
END LOOP;
CLOSE cursorDepartaments;
END;
%FOUND
Retorna CERT si la última instrucció FETCH ha retornat alguna fila.
%ROWCOUNT
Indica el número de files que s’han recorregut amb el cursor (inicialment val 0). És a dir,
indica quants FETCH s’han aplicat sobre el cursor.
Els registres són una estructura estàtica de dades present en gairebé tots els
llenguatges clàssics de programació (amb C o C# seria un struct). Es tracta d’un tipus
de dades que es composa de dades més simples. Per exemple, els registre persona es
composaria de les dades simples nom, cognoms, adreça, data de naixement, etc.
Amb PL/SQL interessa aquest tipus de dades perquè cada fila d’una taula o vista es pot
interpretar com un registre. Els registres faciliten el treball amb cursors.
Per utilitzar registres, primer cal definir les dades que composen el registre. Després es
declara una variable de registre que sigui del tipus definit.
Sintaxi:
TYPE nomTipusRegistre IS RECORD(
camp1 tipusCamp1 [:= valorInicial],
camp2 tipusCamp2 [:= valorInicial],
...
campN tipusCampN [:= valorInicial]
)
nomVariableDeRegistre nomTipusRegistre;
NOTA: Recordar que per definir una variable de tipus registre també podem aprofitar l’ús
de l’atribut %ROWTYPE que hem vist en el punt 1.3.4.
16
UD3. SQL hostatjat SQL hostatjat
Exemple:
TYPE regPersona IS RECORD(
nom VARCHAR2(25),
cog1 VARCHAR2(25),
cog2 VARCHAR2(25),
data_naix DATE
);
pere regPersona;
maria regPersona;
UTILITZACIÓ DE REGISTRES
Per accedir als valors dels registres cal indicar el nom de la variable de registre seguida
d’un punt i el nom del camp:
maria.nom := ‘MARIA’;
maria.data_naix := TO_DATE(‘02/03/1990’);
rDep cursorDepartaments%ROWTYPE;
BEGIN
OPEN cursorDepartaments;
LOOP
FETCH cursorDepartaments INTO rDep;
EXIT WHEN cursorDepartaments%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(rDep.nom || ‘,’ || rDep.empleats);
END LOOP;
CLOSE cursorDepartaments;
END;
17
UD3. SQL hostatjat SQL hostatjat
Exemple:
DECLARE
CURSOR cursorDepartaments IS
SELECT dept_nom AS Nom, COUNT(*) AS Empleats
FROM dept, empl
WHERE empl_dept_num = dept_num
GROUP BY dept_nom;
rDep cursorDepartaments%ROWTYPE;
BEGIN
FOR rDep IN cursorDepartaments LOOP
DBMS_OUTPUT.PUT_LINE(rDep.nom || ‘,’ || rDep.empleats);
END LOOP;
END;
Exemple:
BEGIN
FOR cDep IN (SELECT dept_nom FROM dept WHERE dept_loc=’Girona’) LOOP
DBMS_OUTPUT.PUT_LINE(cDep.dept_nom);
END LOOP;
END;
18
UD3. SQL hostatjat SQL hostatjat
És quan s’obre el cursor quan s’indica el valor dels paràmetres, la qual cosa significa que
es pot obrir tantes vegades com es vulgui el cursor i que aquest tingui resultats diferents
en funció del valor dels paràmetres.
També es poden indicar els paràmetres en el bucle FOR.
Exemple:
DECLARE
CURSOR curEmpleats(dep NUMBER, ofici VARCHAR2(20)) IS
SELECT empl_nom, empl_salari
FROM empl
WHERE empl_dept_num=dep AND empl_ofici=ofici;
BEGIN
FOR r IN curEmpleats(12,’ANALISTA’) LOOP
.....
END LOOP;
END;
Exemple:
DECLARE
CURSOR c_emp IS
19
UD3. SQL hostatjat SQL hostatjat
A continuació, a la instrucció UPDATE que modifica els registres, es pot utilitzar una
nova clàusula anomenada WHERE CURRENT OF seguida del nom d’un cursor, que fa
que es modifiqui el registre actual del cursor.
Exemple:
FOR r_emp IN c_emp LOOP
IF r_emp.empl_salari<1500 THEN
UPDATE empl SET empl_slari = empl_salari * 1.30
WHERE CURRENT OF c_emp;
END IF;
END LOOP;
1.7. Excepcions
1.7.1. Introducció
S’anomena excepció a una acció que li succeeix a un programa que provoca que la seva
execució acabi. Òbviament això causa que el programa acabi de forma anòmala.
Les excepcions es produeixen per:
Que es produeixi un error detectat per Oracle (per exemple si un SELECT no
retorna dades es produeix l’error ORA-01403 també anomenat
NO_DATA_FOUND).
Que el programador les provoqui (comandament RAISE).
Les excepcions es poden capturar pe tal que el programa no finalitzi de forma anòmala.
La captura es fa utilitzant el bloc EXCEPTION que és el bloc que està just abans de
l’END del bloc del programa. Quan hi ha una excepció, es comprova el bloc EXCEPTION
per veure si s’ha capturat, si no es captura, l’error es passa a Oracle que s’encarregarà
d’indicar l’error.
Tipus d’excepcions:
Excepcions preestablertes d’Oracle. Ja tenen assignat un nom d’excepció.
Excepcions d’Oracle sense definir. No tenen nom assignat però se’ls hi pot
assignar.
Definides per l’usuari. Les ha de cridar el programador.
Sintaxi per capturar excepcions:
DECLARE
secció de declaracions
BEGIN
instruccions
EXCEPTION WHEN excepció1 [OR excepció2 ...] THEN
instruccions que s’executen si es produeixen
aquestes excepcions
[WHEN excepció3 [OR...] THEN
instruccions que s’executen si es produeixen
aquestes excepcions]
[WHEN OTHERS THEN]
20
UD3. SQL hostatjat SQL hostatjat
21
UD3. SQL hostatjat SQL hostatjat
no és vàlid.
Exemple:
DECLARE
x NUMBER :=0;
y NUMBER := 3;
res NUMBER;
BEGIN
res:=y/x;
DBMS_OUTPUT.PUT_LINE(res);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('No es pot dividir per zero');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error no esperat’) ;
END;
Hi pot haver moltes més excepcions que no estan a la llista anterior. En aquest cas tot i
que no tenen un nom assignat, si que tenen un número. Aquest número és el que surt
quan Oracle mostra el missatge d’error després de la paraula ORA.
Per exemple, en un error per restricció d’integritat Oracle llança un missatge que
comença pel text: ORA-02292. Per tant, l’error d’integritat referencial és el -02292.
Si es volen capturar excepcions no definides cal:
Declarar un nom per l’excepció que es captura. Això es fa a l’apartat DECLARE.
Sintaxi:
nomExcepció EXCEPTION;
Associar aquest nom amb el número d’error corresponent amb la següent sintaxi dins el
DECLARE (després de la instrucció del pas 1):
PRAGMA EXCEPTION_INIT(nomExcepció, nºExcepció);
22
UD3. SQL hostatjat SQL hostatjat
El programador pot llançar les seves pròpies excepcions simulant errors del programa.
Cal fer el següent:
Declarar un nom per l’excepció.
Utilitzar la instrucció RAISE per llançar l’excepció (dins el bloc BEGIN..END).
Capturar l’excepció a l’apartat EXCEPTION.
1.8. Subprogrames
1.8.1. Introducció
23
UD3. SQL hostatjat SQL hostatjat
1.8.2. Procediments
on:
IN. Són els paràmetres que en altres llenguatges s’anomenen per valor. El
procediment rep una copia del valor o variable que s’utilitza com a paràmetre
al cridar el procediment. Aquests paràmetres poden ser: valors literals (18 per
exemple), variables (v_num per exemple) o expressions (com v_num+18). A
aquests paràmetres se’ls hi pot assignar un valor per defecte.
OUT. Relacionats amb el pas per variable d’altres llenguatges. Només poden
ser variables i no poden tenir un valor per defecte. S’utilitzen perquè el
procediment hi guardi algun valor. És a dir, els paràmetres OUT són variables
que s’envien al procediment de manera que si en el procediment canvia el seu
valor, aquest valor es manté quan el procediment acaba.
IN OUT. Són una combinació dels dos anteriors. Es tracta de variables on el
valor es pot utilitzar pel procediment que, a més a més, pot guardar-hi un
valor. No se’ls hi pot assignar un valor per defecte.
Si no s’especifica cap tipus de paràmetre sempre serà de tipus IN.
CREACIÓ DE PROCEDIMENTS
Els passos a seguir per crear procediments són:
Escriure el codi en un fitxer .sql des de qualsevol editor.
Carregar i compilar el codi mitjançant la línia de comandaments del SGBD (amb Oracle,
l’SQL*Plus).
Executar tants cops com sigui necessari el procediment creat. Amb SQL*Plus es fa
precedint el nom del procediment per la paraula EXECUTE.
24
UD3. SQL hostatjat SQL hostatjat
Exemple:
CREATE OR REPLACE PROCEDURE holaMon
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('HOLA MON’);
END holaMon;
/
Exemple:
CREATE OR REPLACE PROCEDURE consultarEmpleat
(v_Nom VARCHAR2, v_Num OUT NUMBER, v_ofici OUT VARCHAR2) IS
BEGIN
SELECT empl_num, empl_ofici INTO v_Num, v_ofici
FROM empl
WHERE empl_nom LIKE '%'||v_Nom||'%';
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No s’’han trobat dades');
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Hi ha més d’una fila amb aquestes dades’);
END;
1.8.3. Funcions
Les funcions són un tipus especial de procediments que serveixen per calcular un
determinat valor. Tot el que s’ha comentat en l’apartat anterior és vàlid per les funcions,
la diferència està amb que aquestes només retornen un valor.
25
UD3. SQL hostatjat SQL hostatjat
Sintaxi:
CREATE [OR REPLACE]
FUNCTION nom [(paràmetre1[,paràmetre2 [,...]])] RETURN
tipusDades
IS|AS
seccióDeDeclaracions
BEGIN
instruccions
[EXCEPTION
controlDeExcepcions]
END[nom];
Exemple:
CREATE OR REPLACE
FUNCTION salariMig RETURN NUMBER IS
v_salari NUMBER;
BEGIN
SELECT AVG(empl_salari) INTO v_salari
FROM empl;
RETURN v_salari;
END;
Aquesta funció retorna el salari mig dels empleats de la taula EMPL. Un cop compilada
la funció, es pot cridar des d’una instrucció SQL qualsevol.
Exemple:
SQL> SELECT empl_num, empl_nom, empl_salari
2 FROM empl
3 WHERE empl_salari < salariMig;
Cal tenir en compte que perquè les funcions es puguin cridar des d’SQL, han de complir
que :
Les funcions han d’estar emmagatzemades.
Només poden utilitzar paràmetres IN.
Els seus paràmetres han de ser de tipus compatibles amb el llenguatge SQL
(no pot haver-hi paràmetres amb tipus específics de PL/SQL, com BOOLEAN).
El tipus retornar ha de ser compatible amb SQL.
No hi pot haver instruccions DML.
Si una instrucció DML modifica una taula, en aquesta instrucció no es pot
cridar a una funció que faci consultes sobre la mateixa taula.
No es poden utilitzar instruccions de transaccions (COMMIT,ROLLBACK).
La funció no pot invocar una altra funció que se salti alguna de les regles
anteriors.
Exemple:
CREATE OR REPLACE
FUNCTION edat(v_data DATE) RETURN NUMBER IS
v_edat NUMBER;
BEGIN
v_edat := TRUNC((SYSDATE-v_data)/365);
RETURN v_edat;
END;
/
26
UD3. SQL hostatjat SQL hostatjat
27
UD3. SQL hostatjat SQL hostatjat avançat
2.2. Paquets
Un paquet és una secció on s’hi poden definir procediments, funcions, cursors, tipus i
variables.
Els paquets no es poden cridar, parametritzar o eniuar.
Sintaxi:
CREATE [OR REPLACE] PACKAGE nomPaquet AS|IS
especificació_procediement | especificació_funció |
declaració_variable |
defició_tipus | declaració_excepció | declaració_cursor
END nomPaquet;
On:
especificació_procediement | especificació_funció | … són els elements del
paquet i són els mateixos que hi pot haver dins el DECLARE d’un bloc anònim.
Hi ha una sèrie de regles sintàctiques per la capçalera d’un paquet:
Els elements del paquet poder aparèixer en qualsevol ordre. De totes formes, un objecte
s’ha de declarar abans de poder-lo utilitzar. Per exemple, si tenim un cursor que dins el
WHERE utilitza una variable, aquesta s’ha de declarar abans que el cursor.
No és necessari incloure tots els tipus d’elements. Un paquet pot contenir només
especificacions de procediments i funcions, per exemple, sense declarar cap excepció ni
cap tipus.
Les declaracions de procediments i funcions han de ser declaracions formals, a
diferencia de la secció declarativa d’un bloc, que pot contenir tant declaracions formals
com el codi de procediments i funcions del paquet que es troba en el cos.
28
UD3. SQL hostatjat SQL hostatjat avançat
Sintaxi:
CREATE [OR REPLACE] PACKAGE BODY nomPaquet AS | IS
declaracions | subprogrames PL/SQL
END nomPaquet;
Modularitat
Facilitat del disseny de l’aplicació
Informació oculta
Funcionalitat afegida
Millor rendiment
Sobrecàrrega
Exemple: Crear un paquet que tingui un procediment anomenat salutacio. Aquest paquet
es dirà imprimir i els scripts on es guardarà el codi són :
Capçalera
CREATE OR REPLACE PACKAGE imprimir AS
PROCEDURE salutacio;
END imprimir;
/
Cos
CREATE OR REPLACE PACKAGE BODY imprimir AS
PROCEDURE salutacio IS
BEGIN
DBMS_OUTPUT.PUT_LINE('HOLA MON!!');
END salutacio;
END imprimir;
/
2.3. Triggers
29
UD3. SQL hostatjat SQL hostatjat avançat
30
UD3. SQL hostatjat SQL hostatjat avançat
BEFORE. El codi del trigger s’executa just abans d’executar la instrucció DML
que ha provocat que s’activi el trigger.
AFTER. El codi del trigger s’executa just després d’executar la instrucció DML
que ha provocat que s’activi el trigger.
INSTEAD OF. El trigger substitueix a l’operació DML. S’utilitza per vistes que
no es poden modificar.
Exemple: En aquest exemple s’activa el trigger de la taula EMPL cada vegada que
s’executa un INSERT sobre la taula, i genera una excepció en el cas que s’intenti
insertar un nou registre fora del període establert (entre les 9h i les 13h).
CREATE OR REPLACE TRIGGER tr_ins_empl
BEFORE INSERT ON empl
BEGIN
IF(TO_CHAR(SYSDATE,'HH24') NOT IN ('9','10','11','12','13')) THEN
RAISE_APPLICATION_ERROR(-20001,'Nomes es poden ' ||
' afegir empleats entre les 9:00 i les 13:59.');
END IF;
END;
31
UD3. SQL hostatjat SQL hostatjat avançat
Sintaxi:
CREATE [OR REPLACE] TRIGGER nomTrigger
clausulaDeTemps event1 [OR event2[,...]] ON taula
[REFERENCING {OLD AS nomVell | NEW AS nomNou}]
FOR EACH ROW [WHEN condició]
BEGIN
cos
END;
Quan s’executen instruccions UPDATE, cal tenir en compte que es modifiquen valors
antics (OLD) per canviar-los per valors nous (NEW). Les paraules NEW i OLD permeten
accedir als valors nous i antics respectivament.
L’apartat REFERENCING de la creació de triggers, permet assignar noms a les paraules
NEW i OLD (a la pràctica no sol utilitzar). Així, NEW.NOM faria referència al nou nom que
s’assigna a una determinada taula i OLD.NOM al vell.
A l’apartat d’instruccions del trigger ( a partir del BEGIN ) cal posar el símbol “:” davant
de les paraules NEW i OLD (per tant, tindríem :new.nom i :old.nom).
Exemple: Imaginem que volem fer una auditoria (enregistrar el que passa) sobre una
taula d’empleats. Aquesta taula és EMPL i conté les dades dels empleats d’una
empresa. Volem emmagatzemar en una altra taula diferent els canvis del salari que es fa
sobre els empleats, per la qual cosa creem la següent taula:
CREATE TABLE empl_audit(
empl_num NUMBER, -- codi empleat
salari_vell NUMBER(11,2), -- salari vell
salari_nou NUMBER(11,2), -- salari nou
data TIMESTAMP, -- data modificacio
usuari VARCHAR2(50), -- usuari que modifica
PRIMARY KEY(data,usuari)
);
32
UD3. SQL hostatjat SQL hostatjat avançat
Com que volem que la taula d’auditoria s’actualitzi automàticament, creem el següent
trigger:
CREATE OR REPLACE TRIGGER tr_audit_empl
BEFORE UPDATE OF EMPL_SALARI ON EMPL
FOR EACH ROW WHEN (OLD.empl_salari <> NEW.empl_salari)
BEGIN
INSERT INTO EMPL_AUDIT
VALUES(:NEW.empl_num,:OLD.empl_salari,:NEW.empl_salari,SYSTIMESTAMP,USER);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(‘Error num. ‘|| SQLCODE);
DBMS_OUTPUT.PUT_LINE(‘Missatge error: ‘ || SQLERRM);
END;
Són paraules que s’utilitzen per determinar la instrucció que s’estava fent quan s’ha
activat el trigger. Això s’utilitza amb triggers que s’activen per varies operacions (utilitzant
INSERT OR UPDATE, per exemple). En aquest cas s’utilitzen sentències IF seguides de
INSERTING, UPDATING o DELETING; aquestes paraules tornaran TRUE si estava fent
aquella operació.
Exemple:
CREATE OR REPLACE TRIGGER trigger1
BEFORE INSERT OR DELETE OR UPDATE OF camp1 ON taula
FOR EACH ROW
BEGIN
IF DELETING THEN
....
ELSIF INSERTING THEN
....
ELSE -- estarà actualitzant, UPDATING
...
ENDIF
END;
Hi ha un tipus de trigger especial que s’anomena INSTEAD OF i que només s’utilitza amb
les vistes.
33
UD3. SQL hostatjat SQL hostatjat avançat
Exemple: Tenim una vista que mostra les dades d’empleats i del departament on estan
assignats.
CREATE VIEW empleats_i_departaments(num,nom,num_dept,departament) AS
SELECT empl_num, empl_nom, dept_num, dept_nom
FROM empl, dept
WHERE empl_dept_num = dept_num
ORDER BY empl_num;
indicant que aquesta operació no és vàlida en aquesta vista (ja que utilitza dues taules).
Aquesta situació la pot solucionar un trigger que insereixi primer a la taula de
departaments (només si no existeix a la taula DEPT) i llavors insereixi l’empleat.
Això ho permet fer un trigger INSTEAD OF, que substitueixi l’INSERT original pel que fa
el cos del trigger:
CREATE OR REPLACE TRIGGER trg_ins_empleats_i_departament
INSTEAD OF INSERT
ON empleats_i_departaments
DECLARE
nDepts NUMBER;
BEGIN
SELECT COUNT(*) INTO nDepts
FROM DEPT
WHERE dept_num = :NEW.num_dept;
IF nDepts=0 THEN
INSERT INTO DEPT(dept_num, dept_nom)
VALUES(:NEW.num_dept,:NEW.departament);
END IF;
INSERT INTO EMPL(empl_num,empl_nom,empl_dept_num)
VALUES(:NEW.num,:NEW.nom,:NEW.num_dept);
END;
Aquest trigger permet afegir a aquesta vista afegint els camps necessaris a les taules
relacionades a la vista. Es podria modificar el trigger per permetre actualitzar, eliminar o
esborrar dades directament des de la vista i així es podria utilitzar aquesta vista com si
fos una taula.
34
UD3. SQL hostatjat SQL hostatjat avançat
2.3.8. Exemples
Crear un trigger que controli que no es pugui inserir un departament sense indicar la
seva localització.
-- CREAR EL TRIGGER A NIVELL DE FILA (localitzacio NO NULL)
CREATE OR REPLACE TRIGGER trig_loc_no_nul
BEFORE INSERT ON DEPT
FOR EACH ROW
BEGIN
IF :NEW.dept_loc IS NULL THEN
RAISE_APPLICATION_ERROR (-20001,'ERROR: LOCALITZACIO DEL ' ||
' DEPARTAMENT TE VALOR NULL');
END IF;
END;
/
--MODIFICAR
UPDATE dept
SET dept_loc = UPPER(dept_loc);
--ESBORRAR
DELETE FROM dept
WHERE dept_num=90;
35
UD3. SQL hostatjat SQL hostatjat avançat
ESBORRAR TRIGGERS
DROP TRIGGER nomTrigger;
DESACTIVAR UN TRIGGER
ALTER TRIGGER nomTrigger DISABLE;
ACTIVAR UN TRIGGER
ALTER TRIGGER nomTrigger ENABLE;
36
Àlgebra relacional
Operacions de l’àlgebra relacional. Relació amb
les operacions SQL.
Contingut
Contingut
ii
UD4. Àlgebra relacional Introducció
Capítol 1. Introducció
Com ja s’ha comentat en l’apartat dedicat a les operacions del model relacional (UD1),
l’àlgebra relacional s’inspira en la teoria de conjunts per especificar consultes a una base
de dades relacional.
Per especificar una consulta amb àlgebra relacional, cal definir una o més passes que
serveixin per anar construint, mitjançant operacions de l’àlgebra relacional, una nova
relació que contingui les dades que responen a la consulta a partir de les relacions
emmagatzemades. Els llenguatges basats amb l’àlgebra relacional són procedimentals,
ja que les passes que formen la consulta descriuen un procediment.
La visió que es presenta aquí és la d’un llenguatge teòric i, per tant, s’inclouen només les
seves operacions fonamentals, i no les construccions que es podrien afegir a un
llenguatge comercial per facilitar tasques com per exemple l’ordre de presentació del
resultat, el càlcul de dades d’agregats, etc.
Una característica destacable de totes les operacions de l’àlgebra relacional és que tant
els operands com el resultat són relacions. Aquesta propietat s’anomena tancament
relacional.
Aquest fet té implicacions importants:
El resultat d’una operació pot actuar com operand d’una altra operació.
El resultat d’una operació complirà totes les característiques de les relacions.
3
UD4. Àlgebra relacional Operació auxiliar
2.1. Reanomenar
L’operació reanomenar, que indicarem amb el símbol :=, permet assignar un nom R a la
relació resultant d’una operació de l’àlgebra relacional, i s’escriu així:
R := E
On E és l’expressió d’una operació de l’àlgebra relacional.
Cada operació de l’àlgebra relacional dóna un noms per defecte als atributs de
l’esquema de la relació resultat. En alguns casos potser interessa canviar aquests noms
per defecte per uns altres. Per aquest motiu, amb l’opció reanomenar també podrem
canviar el nom dels atributs d’una relació.
Utilitzarem també l’operació reanomenar per canviar l’esquema d’una relació. Si una
relació té l’esquema S(B1,B2,...,Bn) i el volem canviar per R(A1,A2,...,An), ho
farem de la següent manera:
R(A1,A2,...,An) := S(B1,B2,...,Bn)
4
UD4. Àlgebra relacional Operacions primitives
3.1. Unió
Operació que, a partir de dues relacions, obté una nova relació formada per les tuples de
les dues relacions, sense repeticions.
La unió és una operació binària, i la unió de dues relacions r i s s’indica com a r ∪ s .
Per poder aplicar la unió a dues relacions, cal que les dues relacions siguin compatibles.
Direm que dues relacions r i s són relacions compatibles si:
Tenen el mateix grau.
Es pot establir una correspondència entre els atributs dels esquemes de relació R i de S
de tal manera que a cada atribut Ai de R li correspon un atribut Aj de S, de manera que
es compleixi que dom(Ai) = dom(Aj).
Exemple 1:
Suposem que tenim les següents relacions:
EMPLEAT_ADM
DNI nom cognom edifici despatx
40175678 Pere Pi ED1 120
40347890 Josep Pujol ED1 120
EMPLEAT_PROD
DNI nomEmpl cognomEmpl edificiEmpl despatxEmpl
40175678 Pere Pi ED1 120
77900707 Anna Puig ED2 120
41234567 Manel Amat ED1 213
77232144 Jordi Soler NUL NUL
88999210 Marta Roca NUL NUL
Si volem obtenir una relació EMPLEAT que contingui tots els empleats de l’empresa, cal
fer la unió de les relacions EMPLEAT_ADM i EMPLEAT_PROD de la següent forma:
EMPLEAT := EMPLEAT _ ADM ∪ EMPLEAT _ PROD
5
UD4. Àlgebra relacional Operacions primitives
Com es pot observar, s’ha agafat la convenció de que els atributs de la relació resultant
coincideixin amb els atributs de la relació que figura en primer lloc.
3.2. Diferència
La diferència és una operació que, a partir de dues relacions, obté una nova relació
formada per les tuples que estan a la primera relació i que no estan a la segona.
La diferència és una operació binària, i la diferència de dues relacions r i s s’indica com
a r −s .
Com en el cas de la unió i la intersecció, la diferència només es pot aplicar a relacions
que tinguin tuples similars. Per poder fer la diferència de dues relacions, cal que les
relacions siguin compatibles.
Els atributs de l’esquema de la relació resultant de R − S coincideixen amb els atributs
de l’esquema de la relació R.
La relació resultant r − s és el conjunt de tuples que pertanyen a la relació r, però no a
la relació s.
6
UD4. Àlgebra relacional Operacions primitives
Exemple 2:
Suposem que tenim les relacions de l’exemple 1. Si volem obtenir una relació
EMPLEAT_NOMES_ADM que contingui els empleats de l’empresa que treballen a
administració, però no a producció, farem la diferència de les relacions EMPLEAT_ADM i
EMPLEAT_PROD de la següent forma:
EMPLEAT _ NOMES _ ADM := EMPLEAT _ ADM − EMPLEAT _ PROD
La relació resultant serà la que es mostra a la taula següent:
EMPLEAT_NOMES_ADM
DNI nom cognom edificiEmpl despatxEmpl
40347890 Josep Pujol ED1 120
Com es pot observar, s’ha agafat la convenció de que els atributs de la relació resultant
coincideixin amb els atributs de la relació que figura en primer lloc.
El producte cartesià és una operació que, a partir de dues relacions, obté una nova
relació formada per totes les tuples que són el resultat de concatenar tuples de la
primera relació amb tuples de la segona.
El producte cartesià és una operació binària. Essent r i s dues relacions que compleixen
que els seus esquemes no tenen cap atribut comú, el producte cartesià de r i s s’indica
com a r × s .
Si es vol calcular el producte cartesià de dues relacions que tenen algun nom d’atribut
comú, només fa falta reanomenar abans els atributs necessaris en una de les dues
relacions.
Els atributs de l’esquema de la relació resultant de R × S són tots els atributs de R i tots
els atributs de S.
La relació resultant r × s és el conjunt de totes les tuples de la forma
<v1,v2,...,vn,w1,w2,...,wm> per les que es compleix que <v1,v2,...,vn> pertany
a la relació r i <w1,w2,...,wm> pertany a la relació s.
Gràficament, el producte cartesià es pot expressar de la següent manera:
a 1 a 1
b X 2 = a 2
c b 1
b 2
c 1
c 2
7
UD4. Àlgebra relacional Operacions primitives
Exemple 3:
Suposem que tenim la relació EMPLEAT_ADM i la següent relació:
DESPATX
edifici numDespatx superfície
ED1 120 10
ED1 230 20
Si volem fer el ED2 120 10 producte cartesià:
ED2 440 10
EMPL _ DESPATX := EMPLEAT _ ADM − DESPATX
El producte cartesià és una operació que rarament s’utilitza de manera explícita, ja que
el resultat que dóna no acostuma a ser útil per resoldre consultes habituals.
8
UD4. Àlgebra relacional Operacions primitives
3.4. Selecció
Es defineix l’operació de selecció σ sobre una relació r amb uns criteris de selecció c,
com l’obtenció de les tuples de r que compleixen els criteris indicats a c, donant com a
resultat la nova relació S. S’escriu de la següent manera:
s := σ < c > (r )
En els criteris c es poden utilitzar els operadors de comparació ≥, ≤, <, >, =, ≠ i els lògics
I, O i NO.
3.5. Projecció
Es defineix l’operació de projecció П sobre una relació r com l’obtenció d’una nova
π
relació s que té un subconjunt dels atributs de r. S’escriu de la següent manera:
s := < A 1, A 2 ,..., Ai > (r )
On A1,A2,...,Ai és un subconjunt dels atributs de l’esquema de relació R.
9
UD4. Àlgebra relacional Operacions primitives
10
UD4. Àlgebra relacional Operacions no primitives
4.1. Intersecció
La intersecció és una operació que, a partir de dues relacions, obté una nova relació
formada per les tuples que pertanyen a les dues relacions.
La intersecció és una operació binària, i la intersecció de dues relacions r i s s’indica
com a r ∩ s .
Com en el cas de la unió, la intersecció només es pot aplicar a relacions que tinguin
tuples similars. Per poder fer la intersecció de dues relacions, cal que les relacions siguin
compatibles.
Els atributs de l’esquema de la relació resultant de R ∩ S coincideixen amb els atributs de
l’esquema de la relació R.
La relació resultant r ∩ s és el conjunt de tuples que pertanyen a la relació r i a la
relació s.
Gràficament, la intersecció es pot expressar de la següent manera:
Exemple 6:
Suposem que tenim les relacions de l’exemple 1. Si volem obtenir una relació EMPLEAT
que contingui els empleats de l’empresa que treballen tant a administració com a
producció, farem la intersecció de les relacions EMPLEAT_ADM i EMPLEAT_PROD de
la següent forma:
EMPLEAT _ ADM _ PROD := EMPLEAT _ ADM ∩ EMPLEAT _ PROD
La relació resultant serà la que es mostra a la taula següent:
EMPLEAT_ADM_PROD
DNI nom cognom edificiEmpl despatxEmpl
40175678 Pere Pi ED1 120
Com es pot observar, s’ha agafat la convenció de que els atributs de la relació resultant
coincideixin amb els atributs de la relació que figura en primer lloc.
4.2. Combinació
11
UD4. Àlgebra relacional Operacions no primitives
És l’operació binària que permet seleccionar les tuples del producte cartesià entre dues
relacions r i S, les quals compleixen el/s criteri/s d’igualtat c en una o més parelles
d’atributs dels esquemes de relació de R i S. S’escriu de la següent manera:
t := rθ < c > s
π σ
Amb operacions fonamentals s’escriuria així:
t := rθ < c > s= (R ∪ S ) ( <c > (r × s))
Els atributs de la projecció poden ser de R i de S. Els criteris c de la selecció indiquen
quina és la condició.
ALUMNE3
DNI nom cog1 cog2 nomPob
46676676 Pere Pujol Oriol Olot
70765432 Marc Pi Ferrer Besalú
40404040 Mireia Vila Vila Riudaura
42345678 Anna Juncà Vilanova Olot
12
UD4. Àlgebra relacional Seqüències d’operacions de l’àlgebra relacional
En molts casos, per formular una consulta utilitzant els operadors de l’àlgebra relacional
és necessari utilitzar varies operacions, que s’apliquen en un cert ordre.
Per fer-ho, hi ha dues maneres:
Utilitzar una única expressió de l’àlgebra que inclogui totes les operacions amb els
parèntesis necessaris per indicar l’ordre d’aplicació.
Descomposar l’expressió en varis passos on cada pas apliqui una única operació i
obtingui una relació intermitja que es pugui utilitzar en els passos següents.
Exemples:
ALUMNE
DNI nom cog1 cog2 codPob
46676676 Pere Pujol Oriol 1
70765432 Marc Pi Ferrer 2
40404040 Mireia Vila Vila 3
42345678 Anna Juncà Vilanova 1
POBLACIO
codi nomPob
1 Olot
2 Besalú
3 Riudaura
Obtenir el codi de la 4 La
poblacions de les quals no
hi ha cap alumne: Canya
π
P := codi(POBLACIO )
Obtenir el codi de les poblacions
π
P _ ALUM := codPob (ALUMNE )
Obtenir el codi de població de cada alumne
RES := P − P _ ALUM
RES conté els codi de poblacions que no són els codis de poblacions que apareixen a la
relació P_ALUM.
13
UD4. Àlgebra relacional Seqüències d’operacions de l’àlgebra relacional
14
Annex I. SGBD
Oracle. Eines
Descripció del SGBDR Oracle i les eines que
permeten interactuar-hi.
Contingut
Contingut
i
Annex I. SGBD Oracle. Eines Notes prèvies
1.1. Simbologia
En aquest document s’utilitza una simbologia i formats específics per tal de simplificar-ne
la lectura i comprensió.
Quan es faci referència a la sintaxi d’alguna instrucció s’utilitzen els següents símbols:
[text], significa que el text és opcional.
{A|...|B}, significa alternativa, és a dir, que s’ha d’escollir una entre totes les opcions
que hi ha entre claus.
Text amb lletra Courier New: tot el text que forma part de la sintaxi d’alguna instrucció.
Text amb negreta: paraules clau que formen sempre part de la instrucció.
Text amb lletra Courier New i fons gris: indica una instrucció SQL.
2
Annex I. SGBD Oracle. Eines Oracle
Capítol 2. Oracle
2.1. Característiques
3
Annex I. SGBD Oracle. Eines Oracle
4
Annex I. SGBD Oracle. Eines Oracle
2.3. Seguretat
5
Annex I. SGBD Oracle. Eines SQL*Plus
Capítol 3. SQL*Plus
3.1. Introducció
SQL*Plus és una aplicació d’Oracle que reconeix i envia sentències SQL i PL/SQL
(extensió d’ SQL) al servidor Oracle perquè aquest els executi. Bàsicament, es tracta
d’un intèrpret SQL amb algunes opcions d’edició i formatació de resultats.
Quan un usuari escriu un comandament dins SQL*Plus, aquest comprova que estigui
ben escrita.
3.2. El buffer
Cada vegada que l’usuari introdueix una sentència SQL, aquesta es guarda a una part
de la memòria anomenada buffer SQL fins que s’entra una nova sentència SQL. Si la
sentència acaba amb punt i coma (;), s’executa immediatament. Un cop dins el buffer, la
sentència es pot editar i executar tantes vegades com es vulgui.
El comandament run (r) llista el contingut del buffer i, tot seguit, executa la sentència. El
comandament / executa la sentència del buffer, sense llistar-la abans.
El buffer guarda una única sentència SQL a la vegada, de tal manera que se sobreescriu
cada vegada que s’introdueix una nova sentència.
Cal saber distingir entre sentències SQL i comandes SQL*Plus. Per això es mostra la
següent taula comparativa:
SQL SQL*Plus
És un llenguatge per comunicar-se Reconeix les sentències SQL i les
amb el SGBDR i accedir a les envia al servidor
dades.
És un estàndard ANSI És propietat d’Oracle
Permet manipular dades i No permet la manipulació de valors
definicions d’objectes de la base de de la base de dades
dades
Les sentències SQL s’introdueixen Els comandaments SQL*Plus no es
en el buffer SQL en una o més guarden al buffer.
línies.
Utilitza un caràcter de fi per No necessita caràcter de fi.
executar les sentències
immediatament.
Les paraules clau no es poden Les paraules clau es poden abreujar
abreujar
6
Annex I. SGBD Oracle. Eines SQL*Plus
Executar sentències SQL per recuperar, modificar, afegir i eliminar dades de la base de
dades.
Formatar, fer càlculs, emmagatzemar i imprimir resultats de consulta en forma
d’informes.
Crear fitxers de comandes per guardar sentències SQL i poder-les utilitzar posteriorment.
Les comandes SQL*Plus es poden dividir en les següents categories:
Categoria Objectiu
Entorn Canviar el comportament general de les sentències SQL
per la sessió de treball.
Format Formatar resultats de consulta
Manipulació de Guardar, carregar i executar fitxers de comandes
fitxers
Execució Enviar sentències SQL del buffer SQL al servidor Oracle
Edició Modificar sentències SQL en el buffer
Interacció Crear i transferir variables a sentències SQL, imprimir
valors de variables i imprimir missatges per pantalla
Altres Connectar-se a la base de dades, manipular l’entorn
SQL*Plus i mostrar definicions de columna.
3.5. Connexió
SQL*Plus és una aplicació que es troba instal·lada a l’ordinador client (el que es
connecta amb el servidor Oracle). Però no n’hi ha prou amb que estigui instal·lada sinó
que també cal que estigui ben configurada.
La primera configuració que cal fer, és la del fitxer tnsnames.ora (que es troba dins el
subdirectori /network/admin, dins el directori d’instal·lació del client d’Oracle). En
aquest fitxer s’hi troba la informació de les diferents connexions a servidors Oracle que
es poden fer amb SQL*Plus.
Un exemple del contingut d’aquest fitxer és:
XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
BCOMAXE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oraserver)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
Contingut d’un fitxer tnsnames.ora
Com es pot observar, en aquest fitxer hi ha dues configuracions: XE i ORASI2. Aquests
són els noms de les connexions que es podran indicar des de SQL*Plus. Si ens hi fixem
podem veure com en el primer cas, la connexió es fa sobre la mateixa màquina on hi ha
SQL*Plus instal·lat (ja que la IP del HOST és 127.0.0.1). A més a més, s’indica que la
connexió s’estableix utilitzant el protocol TCP i pel port 1521 (que és el port per defecte
d’Oracle). El valor del port es pot canviar si la instal·lació en el port es fa en un de
7
Annex I. SGBD Oracle. Eines SQL*Plus
SQL>
Darrera aquest “prompt” podem escriure les instruccions SQL i/o SQL*Plus. Cal tenir en
compte que el símbol SQL> pot canviar per un símbol amb números 1, 2, 3, etc., la qual
cosa indica que la instrucció no ha acabat (possiblement falti el ; final) indicant la línia en
la que estem.
3.6. Comandes
Per veure l’estructura d’una taula amb SQL*Plus s’utilitza la comanda DESCRIBE. El
resultat d’executar aquesta comanda és que mostra els noms de columna i tipus de
dades de la taula. També mostra si la columna de la taula ha de tenir dades
obligatòriament o no.
Sintaxi:
DESC[RIBE] nomTaula
8
Annex I. SGBD Oracle. Eines SQL*Plus
La sentència guardada al buffer es pot editar utilitzant un senzill editor de línies, que té
les següents comandes:
Comanda Descripció
A[PPEND] text Afegeix text al final de la línia actual.
C[HANGE]/vella/nova Canvia el text vella per nova a la línia actual.
C[HANGE].vella.nova
C[HANGE]/text/ Suprimeix text de la línia actual.
C[HANGE].text.
CL[EAR] BUFF[ER] Esborra totes les línies del buffer.
CL[EAR] SCR[EEN] Neteja la pantalla
DEL Esborra la línia actual
DEL n Esborra la línia n
DEL m n Esborra des de la línia m fins la n, ambdues
incloses
I[NPUT] Insereix un número indefinit de línies.
I[NPUT] text Insereix una línia que conté text
L[IST] Mostra totes les línies del buffer
L[IST] n Mostra una línia (la indicada per n)
L[IST] n Mostra un rang de línies: de m a n, ambdues
incloses
R[UN] Mostra i executa la sentència actual del buffer
/ Executa sense mostrar la sentència actual del buffer
n Mostra la línia n del buffer
n text Substitueix la línia n per text
0 text Insereix una línia abans de la línia 1
9
Annex I. SGBD Oracle. Eines SQL*Plus
A tenir en compte:
Si es prem [INTRO] abans d’acabar una comanda SQL*Plus demanarà un número de
línia.
El buffer SQL s’acaba introduint un dels caràcters de fi (punt i coma o /) o prement
[INTRO] dues vegades.
Exemples:
SQL> LIST
1 SELECT dept_nom
2* FROM dept
Mostrar el buffer.
SQL> L
1* SELECT * FROM empl
Mostrar el buffer.
SQL> C/empl/dept
1* SELECT * FROM dept
Comanda Descripció
SAV[E] fitxer[.ext] Guarda el contingut actual del buffer SQL a un
[REP[LACE] APP[END]] fitxer. Es pot utilitzar APPEND per afegir a un
fitxer que ja existeix, o REPLACE per
sobreescriure un fitxer. L’extensió per defecte
del fitxer és .sql
GET fitxer[.ext] Carrega el contingut del fitxer nomFitxer al
buffer SQL.
STA[RT] fitxer[.ext] Executa un fitxer de comandes guardat
prèviament.
@nomFitxer Igual que START
ED[IT] Obre l’editor i guarda el contingut del buffer a
un fitxer anomenat afiedt.buf
ED[IT] [fitxer[.ext]] Obre l’editor per editar el contingut del fitxer
indicat
10
Annex I. SGBD Oracle. Eines SQL*Plus
Exemples:
SQL> L
1 SELECT empl_nom, empl_dir, empl_dept_num
2* FROM empl
SQL> SAVE laMevaConsulta
Creado file laMevaConsulta.sql
Executa les comandes del fitxer laMevaConsulta.sql. S’obté el mateix resultat amb
@laMevaConsulta
SQL> ED laMevaConsulta
Tot el que es mostri entre SPOOL i SPOOL OFF quedarà emmagatzemat al fitxer
fitxerSessio.
11
Annex I. SGBD Oracle. Eines SQL*Plus
RUN
---
R[UN]
Hi ha moltes més comandes que es poden consultar als manuals oficials d’Oracle.
SQL*Plus torna i formata les dades retornades per la sentència SQL per mostrar-les a
l’usuari per pantalla. El format com ho mostra de tipus llistat tabulat. Les comandes de
SQL*Plus que permeten formatar la sortida no es guarden al buffer i són efectives fins
que es canvien o es tanca la sessió de treball. Algunes d’aquestes comandes
s’estableixen mitjançant els paràmetres d’entorn.
Cada paràmetre d’entorn es guarda com una variable global i té un valor per defecte. La
comanda SET defineix els valors de varies variables SQL*Plus, les quals es poden veure
amb la comanda SHO[W].
A continuació es mostra com es poden configurar aquestes variables i el seu significat:
Variable Descripció
SET LINESIZE n Fixar el nombre màxim de caràcters per línia a
n (per defecte és 80)
SET PAGESIZE n Fixar el nombre de línies de la sortida abans de
començar una nova pàgina (per defecte és 14).
SET HEADING {ON|OFF} Activa i desactiva les capçaleres de columna
SET NULL “text” Indica quin text es mostra quan hi ha nuls (per
defecte no apareix cap text)
SET FEEDBACK Defineix el número mínim de files recuperades
{n|ON|OFF} per una consulta perquè mostri el missatge “n
files seleccionades” (per defecte és 6 i
ON)
SET PAUSE {ON|OFF} Controla el scroll (paginat) de la pantalla; amb
ON es fa una pausa abans de cada pàgina;
prement INTRO s’obté la següent pàgina.
Hi ha molts més paràmetres que es poden consultar als manuals oficials d’Oracle.
12
Annex I. SGBD Oracle. Eines SQL*Plus
Per no haver de configurar a cada inici de sessió els paràmetres d’entorn, hi ha dos
fitxers que poden ajudar a configurar automàticament aquests valors. Són els fitxers
glogin.sql i login.sql.
glogin.sql
Quan es carrega SQL*Plus, busca el fitxer glogin.sql dins el directori
$ORACLE_HOME/sqlplus/admin. Si el troba, el llegeix i executa les comandes que
conté. Això permet guardar els paràmetres d’entorn (com per exemple linesize) per totes
les sessions SQL*PLUS.
login.sql
Desprès de llegir el fitxer glogin.sql, SQL*Plus, busca el fitxer login.sql dins el directori on
s’ha iniciat el programa i també dins el directori indicat per la variable d’entorn del
sistema operatiu SQLPATH.
Cal tenir en compte que la configuració del fitxer login.sql té preferència sobre glogin.sql.
El que fa en aquest cas és canviar el símbol del “prompt” fent que mostri el nom d’usuari
seguit de “>”.
La taula DUAL és una taula creada automàticament per Oracle i és molt útil per fer consultes
amb constants.
La taula DUAL es troba a l’esquema de l’usuari SYS i és accessible per tots els usuaris.
Només té una columna, DUMMY, definida com a VARCHAR2(1), i conté una fila amb el
valor ’X’. Com que DUAL només té una fila, el valor constant és retornat només una
vegada. També es pot seleccionar una constant fent la selecció a qualsevol taula, però
en aquest cas el valor es retornarà tantes vegades com files tingui la taula.
Exemple:
SQL> SELECT 'hola, això és un exemple' AS MISSATGE
2 FROM dual;
MISSATGE
------------------------
hola, això és un exemple
Exemple:
SQL> SELECT 'hola, això és un exemple' AS MISSATGE
2 FROM dept;
MISSATGE
------------------------
Amb la taula dual també podem utilitzar funcions (que les veurem al següent apartat).
Exemple:
SQL> SELECT SYSDATE
2 FROM dual;
SYSDATE
--------
28/11/05
13
Annex I. SGBD Oracle. Eines SQL*Plus
14
Annex II. Dades de
treball
Dades de la base de dades de treball.
Annex II. Dades de treball Notes prèvies
Capítol 1. Simbologia
En aquest document s’utilitza una simbologia i formats específics per tal de simplificar-ne
la lectura i comprensió.
Quan es faci referència a la sintaxi d’alguna instrucció s’utilitzen els següents símbols:
[text], significa que el text és opcional.
|, significa alternativa.
Text amb lletra Courier New: tot el text que forma part de la sintaxi d’alguna instrucció.
Text amb negreta: paraules clau que formen sempre part de la instrucció.
Text amb lletra Courier New i fons gris: indica una instrucció SQL.
2
Capítol 2. Taules i dades d’exemple
En aquest document es mostren molts exemples de consultes sobre les següents taules:
DEPT
CAMP TIPUS RESTRICCIONS
dept_num number(2) primary key
dept_nom varchar2(14)
dept_loc varchar2(13)
EMPL
CAMP TIPUS RESTRICCIONS
empl_num number(4) primary key
empl_nom varchar2(16)
empl_ofici varchar2(10)
foreign key (a la taula
empl_dir number(4)
empl)
empl_datalt date
empl_salari number(11,2)
empl_comissio number(11,2)
MALALT foreign key (a la taula
empl_dept_num number(2)
CAMP TIPUS dept)
RESTRICCIONS
malalt_num number(5) primary key
malalt_nom varchar2(12)
malalt_adreca varchar2(20)
malalt_dnaixa date
malalt_sexe varchar2(1)
malalt_nss number(9)
HOSPITAL
CAMP TIPUS RESTRICCIONS
hospital_codi number(2) primary key
hospital_nom varchar2(12)
hospital_adreca varchar2(20)
hospital_telefon varchar2(8)
hospital_nllits number(4)
SALA
CAMP TIPUS RESTRICCIONS
sala_codi number(2) primary key
primary key, foreign
sala_hospital_codi number(2) key (a la taula
hospital)
sala_nom varchar2(20)
PLANTILLA
sala_nllits number(4)
CAMP TIPUS RESTRICCIONS
plantilla_empleat_num number(4) primary key
plantilla_hospital_codi number(2) foreign key (a la
plantilla_sala_codi number(2) taula sala)
plantilla_nom varchar2(16)
plantilla_funcio varchar2(10)
plantilla_torn varchar2(1)
plantilla_salari number(11,2)
DOCTOR
CAMP TIPUS RESTRICCIONS
doctor_codi number(3) primary key
foreign key (a la
doctor_hospital_codi number(2)
taula hospital)
doctor_nom varchar2(16)
doctor_especialitat varchar2(16)