Está en la página 1de 184

1 - 1 nstalación de Ora e l e .

Para este curso u t i l i z a r e m o s l a versión Oracle 1 Og XE (Express E d i t i o n para

W i n d o w s ) Para d e s c a r g a r el m i s m o d e b e m o s i n g r e s a r a l s i t i o d e O r a c l e :

1 . Oracle 1 Og XE

2. Para p e r m i t i r d e s c a r g a r l o d e l s i t i o s e l e c c i o n a m o s con el m o u s e el control R a d i o

"Accept L i c e n s e A g r e e m e n t " .

3. L u e g o s e l e c c i o n a m o s l a versión " O r a c l e Database 1 Og Express E d i t i o n

( U n i v e r s a l ) " ( O r a c l e X E U n i v . e x e ( 2 1 6 , 9 3 3 , 3 7 2 bytes))

4. E l s i t i o de Oracle r e q u i e r e q u e nos registremos. D e b e m o s s e l e c c i o n a r " s i g n u p

now" y l u e g o "Create y o u r Oracle a c c o u n t now", es d e c i r crear u n a cuenta

Oracle.

L u e g o de habernos registrado p o d e m o s d e s c a r g a r el motor d e base de datos

Ora e l e .

5. E l paso s i g u i e n t e es i n s t a l a r el gestor de base de datos p r o p i a m e n t e d i c h o .

Ejecutamos el a r c h i v o q u e a c a b a m o s de d e s c a r g a r : O r a c l e X E U n i v . e x e

D e b e m o s i r p r e s i o n a n d o el botón " s i g u i e n t e " e n el asistente de i n s t a l a c i ó n ,

salvo c u a n d o nos p i d e i n g r e s a r la contraseña de la base de d a t o s , es

i m p o rt a n t e no o l v i d a r d i c h a c l a v e .

L u e g o de a l g u n o s m i n u t o s ya t e n e m o s i n s t a l a d o el gestor de bases de datos

O r a c l e en nuestro e q u i p o .

La s e g u n d a a p l i c a c i ó n q u e i n s t a l a r e m o s será el " O r a c l e S Q L D e v e l o p e r " . Es u n

entorno v i s u a l q u e nos permite c o m u n i c a r con nuestro gestor de base de datos

O r a c l e . D e s d e este entorno a p r e n d e r e m o s a a d m i n i s t r a r u n a base d e datos O r a c l e .

1 . D e b e m o s i n g r e s a r a la s i g u i e n t e p á g i n a para descargar el Oracle S Q L

Developer

2. Aceptamos l a l i c e n c i a y s e l e c c i o n a m o s " O r a c l e S Q L D e v e l o p e r far Windows

( J D K 1 . 5 . 0 _ 0 6 is b u n d l e d i n t h i s z i p )

3. L u e g o de descargar el archivo procedemos a d e s c o m p r i m i r el a r c h i v o z i p en

u n a carpeta ( este programa no requiere i n s t a l a c i ó n )

4. E n l a carpeta d o n d e d e s c o m p r i m i m o s d e b e m o s ejecutar el archivo

sqldeveloper.exe
2 - Crear tablas (create t a b l e - describe -

all_tables - d r o p t a b l e )

Existen varios objetos de base de d a t o s : t a b l a s , constraints ( r e s t r i c c i o n e s ) , vistas,

s e c u e n c i a s , í n d i c e s , a g r u p a m i e n t o s ( clusters ) , d i s p a r a d o r e s (triggers ) , i n s t a n t a n e a s

( s n a p s h o t s ) , p r o c e d i m i e n t o s , f u n c i o n e s , p a q u e t e s , s i n ó n i m o s , u s u a r i o s , p e rf i l e s ,

p r i v i l e g i o s , r o l e s , etc.

Los p r i m e r o s objetos q u e veremos son t a b l a s .

U n a base d e datos a l m a c e n a su información en t a b l a s , q u e es la u n i d a d básica de

almacenamiento.

U n a t a b l a es u n a estructura de datos q u e organiza l o s datos e n c o l u m n a s y f i l a s ;

cada c o l u m n a es u n c a m p o (o a t r i b u t o ) y cada f i l a , u n registro. La intersección de u n a

c o l u m n a con u n a f i l a , c o n t i e n e u n dato específico, u n solo valor.

C a d a registro c o n t i e n e u n dato por cada c o l u m n a de la t a b l a . Cada c a m p o ( c o l u m n a )

d e b e t e n e r u n n o m b r e . E l n o m b r e d e l c a m p o hace referencia a la i n f o r m a c i ó n q u e

almacenará.

C a d a c a m p o ( c o l u m n a ) t a m b i é n d e b e d e f i n i r el t i p o de dato q u e a l m a c e n a r á .

Las t a b l a s forman parte de u n a base d e datos.

Nosotros trabajaremos con l a base de datos ya creada.

Para ver l a s t a b l a s existentes t i p e a m o s :

select *from all_tables;

Aparece u n a t a b l a q u e nos muestra en cada f i l a , los datos de u n a t a b l a específica; en

l a c o l u m n a "TABLE_NAME" aparece el n o m b r e de cada t a b l a existente.

Al crear u n a t a b l a d e b e m o s resolver q u é campos ( c o l u m n a s ) tendrá y q u e t i p o de

datos a l m a c e n a r á n cada u n o de e l l o s , es decir, su estructura.

La s i n t a x i s básica y g e n e r a l para crear u n a t a b l a es l a s i g u i e n t e :

create table NOMBRETABLA(

NOMBRECAMPOl TIPODEDATO,

NOMBRECAMPON TIPODEDATO

) ;

La t a b l a d e b e ser d e f i n i d a con u n n o m b r e q u e la i d e n t i f i q u e y con el c u a l

accederemos a e l l a .

C r e a m o s u n a t a b l a l l a m a d a " u s u a r i o s " y entre paréntesis d e f i n i m o s l o s c a m p o s y s u s

tipos:
create table usuarios(

nombre varchar2(30),

clave varchar2(10)

) ;

C a d a c a m p o con su t i p o d e b e separarse con comas de los s i g u i e n t e s , excepto el

último.

C u a n d o se crea u n a t a b l a d e b e m o s i n d i c a r s u n o m b r e y d e f i n i r a l m e n o s u n c a m p o

con su tipo de d a t o . E n esta t a b l a " u s u a r i o s " d e f i n i m o s 2 c a m p o s :

- n o m b r e : q u e contendrá u n a cadena de caracteres de 30 caracteres de l o n g i t u d , q u e

a l m a c e n a r á el n o m b r e de u s u a r i o y

- c l a v e : otra c a d e n a d e caracteres de 1 O de l o n g i t u d , q u e g u a r d a r á l a clave d e cada

usuario.

C a d a u s u a r i o o c u p a r á u n registro de esta t a b l a , con su respectivo n o m b r e y clave.

Para n o m b r e s d e t a b l a s , se p u e d e u t i l i z a r c u a l q u i e r caracter p e r m i t i d o para n o m b r e s

de directorios, e l p r i m e r o d e b e s e r u n caracter alfabético y no p u e d e contener

e s p a c i o s . La l o n g i t u d m á x i m a es de 30 caracteres.

S i i n t e n t a m o s crear u n a t a b l a con u n n o m b r e ya existente ( existe otra t a b l a con ese

n o m b r e ) , mostrará u n mensaje i n d i c a n d o q u e a tal n o m b r e ya l o está u t i l i z a n d o otro

objeto y l a s e n t e n c i a no se ejecutará.

Para ver l a estructura d e u n a t a b l a u s a m o s el c o m a n d o "describe" j u n t o a l n o m b r e d e

la tabla:

describe usuarios;

Aparece l a s i g u i e n t e i n f o r m a c i ó n :

Name Null Type

NOMBRE VARCHAR2(30)

CLAVE VARCHAR2(10)

Esta es l a estructura d e l a t a b l a " u s u a r i o s " ; n o s muestra cada c a m p o , su t i p o y

l o n g i t u d y otros valores q u e no a n a l i z a r e m o s por el m o m e n t o .

Para e l i m i n a r u n a t a b l a u s a m o s " d r o p t a b l e " j u n t o a l n o m b r e d e l a t a b l a a e l i m i n a r :

drop table NOMBRETABLA;

E n el s i g u i e n t e e j e m p l o e l i m i n a m o s l a t a b l a " u s u a r i o s " :

drop table usuarios;

S i i n t e n t a m o s e l i m i n a r u n a t a b l a q u e no existe, aparece u n mensaje de error

i n d i c a n d o tal s i t u a c i ó n y l a s e n t e n c i a n o se ejecuta.
3 - I n g r e s a r registros ( i n s e r t i n t o - se l e ct)

U n registro es u n a f i l a de l a t a b l a q u e c o n t i e n e l o s datos p r o p i a m e n t e d i c h o s . Cada

registro t i e n e u n dato por cada c o l u m n a ( c a m p o ) . Nuestra t a b l a " u s u a r i o s " consta d e

2 c a m p o s , " n o m b r e " y "clave".

Al i n g r e s a r l o s datos d e cada registro d e b e tenerse en cuenta l a c a n t i d a d y el o r d e n

de los c a m p o s .

La s i n t a x i s básica y g e n e r a l es la s i g u i e n t e :

insert into NOMBRETABLA {NOMBRECAMPOl, . . . , NOMBRECAMPOn)

values {VALORCAMPOl, . . . , VALORCAMPOn);

U s a m o s " i n s e rt i n t o " , l u e g o e l n o m b r e d e l a t a b l a , d e t a l l a m o s l o s n o m b r e s d e l o s

c a m p o s entre paréntesis y separados por comas y l u e g o de la c l á u s u l a " v a l u e s "

c o l o c a m o s l o s valores para cada c a m p o , t a m b i é n entre paréntesis y s e p a r a d o s por

comas.

E n el s i g u i e n t e e j e m p l o se agrega u n registro a la t a b l a " u s u a r i o s " , en el c a m p o

" n o m b r e " se a l m a c e n a r á " M a r i a n o " y e n el c a m p o " c l a v e " se g u a r d a r á " p a y a s o " :

insert into usuarios (nombre, clave)

values {'Mariano', 'payaso');

L u e g o de cada i n s e r c i ó n aparece u n mensaje i n d i c a n d o la cantidad de registros

ingresados.

Note q u e los datos i n g r e s a d o s , como corresponden a c a d e n a s de caracteres se

c o l o c a n entre c o m i l l a s s i m p l e s .

Para ver los registros d e u n a t a b l a u s a m o s " s e l e c t " :

select *from usuarios;

E l c o m a n d o "select" recupera los registros d e u n a t a b l a . Con el asterisco i n d i c a m o s

q u e muestre todos l o s c a m p o s de l a t a b l a " u s u a r i o s " .

Aparece l a t a b l a , s u s c a m p o s y registros i n g r e s a d o s ; si no t i e n e registros,

a p a r e c e r í a n s o l a m e n t e l o s c a m p o s y la t a b l a v a c í a ) .

Es i m p o rt a n t e i n g r e s a r l o s valores en el m i s m o orden en q u e se n o m b r a n l o s

c a m p o s : E n el s i g u i e n t e e j e m p l o se l i s t a p r i m e r o el c a m p o "clave" y l u e g o el c a m p o

" n o m b r e " por e s o , l o s v a l o r e s t a m b i é n se colocan en ese o r d e n :

insert into usuarios {clave, nombre)

values {'River', 'Juan');


S i i n g r e s a m o s los datos en u n orden d i s t i n t o a l orden en q u e se n o m b r a r o n los

c a m p o s , no aparece u n mensaje de error y los datos se g u a r d a n de m o d o incorrecto.

E n el s i g u i e n t e e j e m p l o se c o l o c a n l o s valores en d i s t i n t o orden en q u e se n o m b r a n

l o s c a m p o s , el v a l o r d e l a clave ( l a c a d e n a " B o c a " ) se g u a r d a r á e n el c a m p o

" n o m b r e " y el v a l o r d e l n o m b r e ( l a c a d e n a " L u i s " ) en el c a m p o " c l a v e " :

insert into usuarios (nombre,clave)

values ('Boca', 'Luis');


4 - Tipos de datos

Ya e x p l i c a m o s q u e a l crear u n a t a b l a d e b e m o s resolver q u é c a m p o s ( c o l u m n a s )

tendrá y q u e t i p o de datos a l m a c e n a r á cada u n o de e l l o s , es decir, su estructura.

E l t i p o de dato especifica el t i p o de información q u e p u e d e g u a r d a r u n c a m p o :

caracteres, n ú m e r o s , etc.

Estos son a l g u n o s t i p o s de datos básicos de Oracle (posteriormente veremos otros y

con m á s d e t a l l e ) :

• - v a r c h a r 2 : se e m p l e a para a l m a c e n a r c a d e n a s de caracteres. U n a c a d e n a es

u n a s e c u e n c i a de caracteres. Se coloca entre c o m i l l a s s i m p l e s ; e j e m p l o : ' H o l a ' ,

' J u a n Perez', ' C o l o n 1 2 3 ' . Este t i p o de dato d e f i n e n u n a c a d e n a d e l o n g i t u d

v a r i a b l e e n l a c u a l d e t e r m i n a m o s el m á x i m o de caracteres entre p a r é n t e s i s .

P u e d e g u a r d a r hasta xxx caracteres. P o r e j e m p l o , para a l m a c e n a r c a d e n a s de

hasta 30 caracteres, d e f i n i m o s u n c a m p o de t i p o varchar2 ( 3 0 ) , es decir, entre

paréntesis, j u n t o a l n o m b r e d e l c a m p o c o l o c a m o s la l o n g i t u d .

S i i n t e n t a m o s a l m a c e n a r u n a c a d e n a d e caracteres de mayor l o n g i t u d q u e la

d e f i n i d a , l a c a d e n a no se carga, aparece u n m e n s a j e i n d i c a n d o tal s i t u a c i ó n y l a

s e n t e n c i a no se ejecuta.

Por e j e m p l o , si d e f i n i m o s u n c a m p o de t i p o varchar(1 O ) e i n t e n t a m o s a l m a c e n a r

en él l a cadena ' B u e n a s tardes', aparece u n mensaje i n d i c a n d o q u e el v a l o r es

d e m a s i a d o g r a n d e para la c o l u m n a .

• - n u m b e r ( p , s ) : se usa para g u a r d a r valores n u m é r i c o s con d e c i m a l e s , de 1 . 0

x 1 0 - 1 2 0 a 9 . 9 . . . (38 p o s i c i o n e s ) . D e f i n i m o s c a m p o s de este t i p o c u a n d o

q u e r e m o s a l m a c e n a r valores n u m é r i c o s con l o s c u a l e s l u e g o realizaremos

o p e r a c i o n e s m a t e m á t i c a s , por e j e m p l o , c a n t i d a d e s , precios, etc.

P u e d e contener n ú m e r o s enteros o d e c i m a l e s , positivos o n e g a t i v o s . El

parámetro " p " i n d i c a l a p r e c i s i ó n , es decir, el n ú m e r o d e d í g i t o s e n total

( c o n t a n d o l o s d e c i m a l e s ) q u e contendrá el n ú m e r o como m á x i m o . El parámetro

"s" especifica l a e s c a l a , es d e c i r , el m á x i m o d e d í g i t o s d e c i m a l e s . P o r e j e m p l o ,

u n c a m p o d e f i n i d o " n u m b e r ( 5 , 2 ) " p u e d e c o n t e n e r c u a l q u i e r n ú m e r o entre 0 . 0 0 y

9 9 9 . 99 (positivo o n e g a t i v o ) .

Para especificar n ú m e r o enteros, p o d e m o s o m i t i r e l parámetro "s" o colocar el

v a l o r O como parámetro " s " . Se u t i l i z a como s e p a r a d o r e l p u n t o ( . ) .

S i i n t e n t a m o s a l m a c e n a r u n v a l o r mayor fuera d e l r a n g o p e r m i t i d o al d e f i n i r l o ,

tal v a l o r no se c a r g a , aparece u n mensaje i n d i c a n d o tal s i t u a c i ó n y l a s e n t e n c i a

no se ejecuta.

Por e j e m p l o , si d e f i n i m o s u n c a m p o de t i p o n u m b e r ( 4 , 2 ) e i n t e n t a m o s g u a r d a r el

v a l o r 1 2 3 . 4 5 , aparece u n mensaje i n d i c a n d o q u e el v a l o r es d e m a s i a d o g r a n d e

para l a c o l u m n a . S i i n g r e s a m o s u n v a l o r con m á s d e c i m a l e s q u e l o s d e f i n i d o s ,

el v a l o r se carga pero con la c a n t i d a d de d e c i m a l e s p e r m i t i d o s , l o s d í g i t o s

sobrantes se o m i t e n .
Antes de crear u n a t a b l a d e b e m o s p e n s a r en s u s c a m p o s y optar por el t i p o de dato

a d e c u a d o para cada u n o de e l l o s .

Por e j e m p l o , si en u n c a m p o a l m a c e n a r e m o s n ú m e r o s telefónicos o u n n ú m e r o s de

d o c u m e n t o , u s a m o s " v a r c h a r 2 " , no " n u m b e r " p o r q u e s i b i e n son d í g i t o s , con e l l o s no

r e a l i z a m o s o p e r a c i o n e s m a t e m á t i c a s . S i en u n c a m p o g u a r d a r e m o s a p e l l i d o s , y

s u p o n e m o s q u e n i n g ú n a p e l l i d o superará l o s 20 caracteres, d e f i n i m o s el c a m p o

" v a r c h a r 2 ( 2 0 ) " . S i en u n c a m p o a l m a c e n a r e m o s precios con d o s d e c i m a l e s q u e no

s u p e r a r á n l o s 9 9 9 . 9 9 pesos d e f i n i m o s u n c a m p o de t i p o " n u m b e r ( 5 , 2 ) " , es decir, 5

d í g i t o s en t o t a l , con 2 d e c i m a l e s . S i en u n c a m p o a l m a c e n a r e m o s valores enteros de

no más de 3 d í g i t o s , d e f i n i m o s u n c a m p o de t i p o " n u m b e r ( 3 , 0 ) " .


5 - Recuperar a l g u n o s c a m p o s (select)

H e m o s a p r e n d i d o cómo ver todos l o s registros de u n a t a b l a , e m p l e a n d o l a

instrucción "select".

La s i n t a x i s básica y g e n e r a l es la s i g u i e n t e :

select *from NOMBRETABLA;

E l asterisco ( * ) i n d i c a q u e se s e l e c c i o n a n todos los c a m p o s de l a t a b l a .

P o d e m o s especificar el n o m b r e de l o s c a m p o s q u e q u e r e m o s ver, s e p a r á n d o l o s p o r

comas:

select titulo,autor from libros;

La l i s t a de c a m p o s l u e g o d e l "select" s e l e c c i o n a los datos c o r r e s p o n d i e n t e s a los

c a m p o s n o m b r a d o s . E n el e j e m p l o a n t e r i o r s e l e c c i o n a m o s los c a m p o s " t i t u l o " y

"autor" de l a t a b l a " l i b r o s " , mostrando todos los registros.


6 - Recuperar a l g u n o s registros ( w h e r e )

H e m o s a p r e n d i d o a s e l e c c i o n a r a l g u n o s campos de u n a t a b l a .

También es p o s i b l e recuperar a l g u n o s registros.

Existe u n a c l á u s u l a , "where" con l a c u a l p o d e m o s e s p e c i f i c a r c o n d i c i o n e s para u n a

c o n s u l t a " s e l e c t " . Es decir, p o d e m o s recuperar a l g u n o s registros, s ó l o los q u e

c u m p l a n con c i e rt a s c o n d i c i o n e s i n d i c a d a s con la c l á u s u l a " w h e r e " . Por e j e m p l o ,

q u e r e m o s ver e l u s u a r i o cuyo n o m b r e es " M a r c e l o " , para e l l o u t i l i z a m o s "where" y

l u e g o de e l l a , l a c o n d i c i ó n :

select nombre, clave

from usuarios

where nombre='Marcelo';

La s i n t a x i s b á s i c a y g e n e r a l es la s i g u i e n t e :

select NOMBRECAMP01, . . . , NOMBRECAMPOn

from NOMBRETABLA

where CONDICION;

Para l a s c o n d i c i o n e s se u t i l i z a n operadores r e l a c i o n a l e s (tema q u e trataremos m á s

a d e l a n t e en d e t a l l e ) . E l s i g n o i g u a l ( = ) es u n operador r e l a c i o n a l . Para la s i g u i e n t e

s e l e c c i ó n d e registros especificamos u n a c o n d i c i ó n q u e s o l i c i t a l o s u s u a r i o s cuya

clave es i g u a l a " R i v e r " :

select nombre,clave

from usuarios

where clave='River';

S i n i n g ú n registro c u m p l e l a c o n d i c i ó n e s t a b l e c i d a con el "where", no aparecerá

n i n g ú n registro.

E n t o n c e s , con "where" e s t a b l e c e m o s c o n d i c i o n e s para recuperar a l g u n o s registros.

Para recuperar a l g u n o s c a m p o s de a l g u n o s registros c o m b i n a m o s en la c o n s u l t a la

lista d e c a m p o s y l a c l á u s u l a " w h e r e " :

select nombre

from usuarios

where clave='River';

E n l a c o n s u l t a a n t e r i o r s o l i c i t a m o s el n o m b r e de todos l o s u s u a r i o s cuya clave sea

i g u a l a "River".
7 - Operadores r e l a c i o n a l e s

Los operadores son s í m b o l o s q u e permiten r e a l i z a r o p e r a c i o n e s matemáticas,

c o n c a t e n a r c a d e n a s , hacer c o m p a r a c i o n e s .

O r a c l e reconoce de 4 t i p o s de o p e r a d o r e s :

1) relacionales (o de comparación)

2) aritméticos

3) de concatenación

4) lógicos

Por a h o r a veremos s o l a m e n t e los p r i m e r o s .

Los operadores r e l a c i o n a l e s ( o de c o m p a r a c i ó n ) nos permiten c o m p a r a r dos

expresiones, q u e p u e d e n ser v a r i a b l e s , valores de c a m p o s , etc.

H e m o s a p r e n d i d o a especificar c o n d i c i o n e s de i g u a l d a d para s e l e c c i o n a r registros d e

u n a t a b l a ; por e j e m p l o :

select *from libros

where autor='Borges';

U t i l i z a m o s el o p e r a d o r r e l a c i o n a l de i g u a l d a d .

Los operadores r e l a c i o n a l e s v i n c u l a n u n c a m p o con u n v a l o r para q u e Oracle

compare cada registro ( el c a m p o especificado) con el v a l o r d a d o .

Los operadores r e l a c i o n a l e s son los s i g u i e n t e s :

= igual

<> distinto

> mayor

< menor

>= mayor o igual

<= menor o igual

P o d e m o s s e l e c c i o n a r l o s registros cuyo a u t o r sea diferente de " B o r g e s " , para e l l o

usamos l a c o n d i c i ó n :

select * from libros

where autor<>'Borges';

P o d e m o s c o m p a r a r valores n u m é r i c o s . Por e j e m p l o , q u e r e m o s mostrar l o s t í t u l o s y

precios de l o s l i b r o s cuyo precio sea mayor a 20 pesos:


select titulo, precio

from libros

where precio>20;

Q u e r e m o s s e l e c c i o n a r los l i b r o s cuyo precio sea m e n o r o i g u a l a 3 0 :

select *from libros

where precio<=30;

Los operadores r e l a c i o n a l e s c o m p a r a n valores d e l m i s m o t i p o . Se e m p l e a n para

c o m p r o b a r si u n c a m p o c u m p l e con u n a c o n d i c i ó n .

N o son los ú n i c o s , existen otros q u e veremos mas a d e l a n t e .


8 - Borrar registros ( d e l e t e )

Para e l i m i n a r los registros d e u n a t a b l a u s a m o s el c o m a n d o " d e l e t e " .

Sintaxis básica:

delete from NOMBRETABLA;

Se coloca el c o m a n d o delete s e g u i d o de la p a l a b r a clave "from" y el n o m b r e d e l a

t a b l a de l a c u a l q u e r e m o s e l i m i n a r l o s registros. E n el s i g u i e n t e e j e m p l o se e l i m i n a n

l o s registros de l a t a b l a " u s u a r i o s " :

d e l e t e from u s u a r i o s ;

L u e g o , u n mensaje i n d i c a l a cantidad de registros q u e se h a n e l i m i n a d o .

S i no q u e r e m o s e l i m i n a r todos los registros, s i n o s o l a m e n t e a l g u n o s , d e b e m o s

i n d i c a r c u á l o c u á l e s ; para e l l o u t i l i z a m o s el c o m a n d o " d e l e t e " j u n t o con l a c l a u s u l a

"where" con l a c u a l establecemos l a c o n d i c i ó n q u e d e b e n c u m p l i r l o s registros a

borrar.

Por e j e m p l o , q u e r e m o s e l i m i n a r a q u e l registro cuyo n o m b r e de u s u a r i o es " M a r c e l o " :

delete from usuarios

where nombre='Marcelo';

S i s o l i c i t a m o s el borrado de u n registro q u e no existe, es decir, n i n g ú n registro

c u m p l e con l a c o n d i c i ó n e s p e c i f i c a d a , aparecerá u n m e n s a j e i n d i c a n d o q u e n i n g ú n

registro fue e l i m i n a d o , pues no encontró registros con ese dato.

Tenga en cuenta q u e si no c o l o c a m o s u n a c o n d i c i ó n , se e l i m i n a n todos los registros

de l a t a b l a e s p e c i f i c a d a .
9 - A c t u a l i z a r registros ( u p d a t e )

D e c i m o s q u e a c t u a l i z a m o s u n registro c u a n d o m o d i f i c a m o s a l g u n o de s u s valores.

Para m o d i f i c a r u n o o varios datos de u n o o varios registros u t i l i z a m o s " u p d a t e "

(actualizar).

Sintaxis básica:

update NOMBRETABLA set CAMPO=NUEVOVALOR;

U t i l i z a m o s " u p d a t e " j u n t o al n o m b r e d e l a t a b l a y "set" j u n t o con el c a m p o a m o d i f i c a r

y su nuevo valor.

E l c a m b i o afectará a todos l o s registros.

Por e j e m p l o , en nuestra t a b l a " u s u a r i o s " , q u e r e m o s c a m b i a r los v a l o r e s d e todas l a s

c l a v e s , por " R e a l M a d r i d " :

update usuarios set clave='RealMadrid';

P o d e m o s m o d i f i c a r a l g u n o s registros, para e l l o d e b e m o s establecer c o n d i c i o n e s de

s e l e c c i ó n con " w h e r e " .

Por e j e m p l o , q u e r e m o s c a m b i a r el v a l o r correspondiente a la clave de nuestro

u s u a r i o l l a m a d o " F e d e r i c o l o p e z " , q u e r e m o s como n u e v a clave " B o c a " , n e c e s i t a m o s

u n a c o n d i c i ó n "where" q u e afecte s o l a m e n t e a este registro:

update usuarios set clave='Boca'

where nombre='Federicolopez';

S i Oracle no e n c u e n t r a registros q u e c u m p l a n con l a c o n d i c i ó n d e l "where", u n

mensaje i n d i c a q u e n i n g ú n registro fue m o d i f i c a d o .

Las c o n d i c i o n e s no s o n o b l i g a t o r i a s , pero si o m i t i m o s la c l á u s u l a " w h e r e " , l a

a c t u a l i z a c i ó n afectará a todos l o s registros.

También p o d e m o s a c t u a l i z a r varios c a m p o s en u n a s o l a i n s t r u c c i ó n :

update usuarios set nombre='Marceloduarte', clave='Marce'

where nombre='Marcelo';

Para e l l o c o l o c a m o s " u p d a t e " , el n o m b r e d e l a t a b l a , "set" j u n t o al n o m b r e d e l c a m p o

y el n u e v o v a l o r y separado por c o m a , el otro n o m b r e d e l c a m p o con su nuevo valor.


1 O - Comentarios

Para a c l a r a r a l g u n a s i n s t r u c c i o n e s , en o c a s i o n e s , necesitamos agregar c o m e n t a r i o s .

Es p o s i b l e i n g r e s a r c o m e n t a r i o s en l a I ínea de c o m a n d o s , es decir, u n texto q u e no

se ejecuta; para e l l o se e m p l e a n dos g u i o n e s ( - - ) :

select *from libros;--mostramos los registros de libros

en l a l í n e a anterior, todo lo q u e está l u e g o d e los g u i o n e s ( h a c i a la d e r e c h a ) no se

ejecuta.

Para a g r e g a r v a r i a s I íneas d e c o m e n t a r i o s , se coloca u n a barra s e g u i d a de u n

asterisco (/*) a l c o m i e n z o d e l b l o q u e d e c o m e n t a r i o y a l f i n a l i z a r l o , u n asterisco

s e g u i d o de u n a barra (*/)

select titulo, autor

/*mostramos títulos y

nombres de los autores*/

from libros;

todo l o q u e está entre los s í m b o l o s " / * " y " * / " no se ejecuta.


1 1 - Valores n u l o s ( n u l l )

" n u l l ' s i g n i f i c a "dato d e s c o n o c i d o " o " v a l o r i n e x i s t e n t e " .

A veces, p u e d e desconocerse o no existir el dato c o r r e s p o n d i e n t e a a l g ú n c a m p o d e

u n registro. E n estos casos d e c i m o s q u e el c a m p o p u e d e contener valores n u l o s .

Por e j e m p l o , en nuestra t a b l a de l i b r o s , p o d e m o s t e n e r valores n u l o s en el c a m p o

" p r e c i o " p o r q u e es p o s i b l e q u e para a l g u n o s l i b r o s no l e h a y a m o s e s t a b l e c i d o el

precio para l a venta.

E n c o n t r a p o s i c i ó n , t e n e m o s c a m p o s q u e no p u e d e n estar vacíos j a m á s .

Veamos u n e j e m p l o . Tenemos nuestra t a b l a " l i b r o s " . E l c a m p o " t i t u l o " no d e b e r í a

estar vacío n u n c a , i g u a l m e n t e el c a m p o " a u t o r " . Para e l l o , a l crear l a t a b l a , d e b e m o s

especificar q u e t a l e s c a m p o s no a d m i t a n valores n u l o s :

create table libros(

titulo varchar2(30) not null,

autor varchar2(20) not null,

editorial varchar2(15) null,

precio number(S,2)

) ;

Para especificar q u e u n c a m p o N O a d m i t a valores n u l o s , d e b e m o s colocar " n o t n u l l "

l u e g o de l a d e f i n i c i ó n d e l c a m p o .

E n el e j e m p l o anterior, l o s c a m p o s " e d i t o r i a l " y " p r e c i o " si a d m i t e n valores n u l o s .

C u a n d o c o l o c a m o s " n u l l " estamos d i c i e n d o q u e a d m i t e valores n u l o s (caso d e l

c a m p o " e d i t o r i a l " ) ; por defecto, es d e c i r , si no l o a c l a r a m o s , los c a m p o s p e r m i t e n

valores n u l o s ( caso d e l c a m p o " p r e c i o " ) .

C u a l q u i e r c a m p o , de c u a l q u i e r tipo de dato permite ser d e f i n i d o para aceptar o no

valores n u l o s . U n v a l o r " n u l l " N O es l o m i s m o q u e u n v a l o r O (cero) o u n a c a d e n a d e

e s p a c i o s en b l a n c o (" " ) .

S i i n g r e s a m o s los datos de u n l i b r o , para el c u a l a ú n no h e m o s d e f i n i d o el precio

p o d e m o s c o l o c a r " n u l l " para mostrar q u e no t i e n e p r e c i o :

insert into libros (titulo,autor,editorial,precio)

values('El aleph', 'Borges', 'Emece',null);

Note q u e el v a l o r " n u l l " no es u n a c a d e n a d e caracteres, N O se coloca entre c o m i l l a s .

E n t o n c e s , si u n c a m p o acepta valores n u l o s , p o d e m o s i n g r e s a r " n u l l " c u a n d o no

conocemos el valor.
También p o d e m o s colocar " n u l l " e n el c a m p o " e d i t o r i a l " si d e s c o n o c e m o s el n o m b r e

de l a e d i t o r i a l a l a c u a l pertenece el l i b r o q u e vamos a i n g r e s a r :

insert into libros (titulo,autor,editorial,precio)

values('Alicia en el p a i s ' , 'Lewis Carroll',null,25);

U n a c a d e n a vacía es interpretada por Oracle como v a l o r n u l o ; por lo tanto, si

i n g r e s a m o s u n a c a d e n a v a c í a , se a l m a c e n a el v a l o r " n u l l " .

S i i n t e n t a m o s i n g r e s a r el v a l o r " n u l l " (o u n a c a d e n a vacía) e n c a m p o s q u e no a d m i t e n

valores n u l o s ( como " t i t u l o " o " a u t o r " ) , Oracle no lo p e r m i t e , muestra u n mensaje y la

i n s e r c i ó n no se r e a l i z a ; por e j e m p l o :

insert into libros (titulo,autor,editorial,precio)

values(null, 'Borges', 'Siglo XXI',25);

C u a n d o vemos l a estructura de u n a t a b l a con " d e s c r i b e " , e n l a c o l u m n a " N u l l " ,

aparece " N O T N U L L " si el c a m p o no a d m i t e valores n u l o s y no aparece en caso q u e

si los p e r m i t a .

Para recuperar l o s registros q u e c o n t e n g a n el v a l o r " n u l l " e n a l g ú n c a m p o , no

p o d e m o s u t i l i z a r l o s operadores r e l a c i o n a l e s vistos a n t e r i o r m e n t e : = ( i g u a l ) y <>

( d i s t i n t o ) ; d e b e m o s u t i l i z a r l o s operadores " i s n u l l " (es i g u a l a n u l l ) y " i s not n u l l " ( n o

es n u l l ) .

Los valores n u l o s no se m u e s t r a n , aparece el c a m p o vacío.

E n t o n c e s , para q u e u n c a m p o no permita valores n u l o s d e b e m o s especificarlo l u e g o

de d e f i n i r el c a m p o , a g r e g a n d o " n o t n u l l " . Por defecto, l o s c a m p o s p e r m i t e n v a l o r e s

n u l o s , pero p o d e m o s especificarlo i g u a l m e n t e a g r e g a n d o " n u l l " .


1 2 - Operadores r e l a c i o n a l e s ( i s n u l l )

Para recuperar l o s registros q u e c o n t e n g a n el v a l o r " n u l l " e n a l g ú n c a m p o , no

p o d e m o s u t i l i z a r l o s operadores r e l a c i o n a l e s vistos a n t e r i o r m e n t e : = ( i g u a l ) y < >

( d i s t i n t o ) ; d e b e m o s u t i l i z a r l o s operadores " i s n u l l " (es i g u a l a n u l l ) y " i s not n u l l " ( n o

es n u l l ) .

C o n l a s i g u i e n t e s e n t e n c i a recuperamos l o s l i b r o s q u e c o n t i e n e n v a l o r n u l o e n el

campo "editorial":

select *from libros

where editorial is null;

Recuerde q u e los v a l o r e s n u l o s no se m u e s t r a n , aparece el c a m p o v a c í o .

Las s i g u i e n t e s s e n t e n c i a s t e n d r á n u n a s a l i d a diferente:

select *from libros where editorial is null;


1 •

select *from libros where editorial=' ,

C o n l a p r i m e r a s e n t e n c i a veremos l o s l i b r o s cuya e d i t o r i a l a l m a c e n a el v a l o r " n u l l "

( d e s c o n o c i d o ) ; con l a s e g u n d a , los l i b r o s cuya e d i t o r i a l g u a r d a u n a c a d e n a d e 3

e s p a c i o s en b l a n c o .

Para obtener l o s registros q u e no c o n t i e n e n " n u l l " , se p u e d e e m p l e a r " i s not n u l l " ,

esto mostrará los registros con valores c o n o c i d o s .

Para ver los l i b r o s q u e N O t i e n e n v a l o r " n u l l " en el c a m p o " p r e c i o " t i p e a m o s :

select *from libros where precio is not null;


1 3 - Clave p r i m a r i a ( p r i m a r y key)

U n a c l a v e p r i m a r i a es u n c a m p o (o v a r i o s ) q u e identifica u n s o l o registro (fila) en u n a

tabla.

Para u n v a l o r d e l c a m p o clave existe s o l a m e n t e u n registro.

Veamos u n e j e m p l o , si t e n e m o s u n a t a b l a con datos de p e r s o n a s , el n ú m e r o d e

d o c u m e n t o p u e d e establecerse como clave p r i m a r i a , es u n v a l o r q u e no se r e p i t e ;

p u e d e h a b e r personas con i g u a l a p e l l i d o y n o m b r e , i n c l u s o el m i s m o d o m i c i l i o (padre

e hijo por e j e m p l o ) , pero su d o c u m e n t o será s i e m p r e d i s t i n t o .

S i t e n e m o s l a t a b l a " u s u a r i o s " , el n o m b r e d e cada u s u a r i o p u e d e establecerse como

c l a v e p r i m a r i a , es u n v a l o r q u e no se repite; p u e d e h a b e r u s u a r i o s con i g u a l clave,

pero su n o m b r e de u s u a r i o será s i e m p r e diferente.

P o d e m o s establecer q u e u n c a m p o sea clave p r i m a r i a al m o m e n t o de crear la t a b l a o

l u e g o q u e ha s i d o c r e a d a . Vamos a a p r e n d e r a e s t a b l e c e r l a al crear l a t a b l a . N o

existe u n a ú n i c a m a n e r a d e h a c e r l o , p o r a h o r a veremos l a s i n t a x i s m á s s e n c i l l a .

Tenemos nuestra t a b l a " u s u a r i o s " d e f i n i d a con 2 campos ( " n o m b r e " y " c l a v e " ) .

La s i n t a x i s básica y g e n e r a l es la s i g u i e n t e :

create table NOMBRETABLA(

CAMPO TIPO,

. . . ,

CAMPO TIPO,

PRIMARY KEY (CAMPO)

) ;

Lo q u e hacemos agregar, l u e g o de la d e f i n i c i ó n d e cada c a m p o , " p r i m a ry key" y entre

p a r é n t e s i s , el n o m b r e d e l c a m p o q u e será clave p r i m a r i a .

E n el s i g u i e n t e e j e m p l o d e f i n i m o s u n a clave p r i m a r i a , para nuestra t a b l a " u s u a r i o s "

para a s e g u r a r n o s q u e cada u s u a r i o tendrá u n n o m b r e diferente y ú n i c o :

create table usuarios(

nombre varchar2(20),

clave varchar2(10),

primary key(nombre)

) ;

U n a t a b l a s ó l o p u e d e t e n e r u n a clave p r i m a r i a . C u a l q u i e r c a m p o ( de c u a l q u i e r t i p o )

p u e d e s e r clave p r i m a r i a , d e b e c u m p l i r como r e q u i s i t o , q u e s u s valores no se repitan

n i s e a n n u l o s . P o r e l l o , a l d e f i n i r u n c a m p o como clave p r i m a r i a , a u t o m á t i c a m e n t e

O r a c l e l o c o n v i e rt e a "not n u l l " .
L u e g o de h a b e r e s t a b l e c i d o u n c a m p o como clave p r i m a r i a , al i n g r e s a r los registros,

O r a c l e controla q u e los valores para el c a m p o e s t a b l e c i d o como clave p r i m a r i a no

estén repetidos en l a t a b l a ; si estuviesen r e p e t i d o s , muestra u n mensaje y la

i n s e r c i ó n no se r e a l i z a . Es decir, si en nuestra t a b l a " u s u a r i o s " ya existe u n u s u a r i o

con n o m b r e " j u a n p e r e z " e i n t e n t a m o s i n g r e s a r u n n u e v o u s u a r i o con n o m b r e

" j u a n p e r e z " , aparece u n m e n s a j e y l a i n s t r u c c i ó n " i n s e rt " no se ejecuta.

I g u a l m e n t e , si r e a l i z a m o s u n a a c t u a l i z a c i ó n , Oracle controla q u e l o s valores para el

c a m p o e s t a b l e c i d o como clave p r i m a r i a no estén repetidos en l a t a b l a , s i l o

estuviese, aparece u n mensaje i n d i c a n d o q u e se v i o l a la clave p r i m a r i a y l a

a c t u a l i z a c i ó n no se r e a l i z a .

P o d e m o s ver e l c a m p o e s t a b l e c i d o como clave p r i m a r i a de u n a t a b l a r e a l i z a n d o la

siguiente consulta:

select uc.table_name, column_name from user_cons_columns ucc

join user_constraints uc

on ucc.constraint name=uc.constraint name

where uc.constraint_type='P' and

uc.table_name='USUARIOS';

N o e x p l i c a r e m o s l a c o n s u l t a a n t e r i o r por el m o m e n t o , s ó l o l a ejecutaremos; si la

c o n s u l t a retorna u n a t a b l a vacía, s i g n i f i c a q u e l a t a b l a especificada no t i e n e clave

p r i m a r i a . E l n o m b r e d e l a t a b l a D E B E i r en m a y ú s c u l a s , s i n o Oracle no la encontrará.
1 4 - Vaciar la t a b l a (truncate t a b l e )

A p r e n d i m o s q u e para borrar todos l o s registro de u n a t a b l a se usa "delete" s i n

condición "where".

También p o d e m o s e l i m i n a r todos los registros de u n a t a b l a con "truncate t a b l e " .

Sintaxis:

truncate table NOMBRETABLA;

Por e j e m p l o , q u e r e m o s v a c i a r l a t a b l a " l i b r o s " , u s a m o s :

truncate table libros;

La s e n t e n c i a "truncate t a b l e " vacía l a t a b l a ( e l i m i n a todos los registros) y conserva l a

estructura d e l a t a b l a .

La diferencia con " d r o p t a b l e " es q u e esta s e n t e n c i a e l i m i n a l a t a b l a , n o s o l a m e n t e

l o s registros, "truncate t a b l e " l a vacía d e registros.

La diferencia con " d e l e t e " es l a s i g u i e n t e , a l e m p l e a r " d e l e t e " , Oracle g u a r d a u n a

c o p i a de los registros borrados y son r e c u p e r a b l e s , con "truncate t a b l e " no es p o s i b l e

l a r e c u p e r a c i ó n p o r q u e se l i b e r a todo el e s p a c i o en d i s c o o c u p a d o por la t a b l a ; por lo

tanto, "truncate t a b l e " es m á s r á p i d o q u e " d e l e t e " (se nota c u a n d o l a cantidad de

registros es m u y g r a n d e ) .
1 5 - Tipos de datos a l f a n u m é r i c o s

Ya e x p l i c a m o s q u e a l crear u n a t a b l a d e b e m o s e l e g i r l a estructura a d e c u a d a , esto e s ,

d e f i n i r l o s campos y s u s tipos más p r e c i s o s , s e g ú n el caso.

Para a l m a c e n a r valores a l f a n u m é r i c o s (texto) u s a m o s cadenas de caracteres.

Las c a d e n a s se c o l o c a n entre c o m i l l a s s i m p l e s .

P o d e m o s a l m a c e n a r letras, s í m b o l o s y d í g i t o s con l o s q u e no se r e a l i z a n

o p e r a c i o n e s m a t e m á t i c a s , por e j e m p l o , c ó d i g o s de i d e n t i f i c a c i ó n , n ú m e r o s de

d o c u m e n t o s , n ú m e r o s telefónicos. Tenemos l o s s i g u i e n t e s t i p o s :

1 ) c h a r ( x ) : d e f i n e u n a c a d e n a de caracteres de l o n g i t u d fija d e t e r m i n a d a por el

a r g u m e n t o "x". S i se o m i t e e l a r g u m e n t o , por defecto coloca 1 . "char" v i e n e de

character, q u e s i g n i f i c a caracter en i n g l é s . Su rango es de 1 a 2000 caracteres.

Q u e sea u n a c a d e n a de l o n g i t u d fija s i g n i f i c a q u e , si d e f i n i m o s u n c a m p o como

" c h a r ( 1 O)" y a l m a c e n a m o s el v a l o r " h o l a " (4 caracteres), Oracle r e l l e n a r á l a s 6

p o s i c i o n e s restantes con e s p a c i o s , es decir, ocupará l a s 1 O p o s i c i o n e s ; por lo tanto,

si l a l o n g i t u d es i n v a r i a b l e , es c o n v e n i e n t e u t i l i z a r el t i p o c h a r ; caso contrario, el t i p o

varchar2.

S i a l m a c e n a m o s " h o l a " en u n c a m p o d e f i n i d o " c h a r ( 1 O ) " Oracle a l m a c e n a r á " h o l a " .

2 ) v a r c h a r 2 ( x ) : a l m a c e n a c a d e n a s de caracteres d e l o n g i t u d v a r i a b l e d e t e r m i n a d a por

el a r g u m e n t o "x" ( o b l i g a t o r i o ) . Q u e sea u n a c a d e n a d e l o n g i t u d v a r i a b l e s i g n i f i c a q u e ,

si d e f i n i m o s u n c a m p o como " v a r c h a r 2 ( 1 O)" y a l m a c e n a m o s el v a l o r " h o l a " (4

caracteres), Oracle s o l a m e n t e o c u p a l a s 4 p o s i c i o n e s (4 bytes y no 1 O como en el

caso d e " c h a r " ) ; por lo tanto, si l a l o n g i t u d es v a r i a b l e , es c o n v e n i e n t e u t i l i z a r este

t i p o d e dato y no " c h a r " , a s í o c u p a m o s m e n o s e s p a c i o d e a l m a c e n a m i e n t o e n d i s c o .

S u r a n g o es de 1 a 4000 caracteres.

3 ) n c h a r ( x ) : es s i m i l a r a "char" excepto q u e p e r m i t e a l m a c e n a r caracteres A S C I 1 ,

E B C D I C y U n i c o d e ; su rango va d e 1 a 1 0 0 0 caracteres porque se e m p l e a n 2 bytes

por cada caracter.

4 ) nvarchar2(x): es s i m i l a r a "varchar2", excepto q u e p e r m i t e a l m a c e n a r caracteres

U n i c o d e ; su rango va de 1 a 2000 caracteres porque se e m p l e a n 2 bytes por cada

caracter.

5 y 6 ) varchar(x) y c h a r 2 ( x ) : d i s p o n i b l e s en O r a c l e 8 .

7 ) l o n g : g u a r d a caracteres d e l o n g i t u d v a r i a b l e ; p u e d e c o n t e n e r hasta 2 0 0 0 0 0 0 0 0 0

caracteres (2 G b ) . N o a d m i t e a r g u m e n t o para especificar su l o n g i t u d . E n Oracle8 y

s i g u i e n t e s versiones c o n v i e n e e m p l e a r " c l o b " y " n l o b " para a l m a c e n a r g r a n d e s

c a n t i d a d e s de datos a l f a n u m é r i c o s .
E n g e n e r a l se u s a r á n l o s 2 p r i m e r o s .

S i i n t e n t a m o s a l m a c e n a r en u n c a m p o a l f a n u m é r i c o u n a c a d e n a de caracteres de

mayor l o n g i t u d q u e l a d e f i n i d a , aparece u n mensaje i n d i c a n d o q u e el v a l o r es

d e m a s i a d o g r a n d e y l a s e n t e n c i a no se ejecuta.

Por e j e m p l o , si d e f i n i m o s u n c a m p o de t i p o v a r c h a r 2 ( 1 O ) y l e a s i g n a m o s la cadena

'Aprenda P H P ' ( 1 1 caracteres), aparece u n mensaje y la s e n t e n c i a no se ejecuta.

S i i n g r e s a m o s u n v a l o r n u m é r i c o ( o m i t i e n d o l a s c o m i l l a s ) , l o convierte a cadena y l o

i n g r e s a como t a l .

Por e j e m p l o , si en u n c a m p o d e f i n i d o como v a r c h a r 2 ( 5 ) i n g r e s a m o s el v a l o r 1 2 3 4 5 , lo

toma como si h u b i é s e m o s t i p e a d o ' 1 2 3 4 5 ' , i g u a l m e n t e , si i n g r e s a m o s el v a l o r 2 3 . 5 6 ,

l o c o n v i e rt e a ' 2 3 . 5 6 ' . S i el v a l o r n u m é r i c o , a l s e r convertido a c a d e n a s u p e r a l a

l o n g i t u d d e f i n i d a , aparece u n mensaje de error y la s e n t e n c i a no se ejecuta.

Es i m p o rt a n t e e l e g i r el t i p o d e dato a d e c u a d o s e g ú n el caso.

Para a l m a c e n a r c a d e n a s q u e varían en su l o n g i t u d , es decir, no todos los registros

t e n d r á n l a m i s m a l o n g i t u d en u n c a m p o d e t e r m i n a d o , se e m p l e a "varchar2" e n l u g a r

de " c h a r " .

Por e j e m p l o , en c a m p o s q u e g u a r d a m o s n o m b r e s y a p e l l i d o s , no todos los n o m b r e s

y apellidos tienen la misma longitud.

Para a l m a c e n a r c a d e n a s q u e no varían en su l o n g i t u d , es decir, todos los registros

t e n d r á n l a m i s m a l o n g i t u d en u n c a m p o d e t e r m i n a d o , se e m p l e a " c h a r " .

Por e j e m p l o , d e f i n i m o s u n c a m p o " c o d i g o " q u e constará de 5 caracteres, todos los

registros t e n d r á n u n c ó d i g o de 5 caracteres, n i más n i m e n o s .

Para a l m a c e n a r valores s u p e r i o r e s a 4000 caracteres se d e b e e m p l e a r " l o n g " .


1 6 - Tipos de datos n u m é r i c o s

Ya e x p l i c a m o s q u e a l crear u n a t a b l a d e b e m o s e l e g i r l a estructura a d e c u a d a , esto e s ,

d e f i n i r l o s campos y s u s tipos más p r e c i s o s , s e g ú n el caso.

Los valores n u m é r i c o s no se i n g r e s a n entre c o m i l l a s . Se u t i l i z a el p u n t o como

s e p a r a d o r de d e c i m a l e s .

Para a l m a c e n a r v a l o r e s N U M E R I C O S Oracle d i s p o n e de dos t i p o s de datos:

1 ) n u m b e r ( t , d ) : para a l m a c e n a r valores enteros o d e c i m a l e s , positivos o negativos.

S u r a n g o va de 1 . 0 x 1 0 - 1 3 0 hasta 9 . 9 9 9 . . . (38 n u e v e s ) . D e f i n i m o s c a m p o s de este

t i p o c u a n d o q u e r e m o s a l m a c e n a r valores n u m é r i c o s con l o s c u a l e s l u e g o

r e a l i z a r e m o s o p e r a c i o n e s matemáticas, por e j e m p l o , c a n t i d a d e s , precios, etc.

E l parámetro "t" i n d i c a el n ú m e r o total d e d í g i t o s ( c o n t a n d o los d e c i m a l e s ) q u e

contendrá el n ú m e r o como m á x i m o (es l a p r e c i s i ó n ) . S u rango va de 1 a 3 8 . E l

parámetro " d " i n d i c a el m á x i m o d e d í g i t o s d e c i m a l e s ( e s c a l a ) . La escala p u e d e i r d e

-84 a 1 2 7 . Para d e f i n i r n ú m e r o enteros, se p u e d e o m i t i r el parámetro " d " o c o l o c a r u n

O.

U n c a m p o d e f i n i d o " n u m b e r ( 5 , 2 ) " p u e d e c o n t e n e r c u a l q u i e r n ú m e r o entre - 9 9 9 . 9 9 y

999.99.

Para especificar n ú m e r o enteros, p o d e m o s o m i t i r el parámetro " d " o colocar el v a l o r

O.

S i i n t e n t a m o s a l m a c e n a r u n v a l o r mayor fuera d e l r a n g o p e r m i t i d o a l d e f i n i r l o , tal

v a l o r no se c a r g a , aparece u n mensaje i n d i c a n d o tal s i t u a c i ó n y la s e n t e n c i a no se

ejecuta.

Por e j e m p l o , si d e f i n i m o s u n c a m p o de t i p o " n u m b e r ( 4 , 2 ) " e i n t e n t a m o s g u a r d a r el

v a l o r 1 2 3 . 4 5 , aparece u n mensaje i n d i c a n d o q u e el v a l o r es d e m a s i a d o g r a n d e para

l a c o l u m n a . S i i n g r e s a m o s u n v a l o r con m á s d e c i m a l e s q u e l o s d e f i n i d o s , el v a l o r se

carga pero con l a c a n t i d a d de d e c i m a l e s p e r m i t i d o s , l o s d í g i t o s sobrantes se o m i t e n .

2 ) float (x): a l m a c e n a u n n ú m e r o en p u n t o d e c i m a l . E l parámetro i n d i c a la p r e c i s i ó n

b i n a r i a m á x i m a ; con u n rango de 1 a 1 2 6 . Si se o m i t e , por defecto es 1 2 6 .

Para a m b o s tipos n u m é r i c o s :

- si i n g r e s a m o s u n v a l o r con m á s d e c i m a l e s q u e los p e r m i t i d o s , redondea al m á s

c e r c a n o ; por e j e m p l o , si d e f i n i m o s " f l o a t ( 4 , 2 ) " e i n g r e s a m o s el v a l o r " 1 2 . 6 8 6 " ,

g u a r d a r á " 1 2 . 6 9 " , r e d o n d e a n d o h a c i a a r r i b a ; s i i n g r e s a m o s el v a l o r " 1 2 . 6 8 2 " ,

guardará " 1 2 . 6 7 " , redondeando hacia abajo.

- si i n t e n t a m o s i n g r e s a r u n v a l o r fuera d e r a n g o , no l o acepta.
- si i n g r e s a m o s u n a c a d e n a , Oracle i n t e n t a c o n v e rt i r l a a v a l o r n u m é r i c o , s i d i c h a

c a d e n a consta s o l a m e n t e d e d í g i t o s , la conversión se r e a l i z a , l u e g o verifica s i está

dentro d e l r a n g o , si es a s í , l a i n g r e s a , s i n o , muestra u n mensaje de error y no ejecuta

l a s e n t e n c i a . S i l a c a d e n a c o n t i e n e caracteres q u e Oracle no p u e d e c o n v e rt i r a v a l o r

n u m é r i c o , muestra u n mensaje de error y l a s e n t e n c i a no se ejecuta.

Por e j e m p l o , d e f i n i m o s u n c a m p o de t i p o " n u m b e r l ( 5 , 2 ) " , si i n g r e s a m o s l a c a d e n a

' 1 2 . 2 2 ' , l a convierte a l v a l o r n u m é r i c o 1 2 . 2 2 y l a i n g r e s a ; si i n t e n t a m o s i n g r e s a r l a

c a d e n a ' 1 2 3 4 . 5 6 ' , l a convierte a l v a l o r n u m é r i c o 1 2 3 4 . 5 6 , pero como el m á x i m o v a l o r

p e r m i t i d o es 9 9 9 . 9 9 , muestra u n mensaje i n d i c a n d o q u e está fuera de r a n g o . S i

i n t e n t a m o s i n g r e s a r el v a l o r ' 1 2 y . 2 5 ' , Oracle no p u e d e r e a l i z a r l a conversión y

muestra u n mensaje d e error.


1 7 - Ingresar algunos campos

H e m o s a p r e n d i d o a i n g r e s a r registros l i s t a n d o todos l o s c a m p o s y c o l o c a n d o valores

para todos y cada u n o de e l l o s l u e g o de " v a l u e s " .

S i i n g r e s a m o s valores para todos l o s c a m p o s , p o d e m o s o m i t i r l a l i s t a de n o m b r e s de

los campos.

Por e j e m p l o , si t e n e m o s creada la t a b l a " l i b r o s " con los campos " t i t u l o " , "autor" y

" e d i t o r i a l " , p o d e m o s i n g r e s a r u n registro de l a s i g u i e n t e m a n e r a :

insert into libros values ( ' U n o ' , 'Richard Bach', 'Planeta');

También es p o s i b l e i n g r e s a r valores para a l g u n o s c a m p o s . I n g r e s a m o s valores

s o l a m e n t e para l o s c a m p o s " t i t u l o " y " a u t o r " :

insert into libros (titulo, autor)

values ( ' E l aleph', 'Borges');

O r a c l e a l m a c e n a r á el v a l o r " n u l l " e n el c a m p o " e d i t o r i a l " , para el c u a l no h e m o s

e x p l i c i t a d o u n valor.

Al i n g r e s a r registros d e b e m o s tener en c u e n t a :

- l a lista de c a m p o s d e b e c o i n c i d i r en c a n t i d a d y t i p o de valores con l a lista de valores

l u e g o de " v a l u e s " . S i se l i s t a n m á s (o m e n o s ) c a m p o s q u e los valores i n g r e s a d o s ,

aparece u n mensaje d e error y la s e n t e n c i a no se ejecuta.

- si i n g r e s a m o s valores para todos l o s c a m p o s p o d e m o s o b v i a r l a lista de c a m p o s .

- p o d e m o s o m i t i r valores para los c a m p o s q u e p e r m i t a n valores n u l o s (se g u a r d a r á

" n u l l " ) ; si o m i t i m o s el v a l o r para u n campo " n o t n u l l " , l a s e n t e n c i a no se ejecuta.


1 8 - Valores por defecto ( d e f a u l t )

H e m o s visto q u e si a l i n s e rt a r registros no se especifica u n v a l o r para u n c a m p o q u e

a d m i t e valores n u l o s , se i n g r e s a a u t o m á t i c a m e n t e " n u l l " . A este v a l o r se l e d e n o m i n a

v a l o r por defecto o p r e d e t e r m i n a d o .

U n v a l o r por defecto se i n s e rt a c u a n d o no está presente a l i n g r e s a r u n registro.

Para c a m p o s d e c u a l q u i e r t i p o no d e c l a r a d o s " n o t n u l l " , es d e c i r , q u e a d m i t e n valores

n u l o s , el v a l o r por defecto es " n u l l " . Para campos d e c l a r a d o s " n o t n u l l " , no existe

v a l o r por defecto, a m e n o s q u e se declare e x p l í c i t a m e n t e con l a c l á u s u l a " d e f a u l t " .

P o d e m o s establecer valores por defecto para l o s c a m p o s c u a n d o creamos la t a b l a .

Para e l l o u t i l i z a m o s "default" a l d e f i n i r e l c a m p o . Por e j e m p l o , q u e r e m o s q u e el v a l o r

por defecto d e l c a m p o "autor" d e l a t a b l a " l i b r o s " sea " D e s c o n o c i d o " y el v a l o r por

defecto d e l c a m p o " c a n t i d a d " sea " O " :

create table libros(

titulo varchar2(40) not null,

autor varchar2{30) default 'Desconocido' not null,

editorial varchar2(20),

precio number(S,2),

cantidad number(3) default 0

) ;

S i a l i n g r e s a r u n n u e v o registro o m i t i m o s l o s valores para el c a m p o "autor" y

" c a n t i d a d " , Oracle i n s e rt a r á los valores por defecto; e n "autor" colocará

" D e s c o n o c i d o " y en c a n t i d a d " O " .

E n t o n c e s , si a l d e f i n i r el c a m p o e x p l i c i t a m o s u n v a l o r m e d i a n t e l a c l á u s u l a " d e f a u l t " ,

ése será el v a l o r por defecto.

La c l á u s u l a "default" d e b e i r antes d e " n o t n u l l " ( s i e x i s t i e s e ) , s i n o aparece u n

mensaje de error.

Para ver si l o s c a m p o s de l a t a b l a " l i b r o s " t i e n e d e f i n i d o s valores por defecto y c u á l e s

s o n , podemos realizar la siguiente consulta:

select column_name,nullable,data_default

from user_tab_columns where TABLE_NAME = 'libros';

Muestra u n a f i l a por cada c a m p o , en la c o l u m n a "data_default" aparece el v a l o r por

defecto (si l o t i e n e ) , en l a c o l u m n a " n u l l a b l e " aparece " N " si el c a m p o no está d e f i n i d o

" n o t n u l l " y "Y" si a d m i t e valores " n u l l " .

También se p u e d e u t i l i z a r " d e f a u l t " para d a r el v a l o r por defecto a l o s c a m p o s en

s e n t e n c i a s " i n s e rt " , por e j e m p l o :


insert into libros (titulo,autor,editorial,precio,cantidad)

values ( ' E l gato con botas',default,default,default,100);

E n t o n c e s , l a c l á u s u l a "default" p e r m i t e especificar el v a l o r por defecto d e u n c a m p o .

S i no se e x p l i c i t a , el v a l o r por defecto es " n u l l " , s i e m p r e q u e el c a m p o no haya s i d o

declarado "not n u l l " .

Los campos para l o s c u a l e s no se i n g r e s a n valores en u n " i n s e rt " t o m a r á n los valores

por defecto:

- si permite valores n u l o s y no t i e n e c l á u s u l a " d e f a u l t " , a l m a c e n a r á " n u l l " ;

- si t i e n e c l á u s u l a "default" ( a d m i t a o no valores n u l o s ) , el v a l o r d e f i n i d o como

predeterminado;

- si está d e c l a r a d o e x p l í c i t a m e n t e "not n u l l " y no t i e n e v a l o r " d e f a u l t " , no hay v a l o r por

defecto, a s í q u e causará u n error y el " i n s e rt " no se ejecutará.

U n c a m p o s ó l o p u e d e t e n e r u n v a l o r p o r defecto. U n a t a b l a p u e d e t e n e r todos s u s

c a m p o s con valores por defecto. Q u e u n c a m p o tenga v a l o r p o r defecto no s i g n i f i c a

q u e no a d m i t a valores n u l o s , p u e d e o no a d m i t i r l o s .

U n c a m p o d e f i n i d o como clave p r i m a r i a acepta u n v a l o r " d e f a u l t " , pero no t i e n e

s e n t i d o ya q u e el v a l o r por defecto s o l a m e n t e podrá i n g r e s a r s e u n a vez; si intenta

ingresarse c u a n d o otro registro ya l o t i e n e a l m a c e n a d o , aparecerá u n mensaje de

error i n d i c a n d o q u e se intenta d u p l i c a r l a c l a v e .
1 9 - Operadores aritméticos y de

concatenación ( c o l u m n a s calculadas)

A p r e n d i m o s q u e l o s operadores son s í m b o l o s q u e permiten realizar d i s t i n t o s t i p o s de

operaciones.

D i j i m o s q u e O r a c l e t i e n e 4 tipos de o p e r a d o r e s : 1 ) r e l a c i o n a l e s o de c o m p a r a c i ó n ( l o s

v i m o s ) , 2 ) a r i t m é t i c o s , 3 ) de c o n c a t e n a c i ó n y 4 ) l ó g i c o s ( l o veremos m á s a d e l a n t e ) .

Los operadores aritméticos permiten r e a l i z a r c á l c u l o s con valores n u m é r i c o s .

Son: multiplicación(*), división(/), s u m a ( + ) y resta(-).

Es p o s i b l e o b t e n e r s a l i d a s en l a s c u a l e s u n a c o l u m n a sea el resultado d e u n c á l c u l o

y no u n c a m p o d e u n a t a b l a .

S i q u e r e m o s ver l o s t í t u l o s , precio y c a n t i d a d de cada l i b r o e s c r i b i m o s l a s i g u i e n t e

sentencia:

select titulo,precio,cantidad

from libros;

S i q u e r e m o s s a b e r el monto total en d i n e r o de u n t í t u l o p o d e m o s m u l t i p l i c a r el precio

por l a c a n t i d a d por cada t í t u l o , pero t a m b i é n p o d e m o s hacer q u e Oracle r e a l i c e el

c á l c u l o y l o i n c l u y a en u n a c o l u m n a extra en l a s a l i d a :

select titulo, precio,cantidad,

precio*cantidad

from libros;

S i q u e r e m o s s a b e r el precio de cada l i b r o con u n 1 0 % de d e s c u e n t o p o d e m o s i n c l u i r

en l a s e n t e n c i a l o s s i g u i e n t e s c á l c u l o s :

select titulo,precio,

precio-(precio*0.1)

from libros;

También p o d e m o s a c t u a l i z a r l o s datos e m p l e a n d o operadores aritméticos:

update libros set precio=precio-(precio*0.1);

Para c o n c a t e n a r c a d e n a s d e caracteres existe el operador de c o n c a t e n a c i ó n 1 1 -

Para c o n c a t e n a r el t í t u l o y el a u t o r de cada l i b r o u s a m o s el o p e r a d o r de

concatenación ( " 1 1 " ) :

select titulol 1 ' - ' 1 !autor

from libros;
Note q u e c o n c a t e n a m o s a d e m á s u n g u i ó n para separar los c a m p o s .

O r a c l e p u e d e c o n v e rt i r a u t o m á t i c a m e n t e valores n u m é r i c o s a c a d e n a s para u n a

c o n c a t e n a c i ó n ; por e j e m p l o , en el s i g u i e n t e e j e m p l o mostramos el t í t u l o y precio de

cada l i b r o c o n c a t e n a d o con el o p e r a d o r " 1 1 " :

select titulol 1 ' $ ' 1 lprecio

from libros;
20 - A l i a s ( e n c a b e z a d o s de c o l u m n a s )

U n a m a n e r a d e hacer m á s c o m p r e n s i b l e el resultado de u n a c o n s u l t a consiste en

c a m b i a r los e n c a b e z a d o s d e l a s c o l u m n a s . Por e j e m p l o , t e n e m o s la t a b l a " l i b r o s " con

u n c a m p o " c a n t i d a d " (entre otros) en e l c u a l se a l m a c e n a l a c a n t i d a d d e l i b r o s en

stock; q u e r e m o s q u e a l mostrar l a información de d i c h a t a b l a aparezca como

e n c a b e z a d o d e l c a m p o " c a n t i d a d " el texto "stock", para e l l o colocamos u n a l i a s de l a

siguiente manera:

select titulo,

cantidad as stock,

precio

from libros;

Para r e e m p l a z a r el n o m b r e de u n c a m p o d e l encabezado por otro, se coloca la

p a l a b r a clave "as" s e g u i d o d e l texto d e l e n c a b e z a d o .

S i el a l i a s consta de u n a s o l a cadena l a s c o m i l l a s no s o n n e c e s a r i a s , pero si c o n t i e n e

m á s d e u n a p a l a b r a , es necesario colocarla entre c o m i l l a s d o b l e s :

select titulo,

cantidad as "stock disponible",

precio

from libros;

También se p u e d e crear u n a l i a s para c o l u m n a s c a l c u l a d a s . P o r e j e m p l o :

select titulo,precio,

precio*0.1 as descuento,

precio-(precio*0.1) as "preciofinal"

from libros;

La p a l a b r a clave "as" es o p c i o n a l , pero es c o n v e n i e n t e u s a r l a .

E n t o n c e s , u n " a l i a s " se usa como n o m b r e d e u n c a m p o o d e u n a e x p r e s i ó n . E n estos

casos, son o p c i o n a l e s , s i rv e n para h a c e r m á s c o m p r e n s i b l e el r e s u l t a d o .


21 - Funciones stri ng

Las f u n c i o n e s de manejo d e caracteres alfanuméricos aceptan argumentos de tipo caracter y

retornan caracteres o valores n u m é r i c o s .

Las s i g u i e n t e s son a l g u n a s d e l a s f u n c i o n e s q u e ofrece Oracle para trabajar con cadenas de

caracteres:

- c h r ( x ) : retorna u n caracter e q u i v a l e n t e a l c ó d i g o e n v i a d o como a r g u m e n t o "x". E j e m p l o :

select chr(65) from dual;-- retorna ' A ' .

select chr(100) from dual;-- retorna ' d ' .

- concat(cadena1 , c a d e n a 2 ) : concatena dos cadenas de caracteres; es e q u i v a l e n t e a l operador 1 1 -

Ejemplo:

select concat('Buenas·, • tardes') from dual;--retorna 'Buenas tardes·.

- i n i t c a p ( c a d e n a ) : retorna l a c a d e n a e n v i a d a como a r g u m e n t o con la primera letra (letra c a p i t a l ) de

cada palabra en m a y ú s c u l a . E j e m p l o :

select initcap('buenas tardes alumno') from dual;--retorna 'Buenas Tardes Alumno·.

- lower(cadena): retorna l a c a d e n a e n v i a d a como a r g u m e n t o en m i n ú s c u l a s . "lower" s i g n i f i c a reducir

en i n g l é s . E j e m p l o :

1 1 1 1 •

select lower('Buenas tardes ALUMNO') from dual;--retorna buenas tardes alumno

- u p p e r ( c a d e n a ) : retorna la c a d e n a con todos los caracteres en m a y ú s c u l a s . E j e m p l o :

select upper('www.oracle.com') from dual;-- ·www.ORACLE.COM'

- l p a d ( c a d e n a , l o n g i t u d , c a d e n a r e l l e n o ) : retorna l a cantidad de caracteres especificados por el

argumento " l o n g i t u d " , de la cadena e n v i a d a como p r i m e r a r g u m e n t o ( c o m e n z a n d o desde el p r i m e r

caracter); si " l o n g i t u d " es mayor q u e el t a m a ñ o de l a c a d e n a e n v i a d a , r e l l e n a los espacios restantes

con l a cadena e n v i a d a como tercer argumento (en caso de o m i t i r el tercer a r g u m e n t o r e l l e n a con

e s p a c i o s ) ; el r e l l e n o c o m i e n z a desde la i z q u i e r d a . E j e m p l o s :

select lpad('alumno',10, 'xyz') fr o m dual;-- retorna 'xyzxalumno•

select lpad('alumno',4, 'xyz') from dual;-- retorna 'alum·

- r p a d ( c a d e n a , l o n g i t u d , c a d e n a r e l l e n o ) : retorna l a c a n t i d a d de caracteres especificados por el

a r g u m e n t o " l o n g i t u d " , de la cadena e n v i a d a como p r i m e r a r g u m e n t o ( c o m e n z a n d o desde el p r i m e r

caracter); si " l o n g i t u d " es mayor q u e el t a m a ñ o de l a c a d e n a e n v i a d a , r e l l e n a los espacios restantes

con l a cadena e n v i a d a como tercer argumento (en caso de o m i t i r el tercer a r g u m e n t o r e l l e n a con

e s p a c i o s ) ; el r e l l e n o c o m i e n z a desde la derecha ( ú l t i m o caracter). E j e m p l o s :

select rpad('alumno',10, 'xyz') from dual;-- retorna 'alumnoxyzx•

select rpad('alumno',4, 'xyz') from dual;-- retorna 'alum·

- l t r i m ( c a d e n a 1 , c a d e n a 2 ) : borra todas las ocurrencias d e " c a d e n a 2 " e n " c a d e n a 1 " , s i se encuentran a l

c o m i e n z o ; si se o m i t e e l s e g u n d o a r g u m e n t o , se e l i m i n a n los e s p a c i o s . E j e m p l o :

select ltrim('la casa de la cuadra•, ' l a ' ) f ro m dual;-- • casa de la cuadra•

select ltrim(' es la casa de la cuadra', ' l a ' ) from dual;-- no elimina ningún caracter

select ltrim(' la casa') from dual;-- 'la casa·


- rt r i m ( cadena 1 , c a d e n a 2 ) : borra todas las o c u r r e n c i a s de "cadena2" en "cadena 1 " , si se encuentran

por la derecha ( a l f i n a l de l a c a d e n a ) ; si se omite e l s e g u n d o a r g u m e n t o , se borran los e s p a c i o s .

Ejemplo:

select rtrim('la casa lila', ' l a ' ) from dual;-- 'la casa li'

select rtrim('la casa lila ' , ' l a ' ) from dual;-- no borra ningún caracter

select rtrim('la casa lila ' ) from dual; - - ' l a casa lila'

- t r i m ( c a d e n a ) : retorna la c a d e n a con los espacios de la izquierda y derecha e l i m i n a d o s . "Trim"

s i g n i f i c a recortar. E j e m p l o :

select trim(' oracle ' ) from dual;--'oracle'

- r e p l a c e ( c a d e n a , s u b c a d e 1 , s u b c a d e 2 ) : retorna la cadena con todas l a s ocurrencias de l a s u b c a d e n a

de r e e m p l a z o ( s u b c a d e 2 ) por l a s u b c a d e n a a reemplazar ( s u b c a e 1 ) . E j e m p l o :

select replace('xxx.oracle.com', ' x ' , ' w ' ) from dual;

retorna "www.oracle.com'.

- s u b s t r ( c a d e n a , i n i c i o , l o n g i t u d ) : devuelve u n a parte de l a cadena especificada como p r i m e r

a r g u m e n t o , e m p e z a n d o d e s d e l a posición especificada por el s e g u n d o a r g u m e n t o y d e tantos

caracteres de l o n g i t u d como i n d i c a el tercer a r g u m e n t o . E j e m p l o :

select substr('www.oracle.com',1,10) f rom dual;-- 'www.oracle'

select substr('www.oracle.com' , 5 , 6 ) from dual;-- 'oracle'

- l e n g t h ( c a d e n a ) : retorna la l o n g i t u d d e l a cadena e n v i a d a como a r g u m e n t o . " l e n g h t " s i g n i f i c a l o n g i t u d

en i n g l é s . E j e m p l o :

select length('www.oracle.com') from dual;-- devuelve 14.

- instr ( c a d e n a , s u b c a d e n a ) : d e v u e l v e la posición de comienzo ( d e l a primera ocurrencia) de l a

s u b c a d e n a especificada en la c a d e n a e n v i a d a como p r i m e r a r g u m e n t o . S i no l a e n c u e n t r a retorna O .

Ejemplos:

select instr('Jorge Luis Borges', ' o r ' ) from dual;-- 2

select instr('Jorge Luis Borges', ' a r ' ) from dual;-- 0, no se encuentra

- t r a n s l a t e ( ) : r e e m p l a z a cada o c u r r e n c i a de u n a serie de caracteres con otra serie d e acracteres. La

diferencia con " r e p l a c e " es q u e a q u e l l a trabaja con cadenas d e caracteres y reemplaza u n a cadena

c o m p l e t a por otra, e n c a m b i o "translate" trabaja con caracteres s i m p l e s y reemplaza varios. E n el

s i g u i e n t e e j e m p l o se especifica q u e se r e e m p l a c e n todos los caracteres "O" por el caracter " O " , todos

los caracteres " S " por el caracter "5" y todos los caracteres " G " por " 6 " :

select translate('JORGE LUIS BORGES', 'OSG', ' 0 5 6 ' ) f ro m dual;--'J0R6E LUIS B0R6ES'

Se p u e d e n e m p l e a r estas f u n c i o n e s e n v i a n d o como a r g u m e n t o e l nombre de u n c a m p o de t i p o

caracter.
23 - Funciones de fechas y horas

Oracle d i s p o n e de varias funciones q u e operan con tipos de datos "date". Estas son a l g u n a s :

- add_months(f,n): agrega a u n a fecha, u n n ú m e r o de meses. Si el s e gundo argumento es positivo, se le suma a la

fecha e n v i a d a tal cantidad de meses; si es negativo, se le resta a la fecha e n viada tal cantidad de meses. E j e m p l o :

select add_months('10/06/2007',5) from dual; --retorna "10/11/07"

select add_months('10/06/2007',-5) from dual; --retorna "10/01/07"

select add_months('30/01/2007',1) from dual;-- retorna "25/02/07" ya que es el último día de ese mes

- last_day(f): retorna el u l t i m o d ía de mes de la fecha enviada como a r g u m e n t o . E j e m p l o :

select last_day('10/02/2007') from dual;-- "28/02/07"

select last_day('10/08/2007') from dual;-- "31/08/07"

- months_between(f1 ,f2): retorna el numero de meses entre las fechas enviadas como argumento. E j e m p l o :

select months_between('19/05/2003', '21/06/05') from dual;-- retorna

- next_day(fecha,dia): retorna u n a fecha correspondiente al primer día especificado en "dia" lue go de la fecha

especificada. En el s i g u i e n t e ejemplo se busca el l u n e s s i g u i e n t e a la fecha especificada:

select next_day('l0/08/2007', ' L U N E S ' ) from dual;

- current_date: retorna l a fecha actual. E j e m p l o :

select current_date from dual;

- current_timestamp: retorna la fecha actual

select current_timestamp from dual;

Retorna: 10/08/07 0 9 : 5 9 : 4 4 , 1 0 9 0 0 0 0 0 0 A M E R I C A/ B U E N O S _ A I R E S

- sysdate: retorna la fecha y hora actuales en el servidor de Oracle.

-systimestamp: retorna fecha y hora actuales.

select systimestamp from dual;

Retorna 10/08/07 1 0 : 3 3 : 4 8 , 9 8 4 0 0 0 0 0 0 - 0 3 : 0 0

- to_date: convierte u n a cadena a tipo de dato "date". Ejemplo:

select to_date ('05-SEP-2007 10:00 A M ' , ' D D - M O N - YY Y Y HH:MI AM') from dual;

Retorna 05/09/07

- to_char: convierte u n a fecha a cadena de caracteres. Ejemplo:

select to_char('l0/10/2007')from dual;

- extract(parte,fecha): retorna la parte (especificada por el primer a r g u m e n t o ) de u n a fecha. Puede extraer el a ñ o (year),

mes ( m o n t h ) , d í a (day), hora ( h our ) , m i n u t o ( m i n u t e ) , s e g u n d o (second), etc. E j e m p l o :

select extract(month from sysdate) from dual;

retorna el número mes de la fecha a c t u a l .

En Oracle: Los operadores a r i t m é t i c o s " + " (má s) y " - " (menos) pueden emplearse con fechas. Por ejemplos:

select sysdate-3:

Retorna 3 días antes de la fecha a c t u a l .

select to_date('15/12/2007')-5 from dual;

Retorna 1 0 / 1 2 / 0 7
24 - O r d e n a r registros ( o r d e r by)

P o d e m o s o r d e n a r el resultado de u n "select" para q u e l o s registros se muestren

o r d e n a d o s por a l g ú n c a m p o , para e l l o u s a m o s la c l á u s u l a "arder by".

La s i n t a x i s básica es l a s i g u i e n t e :

select *from NOMBRETABLA

arder by CAMPO;

Por e j e m p l o , r e c u p e r a m o s l o s registros de l a t a b l a " l i b r o s " o r d e n a d o s por el t í t u l o :

select *from libros

arder by titulo;

Aparecen l o s registros o r d e n a d o s alfabéticamente por el c a m p o especificado.

También p o d e m o s colocar el n ú m e r o d e orden d e l c a m p o por el q u e q u e r e m o s q u e

se o r d e n e en l u g a r de su n o m b r e , es decir, referenciar a los c a m p o s por s u p o s i c i ó n

en l a lista d e s e l e c c i ó n . Por e j e m p l o , q u e r e m o s el resultado del "select" o r d e n a d o por

"precio":

select titulo,autor,precio

from libros arder by 3;

S i c o l o c a m o s u n n ú m e r o mayor a l a c a n t i d a d de c a m p o s de la l i s t a de s e l e c c i ó n ,

aparece u n mensaje d e error y la s e n t e n c i a no se ejecuta.

Por defecto, si no a c l a r a m o s en la s e n t e n c i a , l o s o r d e n a de m a n e r a a s c e n d e n t e ( de

m e n o r a m a y o r ) . P o d e m o s o r d e n a r l o s d e mayor a menor, para e l l o a g r e g a m o s la

p a l a b r a clave " d e s e " :

select *libros

arder by editorial dese;

También p o d e m o s o r d e n a r por varios c a m p o s , por e j e m p l o , por " t i t u l o " y " e d i t o r i a l " :

select *from libros

arder by titulo,editorial;

I n c l u s o , p o d e m o s o r d e n a r en d i s t i n t o s s e n t i d o s , por e j e m p l o , p o r " t i t u l o " en s e n t i d o

ascendente y "editorial" en sentido descendente:

select *from libros

arder by titulo ase, editorial dese;

D e b e aclararse a l l a d o de cada c a m p o , p u e s estas p a l a b r a s claves afectan al c a m p o

i n m e d i a t a m e n t e anterior.
Es p o s i b l e o r d e n a r por u n c a m p o q u e no se lista en la selección i n c l u s o por c o l u m n a s

calculados.

Se p u e d e e m p l e a r "arder by" con c a m p o s d e t i p o caracter, n u m é r i c o y date.


2 5 - Operadores lógicos ( a n d - o r - n o t )

Hasta el m o m e n t o , h e m o s a p r e n d i d o a establecer u n a c o n d i c i ó n con "where"

u t i l i z a n d o operadores r e l a c i o n a l e s . P o d e m o s establecer más de u n a c o n d i c i ó n con l a

c l á u s u l a " w h e r e " , para e l l o a p r e n d e r e m o s los operadores l ó g i c o s .

Son los s i g u i e n t e s :

- and, significa "y",

- or, significa "y/o",

- not, significa "no", invierte el resultado

- { ) , paréntesis

Los operadores l ó g i c o s se u s a n para c o m b i n a r c o n d i c i o n e s .

S i q u e r e m o s recuperar todos l o s l i b r o s cuyo autor sea i g u a l a "Borges" y cuyo precio

no s u p e r e l o s 20 pesos, n e c e s i t a m o s 2 c o n d i c i o n e s :

select *from libros

where (autor='Borges') and

(precio<=20);

Los registros r e c u p e r a d o s en u n a s e n t e n c i a q u e u n e dos c o n d i c i o n e s con el operador

" a n d " , c u m p l e n con las 2 c o n d i c i o n e s .

Q u e r e m o s ver los l i b r o s cuyo a u t o r sea " B o r g e s " y/o cuya e d i t o r i a l sea " P l a n e t a " :

select *from libros

where autor='Borges' or

editorial='Planeta';

E n l a s e n t e n c i a a n t e r i o r u s a m o s el operador "or"; i n d i c a m o s q u e recupere los l i b r o s

en los c u a l e s el v a l o r d e l c a m p o "autor" sea "Borges" y/o el v a l o r d e l c a m p o

" e d i t o r i a l " sea " P l a n e t a " , es decir, seleccionará l o s registros q u e c u m p l a n con l a

p r i m e r a c o n d i c i ó n , con l a s e g u n d a c o n d i c i ó n y con a m b a s c o n d i c i o n e s .

Los registros recuperados con u n a sentencia q u e u n e dos c o n d i c i o n e s con el

operador "or", c u m p l e n u n a de las condiciones o a m b a s .

Q u e r e m o s recuperar l o s l i b r o s q u e N O c u m p l a n l a c o n d i c i ó n d a d a , p o r e j e m p l o ,

a q u e l l o s cuya e d i t o r i a l N O sea " P l a n e t a " :

select *from libros

where not editorial='Planeta';

E l operador "not" i n v i e rt e el r e s u l t a d o d e l a c o n d i c i ó n a l a c u a l a n t e c e d e .
Los registros recuperados en u n a s e n t e n c i a en la c u a l aparece el operador " n o t " , no

c u m p l e n con l a c o n d i c i ó n a l a c u a l afecta el " N O T " .

Los paréntesis se u s a n para encerrar c o n d i c i o n e s , para q u e se e v a l ú e n como u n a

sola expresión.

C u a n d o e x p l i c i t a m o s varias c o n d i c i o n e s con diferentes operadores l ó g i c o s

( c o m b i n a m o s " a n d " , "or") p e r m i t e establecer el orden de p r i o r i d a d de la e v a l u a c i ó n ;

a d e m á s p e r m i t e d i f e r e n c i a r l a s expresiones m á s c l a r a m e n t e .

Por e j e m p l o , l a s s i g u i e n t e s expresiones d e v u e l v e n u n resultado diferente:

select *from libros

where (autor='Borges') or

(editorial='Paidos' and precio<20);

select *from libros

where (autor='Borges' or editorial='Paidos') and

(precio<20);

S i b i e n los paréntesis no son o b l i g a t o r i o s en todos l o s casos, se r e c o m i e n d a

u t i l i z a r l o s para evitar c o n f u s i o n e s .

E l orden de p r i o r i d a d de l o s operadores l ó g i c o s es el s i g u i e n t e : "not" se a p l i c a a n t e s

q u e " a n d " y " a n d " antes q u e " o r " , s i no se especifica u n o r d e n d e e v a l u a c i ó n

m e d i a n t e el uso de p a r é n t e s i s . E l orden en el q u e se e v a l ú a n l o s operadores con

i g u a l n i v e l d e p r e c e d e n c i a es i n d e f i n i d o , por e l l o se r e c o m i e n d a u s a r l o s p a r é n t e s i s .

E n t o n c e s , para establecer m á s de u n a c o n d i c i ó n en u n "where" es necesario e m p l e a r

operadores l ó g i c o s . " a n d " s i g n i f i c a "y", i n d i c a q u e se c u m p l a n a m b a s c o n d i c i o n e s ;

"or" s i g n i f i c a "y/o", i n d i c a q u e se c u m p l a u n a u otra c o n d i c i ó n (o a m b a s ) ; "not"

s i g n i f i c a " n o . " , i n d i c a q u e no se c u m p l a l a c o n d i c i ó n e s p e c i f i c a d a .
2 6 - Otros operadores r e l a c i o n a l e s ( b e t w e e n )

H e m o s visto l o s operadores r e l a c i o n a l e s : = ( i g u a l ) , < > ( d i s t i n t o ) , > ( m a y o r ) , <

( m e n o r ) , > = ( m a y o r o i g u a l ) , < = ( m e n o r o i g u a l ) , is n u l l / i s not n u l l (si u n v a l o r es N U L L

o no).

Otro o p e r a d o r r e l a c i o n a l es " b e t w e e n " , trabajan con i n t e rv a l o s d e v a l o r e s .

Hasta a h o r a , para recuperar de la t a b l a " l i b r o s " los l i b r o s con precio mayor o i g u a l a

20 y m e n o r o i g u a l a 4 0 , u s a m o s 2 c o n d i c i o n e s u n i d a s p o r el o p e r a d o r l ó g i c o " a n d " :

select *from libros

where precio>=20 and

precio<=40;

P o d e m o s u s a r "between" y a s í s i m p l i f i c a r l a c o n s u l t a :

select *from libros

where precio between 20 and 40;

A v e r i g u a m o s si el v a l o r d e u n c a m p o d a d o ( p r e c i o ) está entre los valores m í n i m o y

m á x i m o especificados (20 y 40 respectivamente).

"between" s i g n i f i c a " e n t r e " . Trabaja con i n t e rv a l o d e v a l o r e s .

Este o p e r a d o r no t i e n e en c u e n t a l o s v a l ores " n u l l " .

S i a g r e g a m o s e l o p e r a d o r "not" antes d e "between" el resultado se i n v i e rt e , es d e c i r ,

se r e c u p e r a n los registros q u e están fuera d e l i n t e rv a l o e s p e c i f i c a d o . Por e j e m p l o ,

r e c u p e r a m o s los l i b r o s cuyo precio N O se e n c u e n t r e entre 20 y 3 0 , es d e c i r , l o s

m e n o r e s a 20 y mayores a 3 0 :

select *from libros

where precio not between 20 and 30;

P o d e m o s especificar u n i n t e rv a l o de valores de t i p o fecha con " b e t w e e n " :

select *from libros

where edicion between '01/05/2000' and '01/05/2007';

E n t o n c e s , e m p l e a m o s el o p e r a d o r "between" para r e d u c i r l a s c o n d i c i o n e s " w h e r e " .


27 - Otros operadores r e l a c i o n a l e s ( i n )

Se u t i l i z a " i n " para a v e r i g u a r si el v a l o r d e u n c a m p o está i n c l u i d o en u n a l i s t a de

valores e s p e c i f i c a d a .

E n l a s i g u i e n t e s e n t e n c i a u s a m o s " i n " para a v e r i g u a r si el v a l o r d e l c a m p o a u t o r está

i n c l u i d o e n l a l i s t a de valores especificada (en este caso, 2 c a d e n a s ) .

Hasta a h o r a , para recuperar l o s l i b r o s cuyo autor sea ' P a e n z a ' o 'Borges' u s á b a m o s

2 condiciones:

select *from libros

where autor='Borges' or autor='Paenza';

Podemos usar " i n " y s i m p l i f i c a r la consulta:

select *from libros

where autor in{'Borges', 'Paenza');

Para recuperar l o s l i b r o s cuyo a u t o r no sea ' P a e n z a ' n i 'Borges' u s á b a m o s :

select *from libros

where autor<>'Borges' and

autor<>'Paenza';

También p o d e m o s u s a r " i n " a n t e p o n i e n d o " n o t " :

select *from libros

where autor not in {'Borges', 'Paenza');

E m p l e a n d o " i n " a v e r i g u a m o s s i el v a l o r d e l c a m p o está i n c l u i d o e n l a l i s t a d e valores

e s p e c i f i c a d a ; con "not" a n t e c e d i e n d o l a c o n d i c i ó n , i n v e rt i m o s el r e s u l t a d o , es decir,

recuperamos los valores q u e no se e n c u e n t r a n ( n o c o i n c i d e n ) con la lista de valores.

Los valores " n u l l " no se c o n s i d e r a n .


2 8 - B ú s q u e d a de patrones ( l i k e - not l i k e )

Existe u n o p e r a d o r r e l a c i o n a l q u e se usa para r e a l i z a r c o m p a r a c i o n e s

exclusivamente de cadenas, " l i k e " y "not l i k e " .

H e m o s r e a l i z a d o c o n s u l t a s u t i l i z a n d o operadores r e l a c i o n a l e s para c o m p a r a r

c a d e n a s . Por e j e m p l o , s a b e m o s recuperar l o s l i b r o s cuyo a u t o r sea i g u a l a la c a d e n a

"Borges":

select *from libros

where autor='Borges';

E l operador i g u a l ( " = " ) nos permite comparar c a d e n a s d e caracteres, pero a l r e a l i z a r

l a c o m p a r a c i ó n , busca c o i n c i d e n c i a s d e c a d e n a s c o m p l e t a s , realiza u n a b ú s q u e d a

exacta.

I m a g i n e m o s q u e t e n e m o s registrados estos 2 l i b r o s :

"El Aleph", "Borges";

"Antologia poetica", " J . L . Borges";

S i q u e r e m o s r e c u p e r a r todos l o s l i b r o s de "Borges" y e s p e c i f i c a m o s l a s i g u i e n t e

condición:

select *from libros

where autor='Borges';

s ó l o aparecerá el p r i m e r registro, ya q u e l a c a d e n a "Borges" no es i g u a l a l a c a d e n a

" J . L . Borges".

Esto s u c e d e porque el o p e r a d o r " = " ( i g u a l ) , t a m b i é n el o p e r a d o r " < > " ( d i s t i n t o )

c o m p a r a n c a d e n a s d e caracteres c o m p l e t a s . Para c o m p a r a r porciones de c a d e n a s

u t i l i z a m o s l o s operadores " l i k e " y "not l i k e " .

E n t o n c e s , p o d e m o s c o m p a r a r trozos d e c a d e n a s de caracteres para r e a l i z a r

c o n s u l t a s . Para recuperar todos los registros cuyo a u t o r c o n t e n g a la cadena "Borges"

debemos tipear:

select *from libros

where autor like "%Borges%";

E l s í m b o l o " % " (porcentaje) r e e m p l a z a c u a l q u i e r c a n t i d a d d e caracteres ( i n c l u y e n d o

n i n g ú n caracter). Es u n caracter c o m o d í n . " l i k e " y "not l i k e " s o n o p e r a d o r e s de

comparación q u e s e ñ a l a n i g u a l d a d o diferencia.

Para s e l e c c i o n a r todos l o s l i b r o s q u e c o m i e n c e n con " M " :


select *from libros

where titulo like 'M%';

Note q u e el s í m b o l o " % " ya no está al c o m i e n z o , con esto i n d i c a m o s q u e el t í t u l o

d e b e t e n e r como p r i m e r a letra l a " M " y l u e g o , c u a l q u i e r c a n t i d a d d e caracteres.

Para s e l e c c i o n a r todos l o s l i b r o s q u e N O c o m i e n c e n con " M " :

select *from libros

where titulo not like 'M%';

Así c o m o " % " r e e m p l a z a c u a l q u i e r c a n t i d a d d e caracteres, el g u i ó n b a j o " _ "

r e e m p l a z a u n caracter, es otro caracter c o m o d í n . Por e j e m p l o , q u e r e m o s ver l o s

l i b r o s de "Lewis C a r r o l l " pero no recordamos si se e s c r i b e " C a r r o l l " o "Carrolt",

entonces t i p e a m o s esta c o n d i c i ó n :

select *from libros

where autor like "%Carral_";

" l i k e " se e m p l e a con t i p o s d e datos caracter y date. S i e m p l e a m o s " l i k e " con t i p o s de

datos q u e no son caracteres, Oracle convierte (si es p o s i b l e ) el t i p o de dato a

caracter. P o r e j e m p l o , q u e r e m o s b u s c a r todos l o s l i b r o s cuyo precio se encuentre

entre 1 0 . 0 0 y 1 9 . 9 9 :

select titulo,precio from libros

where precio like '1_,%';

Q u e r e m o s l o s l i b r o s q u e N O i n c l u y e n centavos en s u s precios:

select titulo,precio from libros

where precio not like '%,%';

Los valores n u l o s no se i n c l u y e n en l a s b ú s q u e d a s con " l i k e " y " n o t l i k e " .


2 9 - C o n t a r registros ( c o u n t )

Existen e n O r a c l e f u n c i o n e s q u e nos p e r m i t e n contar registros, c a l c u l a r s u m a s ,

p r o m e d i o s , o b t e n e r valores m á x i m o s y m í n i m o s . Estas f u n c i o n e s se d e n o m i n a n

f u n c i o n e s d e g r u p o y operan sobre u n conjunto de valores (registros), no con datos

i n d i v i d u a l e s y d e v u e l v e n u n ú n i c o valor.

I m a g i n e m o s q u e nuestra t a b l a " l i b r o s " c o n t i e n e m u c h o s registros. Para a v e r i g u a r l a

c a n t i d a d s i n n e c e s i d a d de contarlos m a n u a l m e n t e u s a m o s la f u n c i ó n " c o u n t ( ) " :

select count(*)

from libros;

La f u n c i ó n " c o u n t ( ) " cuenta l a cantidad de registros d e u n a t a b l a , i n c l u y e n d o l o s q u e

tienen valor n u l o .

También p o d e m o s u t i l i z a r esta f u n c i ó n j u n t o con la c l a u s u l a "where" para u n a

c o n s u l t a m á s específica. Q u e r e m o s s a b e r l a c a n t i d a d de l i b r o s de la e d i t o r i a l

"Planeta":

select count(*)

from libros

where editorial='Planeta';

Para contar l o s registros q u e t i e n e n precio ( s i n tener en cuenta los q u e t i e n e n v a l o r

n u l o ) , u s a m o s l a f u n c i ó n " c o u n t ( ) " y e n l o s paréntesis c o l o c a m o s el n o m b r e d e l

c a m p o q u e n e c e s i t a m o s contar:

select count(precio)

from libros;

Note q u e " c o u n t ( * ) " retorna l a c a n t i d a d d e registros de u n a t a b l a ( i n c l u y e n d o l o s q u e

t i e n e n v a l o r " n u l l " ) m i e n t r a s q u e " c o u n t ( p r e c i o )" retorna l a cantidad de registros en los

c u a l e s el c a m p o "precio" no es n u l o . No es lo m i s m o . " c o u n t ( * ) " cuenta registros, si

en l u g a r de u n asterisco colocamos como a r g u m e n t o el n o m b r e de u n c a m p o , se

c o n t a b i l i z a n l o s registros cuyo v a l o r en ese c a m p o N O es n u l o .


3 0 - F u n c i o n e s de g r u p o ( c o u n t - max - m i n -

s u m - avg)

H e m o s visto q u e O r a c l e d i s p o n e de f u n c i o n e s q u e nos permiten contar registros,

c a l c u l a r s u m a s , p r o m e d i o s , obtener valores m á x i m o s y m í n i m o s , l a s f u n c i o n e s de

g r u p o . Las f u n c i o n e s de g r u p o operan sobre u n conjunto de valores (registros) y

retornan u n s o l o v a l o r .

Ya h e m o s a p r e n d i d o u n a d e e l l a s , " c o u n t ( ) " , v e a m o s otras.

Se p u e d e n u s a r en u n a i n s t r u c c i ó n "select" y c o m b i n a r l a s con l a c l á u s u l a " g r o u p by"

( l a veremos posteriormente).

Todas estas f u n c i o n e s retornan " n u l l " si n i n g ú n registro c u m p l e con l a c o n d i c i o n d e l

"where" ( excepto "count" q u e en tal caso retorna cero).

E l t i p o de dato d e l c a m p o d e t e r m i n a l a s f u n c i o n e s q u e se p u e d e n e m p l e a r con e l l a s .

Las r e l a c i o n e s entre l a s f u n c i o n e s de a g r u p a m i e n t o y l o s t i p o s de datos es la

siguiente:

- c o u n t : se p u e d e e m p l e a r con c u a l q u i e r t i p o de d a t o .

- m i n y m a x : con c u a l q u i e r t i p o de d a t o .

- s u m y a v g : s ó l o en c a m p o s de t i p o n u m é r i c o .

La f u n c i ó n " s u m ( ) " retorna l a s u m a d e los valores q u e c o n t i e n e el c a m p o

e s p e c i f i c a d o . S i q u e r e m o s s a b e r la c a n t i d a d total de l i b r o s q u e t e n e m o s d i s p o n i b l e s

para l a v e n t a , d e b e m o s s u m a r todos l o s valores d e l c a m p o " c a n t i d a d " :

select sum(cantidad)

from libros;

Para a v e r i g u a r el v a l o r m á x i m o o m í n i m o de u n c a m p o u s a m o s l a s f u n c i o n e s " m a x ( ) "

y " m i n ( ) " respectivamente. Q u e r e m o s s a b e r c u á l es el mayor precio d e todos los

libros:

select max(precio)

from libros;

E n t o n c e s , dentro d e l paréntesis de l a f u n c i ó n colocamos el n o m b r e d e l c a m p o d e l

c u á l q u e r e m o s el m á x i m o valor.

La f u n c i ó n " a v g ( ) " retorna el v a l o r p r o m e d i o d e los valores d e l c a m p o e s p e c i f i c a d o .

Q u e r e m o s s a b e r el p r o m e d i o d e l precio de l o s l i b r o s referentes a " P H P " :


select avg(precio)

from libros

where titulo like '%PHP%';

Ahora p o d e m o s e n t e n d e r p o r q u e estas f u n c i o n e s se d e n o m i n a n "funciones de

g r u p o " , p o r q u e operan sobre c onjuntos d e registros, no con datos i n d i v i d u a l e s .

Tratamiento d e los valores n u l o s :

S i r eali za u n a c o n s u l t a con l a f u n c i ó n "count" i n c l u y e n d o entre paréntesis u n c a m p o y

l a t a b l a c o n t i e n e 1 8 registros, 2 de l os c u a l e s c o n t i e n e n v a l o r n u l o en " p r e c i o " , el

r e s u l tad o d e v u e l v e u n total de 1 6 f i l a s p o r q u e no c o n s i d e r a a q u e l l o s con valor n u l o .

Todas l a s f u n c i o n e s d e g r u p o , excepto " c o u n t ( * ) " , excluye los valores n u l o s d e los

campos;

" c o u n t ( * ) " cuenta todos los registros, i n c l u i d o s los q u e c o n t i e n e n " n u l l " .


31 - A g r u p a r registros ( g r o u p by)

H e m o s a p r e n d i d o q u e l a s f u n c i o n e s de g r u p o permiten r e a l i z a r varios c á l c u l o s

o p e r a n d o con conjuntos de registros.

Las f u n c i o n e s d e g r u p o s o l a s producen u n v a l o r d e r e s u m e n para todos los registros

de u n c a m p o .

P o d e m o s g e n e r a r v a l o r e s d e r e s u m e n para u n solo c a m p o , c o m b i n a n d o l a s

f u n c i o n e s d e a g r e g a d o con l a c l á u s u l a " g r o u p by", q u e a g r u p a registros para

consultas detalladas.

Q u e r e m o s s a b e r l a c a n t i d a d de l i b r o s d e cada e d i t o r i a l , p o d e m o s t i p e a r la s i g u i e n t e

sentencia:

select count(*) from libros

where editorial='Planeta';

y repetirla con cada v a l o r d e " e d i t o r i a l " :

select count(*) from libros

where editorial='Emece';

select count(*) from libros

where editorial='Paidos';

Pero hay otra m a n e r a , u t i l i z a n d o l a c l á u s u l a " g r o u p by":

select editorial, count(*)

from libros

group by editorial;

La i n s t r u c c i ó n a n t e r i o r s o l i c i t a q u e muestre el n o m b r e de l a e d i t o r i a l y cuente la

c a n t i d a d a g r u p a n d o l o s registros por el c a m p o " e d i t o r i a l " . C o m o r e s u l t a d o a p a r e c e n

l o s n o m b r e s de l a s e d i t o r i a l e s y la c a n t i d a d de registros para cada v a l o r d e l c a m p o .

Los valores n u l o s se procesan como otro g r u p o .

E n t o n c e s , para s a b e r l a c a n t i d a d de l i b r o s q u e t e n e m o s de cada e d i t o r i a l , u t i l i z a m o s

l a f u n c i ó n " c o u n t ( ) " , a g r e g a m o s " g r o u p by" ( q u e a g r u p a registros) y el c a m p o por el

q u e d e s e a m o s q u e se r e a l i c e el a g r u p a m i e n t o , t a m b i é n c o l o c a m o s el n o m b r e d e l

c a m p o a recuperar; l a s i n t a x i s básica es l a s i g u i e n t e :

select CAMPO, FUNCIONDEAGREGADO

from NOMBRETABLA

group by CAMPO;
También se p u e d e a g r u p a r por más de u n c a m p o , en tal caso, l u e g o d e l " g r o u p by"

se l i s t a n los c a m p o s , separados por c o m a s . Todos l o s c a m p o s q u e se especifican en

l a c l á u s u l a " g r o u p by" d e b e n estar e n l a l i s t a de s e l e c c i ó n .

select CAMPOl, CAMP02, FUNCIONDEAGREGADO

from NOMBRETABLA

group by CAMP01,CAMP02;

Para o b t e n e r l a c a n t i d a d l i b r o s con precio no n u l o , de cada e d i t o r i a l u t i l i z a m o s l a

f u n c i ó n " c o u n t ( ) " e n v i á n d o l e como a r g u m e n t o el c a m p o " p r e c i o " , a g r e g a m o s " g r o u p

by" y el c a m p o por el q u e deseamos q u e se r e a l i c e el a g r u p a m i e n t o ( e d i t o r i a l ) :

select editorial, count(precio)

from libros

group by editorial;

C o m o r e s u l t a d o aparecen l o s n o m b r e s de l a s e d i t o r i a l e s y la c a n t i d a d de registros de

cada u n a , s i n contar l o s q u e t i e n e n precio n u l o .

Recuerde l a diferencia de los valores q u e retorna la f u n c i ó n " c o u n t ( ) " c u a n d o

e n v i a m o s como a r g u m e n t o u n asterisco o el n o m b r e de u n c a m p o : en el p r i m e r caso

cuenta todos l o s registros i n c l u y e n d o l o s q u e t i e n e n v a l o r n u l o , en el s e g u n d o , los

registros e n l o s c u a l e s el c a m p o especificado es no n u l o .

Para conocer e l total d e l i b r o s a g r u p a d o s por e d i t o r i a l :

select editorial, sum(cantidad)

from libros

group by editorial;

Para s a b e r el m á x i m o y m í n i m o v a l o r d e l o s l i b r o s a g r u p a d o s por e d i t o r i a l :

select editorial,

max(precio) as mayor,

min(precio) as menor

from libros

group by editorial;

Para c a l c u l a r el p r o m e d i o d e l v a l o r de l o s l i b r o s a g r u p a d o s p o r e d i t o r i a l :

select editorial, avg(precio)

from libros

group by editorial;

Es p o s i b l e l i m i t a r l a c o n s u l t a con " w h e r e " .

S i i n c l u y e u n a c l á u s u l a " w h e r e " , s ó l o se a g r u p a n l o s registros q u e c u m p l e n l a s

condiciones.

Vamos a contar y a g r u p a r por e d i t o r i a l c o n s i d e r a n d o s o l a m e n t e l o s l i b r o s cuyo precio

sea m e n o r a 30 pesos:
select editorial, count(*)

from libros

where precio<30

group by editorial;

Note q u e l a s e d i t o r i a l e s q u e no t i e n e n l i b r o s q u e c u m p l a n la c o n d i c i ó n , no aparecen

en l a s a l i d a .

E n t o n c e s , u s a m o s " g r o u p by" para o r g a n i z a r registros e n g r u p o s y o b t e n e r u n

r e s u m e n d e d i c h o s g r u p o s . Oracle p r o d u c e u n a c o l u m n a de valores por cada g r u p o ,

d e v o l v i e n d o f i l a s por cada g r u p o e s p e c i f i c a d o .
3 2 - Seleccionar grupos (Having)

Así como l a c l á u s u l a "where" p e r m i t e s e l e c c i o n a r (o rechazar) registros i n d i v i d u a l e s ;

l a c l á u s u l a " h a v i n g " p e r m i t e s e l e c c i o n a r (o rechazar) u n g r u p o de registros.

S i q u e r e m o s s a b e r l a c a n t i d a d de l i b r o s a g r u p a d o s por e d i t o r i a l u s a m o s la s i g u i e n t e

i n s t r u c c i ó n ya a p r e n d i d a :

select editorial, count(*)

from libros

group by editorial;

S i q u e r e m o s s a b e r l a c a n t i d a d de l i b r o s a g r u p a d o s por e d i t o r i a l pero c o n s i d e r a n d o

s ó l o a l g u n o s g r u p o s , por e j e m p l o , l o s q u e d e v u e l v a n u n v a l o r mayor a 2 , u s a m o s la

siguiente instrucción:

select editorial, count(*) from libros

group by editorial

having count(*)>2;

Se u t i l i z a " h a v i n g " , s e g u i d o d e l a c o n d i c i ó n d e b ú s q u e d a , para s e l e c c i o n a r ciertas

f i l a s retornadas por l a c l á u s u l a " g r o u p b y " .

Veamos otros e j e m p l o s . Q u e r e m o s el p r o m e d i o de l o s precios a g r u p a d o s por

e d i t o r i a l , pero s o l a m e n t e d e a q u e l l o s g r u p o s cuyo p r o m e d i o supere l o s 25 pesos:

select editorial, avg(precio) from libros

group by editorial

having avg(precio)>25;

E n a l g u n o s casos es p o s i b l e c o n f u n d i r l a s c l á u s u l a s "where" y " h a v i n g " . Q u e r e m o s

contar l o s registros a g r u p a d o s por e d i t o r i a l s i n t e n e r en cuenta a la e d i t o r i a l

"Planeta".

Analicemos las siguientes sentencias:

select editorial, count(*) from libros

where editorial<>'Planeta'

group by editorial;

select editorial, count(*) from libros

group by editorial

having editorial<>'Planeta';

Ambas d e v u e l v e n el m i s m o r e s u l t a d o , pero son diferentes. La p r i m e r a , s e l e c c i o n a

todos l o s registros rechazando los de e d i t o r i a l " P l a n e t a " y l u e g o los a g r u p a para

c o n t a r l o s . La s e g u n d a , s e l e c c i o n a todos l o s registros, l o s a g r u p a para contarlos y

f i n a l m e n t e rechaza f i l a con l a cuenta c o r r e s p o n d i e n t e a l a e d i t o r i a l " P l a n e t a " .


N o d e b e m o s c o n f u n d i r l a c l á u s u l a "where" con l a c l á u s u l a " h a v i n g " ; la p r i m e r a

establece c o n d i c i o n e s para l a selección de registros de u n "select"; l a s e g u n d a

establece c o n d i c i o n e s para l a s e l e c c i ó n de registros de u n a s a l i d a " g r o u p by".

Veamos otros e j e m p l o s c o m b i n a n d o "where" y " h a v i n g " . Q u e r e m o s l a c a n t i d a d de

l i b r o s , s i n c o n s i d e r a r l o s q u e t i e n e n precio n u l o , a g r u p a d o s por e d i t o r i a l , s i n

considerar la editorial "Planeta":

select editorial, count(*) from libros

where precio is not null

group by editorial

having editorial<>'Planeta';

A q u í , s e l e c c i o n a l o s registros rechazando l o s q u e no c u m p l a n con la c o n d i c i ó n d a d a

en " w h e r e " , l u e g o l o s a g r u p a por " e d i t o r i a l " y f i n a l m e n t e rechaza los g r u p o s q u e no

c u m p l a n con l a c o n d i c i ó n d a d a en el " h a v i n g " .

Se e m p l e a l a c l á u s u l a " h a v i n g " con f u n c i o n e s d e g r u p o , esto no p u e d e h a c e r l o l a

c l á u s u l a " w h e r e " . P o r e j e m p l o q u e r e m o s el p r o m e d i o d e l o s precios a g r u p a d o s por

e d i t o r i a l , de a q u e l l a s e d i t o r i a l e s q u e t i e n e n m á s de 2 l i b r o s :

select editorial, avg(precio) from libros

group by editorial

having count(*) > 2;

En u n a c l á u s u l a " h a v i n g " puede h a b e r varias condiciones. C u a n d o utilice varias

c o n d i c i o n e s , t i e n e q u e c o m b i n a r l a s con operadores l ó g i c o s ( a n d , or, n o t ) .

P o d e m o s e n c o n t r a r el m a y o r v a l o r de los l i b r o s a g r u p a d o s y o r d e n a d o s por e d i t o r i a l y

s e l e c c i o n a r l a s f i l a s q u e t e n g a n u n v a l o r m e n o r a 1 0 0 y mayor a 3 0 :

select editorial, max(precio) as mayor

from libros

group by editorial

having min(precio)<100 and

min(precio)>30

arder by editorial;

E n t o n c e s , u s a m o s l a c l a u s u l a " h a v i n g " para r e s t r i n g i r l a s f i l a s q u e d e v u e l v e u n a

s a l i d a " g r o u p b y " . Va s i e m p r e d e s p u é s d e l a c l á u s u l a " g r o u p by" y antes d e l a

c l á u s u l a "arder by" s i l a h u b i e r e .
3 3 - Registros d u p l i c a d o s ( D i s t i n c t )

C o n l a c l á u s u l a " d i s t i n c t " se especifica q u e los registros con ciertos datos d u p l i c a d o s

sean o b v i a d a s en el r e s u l t a d o . P o r e j e m p l o , q u e r e m o s conocer todos l o s autores de

l o s c u a l e s t e n e m o s l i b r o s , si u t i l i z a m o s esta s e n t e n c i a :

select autor from libros;

Aparecen r e p e t i d o s . Para obtener l a lista de autores s i n repetición u s a m o s :

select distinct autor from libros;

También p o d e m o s t i p e a r :

select autor from libros

group by autor;

Note q u e en l o s tres casos anteriores aparece " n u l l " como u n v a l o r para " a u t o r " · S i

s ó l o q u e r e m o s l a l i s t a de autores c o n o c i d o s , es decir, no q u e r e m o s i n c l u i r " n u l l " e n l a

lista, podemos utilizar la sentencia s i g u i e n t e :

select distinct autor from libros

where autor is not null;

Para contar l o s d i s t i n t o s a u t o r e s , s i n c o n s i d e r a r el v a l o r " n u l l " u s a m o s :

select count(distinct autor)

from libros;

Note q u e si contamos l o s autores s i n " d i s t i n c t " , no i n c l u i r á los valores " n u l l " pero si

los repetidos:

select count(autor)

from libros;

Esta s e n t e n c i a c u e n t a l o s registros q u e t i e n e n autor.

P o d e m o s c o m b i n a r l a con " w h e r e " . Por e j e m p l o , q u e r e m o s c o n o c e r l o s distintos

autores de l a e d i t o r i a l " P l a n e t a " :

select distinct autor from libros

where editorial='Planeta';

También p u e d e u t i l i z a r s e con " g r o u p by" para contar los diferentes autores por

editorial:

select editorial, count(distinct autor)

from libros

group by editorial;
La c l á u s u l a " d i s t i n c t " afecta a todos los c a m p o s p r e s e n t a d o s . Para mostrar los títulos

y e d i t o r i a l e s de l o s l i b r o s s i n repetir t í t u l o s n i e d i t o r i a l e s , u s a m o s :

select distinct titulo,editorial

from libros

arder by titulo;

Note q u e los registros no están d u p l i c a d o s , aparecen t í t u l o s i g u a l e s pero con e d i t o r i a l

diferente, cada registro es diferente.

E n t o n c e s , " d i s t i n c t " e l i m i n a registros d u p l i c a d o s .


3 4 - Clave p r i m a r i a c o m p u e s t a

Las claves p r i m a r i a s p u e d e n ser s i m p l e s , formadas por u n s o l o c a m p o o

c o m p u e s t a s , m á s de u n c a m p o .

Recordemos q u e u n a clave p r i m a r i a identifica u n s o l o registro en u n a t a b l a .

Para u n v a l o r d e l c a m p o clave existe s o l a m e n t e u n registro. Los valores no se repiten

n i p u e d e n ser n u l o s .

Existe u n a p l a y a de e s t a c i o n a m i e n t o q u e a l m a c e n a cada d í a l o s datos d e l o s

v e h í c u l o s q u e i n g r e s a n en l a t a b l a l l a m a d a " v e h i c u l o s " con l o s s i g u i e n t e s c a m p o s :

- patente char(6) not null,

- tipo char (1), ' a ' = auto, 'm'=moto,

- horallegada date,

- horasalida date,

Necesitamos d e f i n i r u n a clave p r i m a r i a para u n a t a b l a con los datos descriptos a r r i b a .

N o p o d e m o s u s a r s o l a m e n t e l a patente porque u n m i s m o auto p u e d e i n g r e s a r m á s

de u n a vez en el d í a a l a p l a y a ; t a m p o c o p o d e m o s u s a r l a hora de entrada p o r q u e

varios autos p u e d e n i n g r e s a r a u n a m i s m a h o r a . Tampoco s i rv e n l o s otros c a m p o s .

C o m o n i n g ú n c a m p o , por si s ó l o c u m p l e con l a c o n d i c i ó n para ser clave, es decir,

d e b e i d e n t i f i c a r u n s o l o registro, el v a l o r no p u e d e repetirse, d e b e m o s u s a r dos

campos.

D e f i n i m o s u n a clave c o m p u e s t a c u a n d o n i n g ú n c a m p o p o r si s o l o c u m p l e con l a

c o n d i c i ó n para ser c l a v e .

E n este e j e m p l o , u n auto p u e d e i n g r e s a r varias veces e n u n d í a a l a p l a y a , pero

s i e m p r e será a d i s t i n t a h o r a .

U s a m o s 2 campos como c l a v e , l a patente j u n t o con l a hora de l l e g a d a , a s í

i d e n t i f i c a m o s u n í v o c a m e n t e cada registro.

Para establecer m á s d e u n c a m p o como clave p r i m a r i a u s a m o s l a s i g u i e n t e s i n t a x i s :

create table vehiculos(

patente char(6) not null,

tipo char(l),--'a'=auto, 'm'=moto

horallegada date,

horasalida date,

primary key(patente,horallegada)

) ;

N o m b r a m o s l o s c a m p o s q u e formarán parte d e l a clave separados por c o m a s .


Al i n g r e s a r l o s registros, O r a c l e controla q u e l o s valores para l o s campos

e s t a b l e c i d o s como clave p r i m a r i a no estén repetidos en la t a b l a ; si estuviesen

r e p e t i d o s , muestra u n mensaje y l a i n s e r c i ó n no se r e a l i z a . Lo m i s m o sucede s i

realizamos u n a actualización.

Para ver l a clave p r i m a r i a d e u n a t a b l a p o d e m o s realizar l a s i g u i e n t e c o n s u l t a :

select uc.table_name, column_name, position from user cons columns ucc

join user_constraints uc

on ucc.constraint name=uc.constraint name

where uc.constraint_type='P' and

uc.table_name='VEHICULOS';

E n t o n c e s , si u n s o l o c a m p o no identifica u n í v o c a m e n t e u n registro p o d e m o s d e f i n i r

u n a clave p r i m a r i a c o m p u e s t a , es d e c i r formada por m á s de u n c a m p o .


3 5 - S e c u e n c i a s (create s e q u e n c e - c u r r v a l -

nextval - drop s e q u e n c e )

H e m o s a p r e n d i d o q u e existen varios objetos de base d e datos, hasta ahora h e m o s visto

TABLAS y a l g u n a s F U N C I O N E S p r e d e f i n i d a s . Otro objeto de base de datos es la

secuencia.

U n a s e c u e n c i a ( s e q u e n c e ) se e m p l e a para g e n e r a r valores enteros s e c u e n c i a l e s ú n i c o s y

a s i g n á r s e l o s a c a m p o s n u m é r i c o s ; se u t i l i z a n g e n e r a l m e n t e para l a s claves p r i m a r i a s de

l a s t a b l a s g a r a n t i z a n d o q u e s u s valores no se r e p i t a n .

U n a s e c u e n c i a es u n a tabla con u n campo n u m é r i c o en el c u a l se a l m a c e n a u n valor y

cada vez q u e se c o n s u l t a , se i n c r e m e n t a tal valor para l a próxima c o n s u l t a .

Sintaxis general:

create sequence NOMBRESECUENCIA

start with VALORENTERO

increment by VALORENTERO

maxvalue VALORENTERO

minvalue VALORENTERO

cycle I nocycle;

- L a c l á u s u l a "start with" i n d i c a el v a l o r d e s d e el c u a l comenzará la g e n e r a c i ó n de

n ú m e r o s s e c u e n c i a l e s . S i no se especifica, se i n i c i a con el valor q u e i n d i q u e " m i n v a l u e " .

- L a c l á u s u l a " i n c r e m e n t by" especifica el i n c r e m e n t o , es decir, l a d i f e r e n c i a entre los

n ú m e r o s de la s e c u e n c i a ; d e b e s e r u n v a l o r n u m é r i c o entero positivo o negativo diferente

de O . S i no se i n d i c a , por defecto es 1 .

- " m a x v a l u e " d e f i n e el valor m á x i m o para la s e c u e n c i a . S i se o m i t e , por defecto es

99999999999999999999999999.

- " m i n v a l u e " establece el v a l o r m í n i m o d e la s e c u e n c i a . Si se o m i t e será 1 .

- L a c l á u s u l a "cycle" i n d i c a q u e , c u a n d o la s e c u e n c i a l l e g u e a m á x i m o valor (valor d e

" m a x v a l u e " ) se r e i n i c i e , c o m e n z a n d o con el m í n i m o v a l o r ( " m i n v a l u e " ) n u e v a m e n t e , es

decir, la s e c u e n c i a v u e l v e a u t i l i z a r l o s n ú m e r o s . S i se o m i t e , por defecto la s e c u e n c i a se

crea " n o c y c l e " .

S i no se especifica n i n g u n a c l á u s u l a , excepto el n o m b r e de la s e c u e n c i a , por defecto,

comenzará en 1 , se incrementará en 1 , el m í n i m o v a l o r será 1 , el m á x i m o será

999999999999999999999999999 y "nocycle".

E n el s i g u i e n t e e j e m p l o creamos u n a s e c u e n c i a l l a m a d a " s e c _ c o d i g o l i b r o s " ,

e s t a b l e c i e n d o q u e c o m i e n c e en 1 , s u s valores estén entre 1 y 99999 y se i n c r e m e n t e n en

1 , por defecto, será "nocycle":

create sequence sec_codigolibros

start with 1
increment by 1

maxvalue 99999

minvalue 1;

S i b i e n , las s e c u e n c i a s son i n d e p e n d i e n t e s de l a s t a b l a s , se u t i l i z a r á n g e n e r a l m e n t e para

u n a tabla específica, por lo tanto, es c o n v e n i e n t e d a r l e u n n o m b r e q u e referencie a la

misma.

Otro e j e m p l o :

create sequence sec numerosocios

increment by 5

cycle;

La s e c u e n c i a anterior, "sec_numerosocios", i n c r e m e n t a s u s valores en 5 y a l l l e g a r al

m á x i m o v a l o r recomenzará la s e c u e n c i a d e s d e el valor m í n i m o ; no se especifican l a s

otras c l á u s u l a s , por lo tanto, por defecto, el valor m í n i m o es 1 , el m á x i m o

9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 y el v a l o r i n i c i a l es 1 .

D i j i m o s q u e l a s s e c u e n c i a s son t a b l a s ; por lo tanto se accede a e l l a s m e d i a n t e c o n s u l t a s ,

e m p l e a n d o "select". La diferencia es q u e u t i l i z a m o s p s e u d o c o l u m n a s para recuperar el

valor actual y el s i g u i e n t e de la s e c u e n c i a . Estas p s e u d o c o l u m n a s p u e d e n i n c l u i r s e en el

"from" de u n a c o n s u l t a a otra t a b l a o de la t a b l a " d u a l " .

Para recuperar los valores d e u n a s e c u e n c i a e m p l e a m o s l a s p s e u d o c o l u m n a s " c u r rv a l " y

"nextval".

P r i m e r o d e b e i n i c i a l i z a r s e la s e c u e n c i a con " n e x t v a l " . La p r i m e r a vez q u e se referencia

"nextval" retorna el v a l o r d e i n i c i o de la s e c u e n c i a ; l a s s i g u i e n t e s veces, incrementa la

s e c u e n c i a y nos retorna el n u e v o v a l o r :

NOMBRESECUENCIA.NEXTVAL;

se coloca el n o m b r e de l a s e c u e n c i a s e g u i d o de u n punto y la p s e u d o c o l u m n a "nextval"

( q u e es u n a forma abreviada de "next v a l u e " , s i g u i e n t e v a l o r ) .

Para recuperar el v a l o r actual de u n a s e c u e n c i a u s a m o s :

NOMBRESECUENCIA.CURRVAL;

es decir, el n o m b r e de la s e c u e n c i a , u n p u n t o y l a p s e u d o c o l u m n a " c u r rv a l " ( q u e es u n a

forma abreviada de "current v a l u e " , valor a c t u a l ) .

Los valores retornados por " c u r rv a l " y "nextval" p u e d e n usarse en s e n t e n c i a s " i n s e rt " y

"update".

Veamos u n e j e m p l o c o m p l e t o :

C r e a m o s u n a s e c u e n c i a para el c ó d i g o de la tabla " l i b r o s " , e s p e c i f i c a n d o el v a l o r m á x i m o ,

el incremento y q u e no sea c i r c u l a r :

create sequence sec_codigolibros

maxvalue 999999

increment by 1

nocycle;
L u e g o i n i c i a l i z a m o s la s e c u e n c i a

select sec_codigolibros.nextval from dual;

Recuerde q u e la primera vez q u e se referencie l a s e c u e n c i a debe e m p l e a r s e "nextval"

para i n i c i a l i z a r l a .

I n g r e s a m o s u n registro en " l i b r o s " , a l m a c e n a n d o en el c a m p o "codigo" el valor actual d e

la secuencia:

insert into libros values

(sec_codigolibros.currval, ' E l aleph', 'Borges·, 'Emece');

I n g r e s a m o s otro registro en " l i b r o s " , a l m a c e n a n d o en el c a m p o "codigo" el v a l o r s i g u i e n t e

de la s e c u e n c i a :

insert into libros values

(sec_codigolibros.nextval, 'Matematica estas ahi', ' P a e n z a ' , 'Nuevo siglo');

Para ver todas l a s s e c u e n c i a s de l a base de datos actual r e a l i z a m o s la s i g u i e n t e

consulta:

select *from all_sequences;

N o s muestra el propietario d e l a s e c u e n c i a , el n o m b r e d e la m i s m a , los valores m í n i m o y

m á x i m o , el valor de i n c r e m e n t o y si es c i r c u l a r o n o , entre otros datos q u e no

a n a l i z a r e m o s por el m o m e n t o .

También p o d e m o s ver todos los objetos de l a base d e datos actual t i p e a n d o ;

select *from all_objects;

E n la tabla resultado aparecen todos los objetos de la base de datos, i n c l u i d a s l a s

s e c u e n c i a s ; si es u n a s e c u e n c i a e n la c o l u m n a O B J E C T_TYPE se muestra

"SEQUENCE".

Podemos c o n s u l t a r "all_objects" especificando q u e nos muestre el n o m b r e d e todas las

secuencias:

select object_name from all_objects

where object_type='SEQUENCE';

Para e l i m i n a r u n a s e c u e n c i a e m p l e a m o s "drop s e q u e n c e " . S i n t a x i s :

drop sequence NOMBRESECUENCIA;

S i l a s e c u e n c i a no existe aparecerá u n mensaje i n d i c a n d o tal s i t u a c i ó n .

E n el s i g u i e n t e e j e m p l o se e l i m i n a la s e c u e n c i a " s e c _ c o d i g o l i b r o s " :

drop sequence sec_codigolibros;


3 6 - Alterar s e c u e n c i a ( a l t e r s e q u e n c e )

Es p o s i b l e m o d i f i c a r u n a s e c u e n c i a , su v a l o r de i n c r e m e n t o , los valores m í n i m o y

m á x i m o y el atributo "cycle" ( e l v a l o r de i n i c i o no p u e d e m o d i f i c a r s e ) ; para e l l o

empleamos la sentencia "alter sequence". Sintaxis:

alter sequence NOMBRESECUENCIA ATRIBUTOSAMODIFICAR;

D e f i n i m o s u n a s e c u e n c i a d e n o m i n a d a "sec_codigolibros" con los s i g u i e n t e s a t r i b u t o s :

create sequence sec_codigolibros

start with 1

increment by 1

maxvalue 999

minvalue 1

nocycle;

Para m o d i f i c a r e l m á x i m o v a l o r a 99999 y el i n c r e m e n t o a 2 , t i p e a m o s :

alter sequence sec_codigolibros

increment by 2

maxvalue 99999;

Los valores de i n c r e m e n t o y m í n i m o h a n s i d o m o d i f i c a d o s , l o s d e m á s atributos no

especificados e n l a s e n t e n c i a " a l t e r s e q u e n c e " se m a n t i e n e n .


3 7 - Integridad de datos

Es i m p o rt a n t e , a l d i s e ñ a r u n a base de datos y l a s t a b l a s q u e c o n t i e n e , t e n e r e n

cuenta l a i n t e g r i d a d d e l o s datos, esto s i g n i f i c a q u e la i n f o r m a c i ó n a l m a c e n a d a en l a s

t a b l a s d e b e ser v á l i d a , coherente y exacta.

Hasta el m o m e n t o , h e m o s controlado y r e s t r i n g i d o l a entrada de valores a u n c a m p o

m e d i a n t e el t i p o de dato q u e l e d e f i n i m o s ( c a d e n a , n u m é r i c o s , e t c . ) , l a aceptación o

no d e valores n u l o s , el v a l o r por defecto. También h e m o s a s e g u r a d o q u e cada

registro de u n a t a b l a sea ú n i c o d e f i n i e n d o u n a clave p r i m a r i a y e m p l e a n d o

secuencias.

O r a c l e ofrece más a l t e r n a t i v a s , a d e m á s de l a s a p r e n d i d a s , para r e s t r i n g i r y v a l i d a r

l o s datos, l a s veremos o r d e n a d a m e n t e y a l f i n a l i z a r h a r e m o s u n r e s u m e n de l a s

mismas.

C o m e n z a m o s por l a s restricciones.

Las restricciones ( constraints) son u n método para m a n t e n e r la i n t e g r i d a d de los

datos, a s e g u r a n d o q u e l o s valores i n g r e s a d o s sean v á l i d o s y q u e l a s r e l a c i o n e s entre

l a s t a b l a s se m a n t e n g a .

Las restricciones p u e d e n establecerse a n i v e l de c a m p o o de t a b l a .

P u e d e n definirse a l crear l a t a b l a ("create t a b l e " ) o agregarse a u n a t a b l a existente

( e m p l e a n d o " a l t e r t a b l e " ) y se p u e d e n a p l i c a r a u n c a m p o o a v a r i o s . T a m b i é n es

posible habilitarlas y deshabilitarlas.

O r a c l e ofrece v a r i o s t i p o s d e restricciones:

- not n u l l : a n i v e l de c a m p o .

- p r i m a ry key: a n i v e l d e t a b l a . Es u n c a m p o o varios q u e identifican cada registro de

una tabla.

- foreign key: a n i v e l d e t a b l a . Establece q u e u n c a m p o ( o varios) r e l a c i o n e u n a clave

p r i m a r i a d e u n a t a b l a con otra.

- c h e c k : a n i v e l d e t a b l a . Restringe l o s valores q u e p u e d e n ingresarse en u n c a m p o

especifico.

- u n i q u e : a n i v e l de t a b l a .

Se p u e d e n crear, m o d i f i c a r y e l i m i n a r l a s restricciones s i n e l i m i n a r la t a b l a y volver a

crearla.
Para o b t e n e r i n f o r m a c i ó n d e l a s restricciones p o d e m o s c o n s u l t a r l o s catálogos

"all_objects", "all_constraints" y " a l l _ c o n s _ c o l u m n s " .

E l catálogo "all_constraints" retorna varias c o l u m n a s , entre e l l a s : O W N E R

( p r o p i e t a r i o ) , C O N S T R A I N T _ N A M E ( n o m b r e d e l a restricción), C O N S T R A I N T _ T Y P E

(tipo d e restricción, si es p r i m a ry key ( P ) , foreign key ( ) , u n i q u e ( U ) , e t c . ) ,

TABLE_NAME ( n o m b r e d e la t a b l a ) , S E A R C H _ C O N D I T I O N (en caso de ser C h e c k u

otra), D E L E T E _ R U L E ( ) , STATUS ( e s t a d o ) , D E F E R R A B L E ( ) , D E F E R R E D ( ) ,

VALIDATED ( ) , G E N E R A T E D ( ) , I N D E X _ O W N E R ( ) , I N D E X _ N A M E ( ) .

E l catálogo " a l l _ c o n s _ c o l u m n a s " retorna l a s s i g u i e n t e s c o l u m n a s : O W N E R

( p r o p i e t a r i o ) , C O N S T R A I N T_ N A M E ( n o m b r e ) , TABLE_NAME ( n o m b r e de l a t a b l a ) ,

COLUMN_NAME (campo), POSITION (posición).


3 8 - Restricción pri mary key

La restricción " p r i m a ry key" a s e g u r a q u e l o s valores sean ú n i c o s para cada registro.

A n t e r i o r m e n t e , para establecer u n a clave p r i m a r i a para u n a t a b l a e m p l e á b a m o s la

s i g u i e n t e s i n t a x i s a l crear l a t a b l a , por e j e m p l o :

create table libros(

codigo int not null,

titulo varchar(30),

autor varchar(30),

editorial varchar(20),

primary key(codigo)

) ;

C a d a vez q u e e s t a b l e c í a m o s l a clave p r i m a r i a para l a t a b l a , Oracle creaba

a u t o m á t i c a m e n t e u n a restricción " p r i m a ry key" para d i c h a t a b l a . D i c h a restricción, a

l a c u a l no l e d á b a m o s u n n o m b r e , recibía u n n o m b r e dado por Oracle q u e consta d e

u n a serie d e letras y n ú m e r o s a l e a t o r i o s .

P o d e m o s a g r e g a r u n a restricción " p r i m a ry key" a u n a t a b l a existente con l a s i n t a x i s

básica s i g u i e n t e :

alter table NOMBRETABLA

add constraint NOMBRECONSTRAINT

primary key (CAMPO, . . . ) ;

E n el s i g u i e n t e e j e m p l o d e f i n i m o s u n a restricción " p r i m a ry key" para nuestra t a b l a

" l i b r o s " para a s e g u r a r n o s q u e cada l i b r o t e n d r á u n c ó d i g o diferente y ú n i c o :

alter table libros

add constraint PK_libros_codigo

primary key(codigo);

C o n esta restricción, si i n t e n t a m o s i n g r e s a r u n registro con u n v a l o r para el c a m p o

" c o d i g o " q u e ya existe o el v a l o r " n u l l " , aparece u n m e n s a j e de error, p o r q u e n o se

permiten valores d u p l i c a d o s n i n u l o s . I g u a l m e n t e , si a c t u a l i z a m o s .

Por c o n v e n c i ó n , c u a n d o d e m o s el n o m b r e a l a s restricciones " p r i m a r y key"

s e g u i r e m o s el formato " P K _ N O M B R E T A B L A _ N O M B R E C A M P O " .

C u a n d o a g r e g a m o s u n a restricción a u n a t a b l a q u e c o n t i e n e i n f o r m a c i ó n , Oracle

controla los datos existentes para confirmar q u e c u m p l e n l a s e x i g e n c i a s de la

restricción, si no l o s c u m p l e , l a restricción no se a p l i c a y aparece u n mensaje de

error. P o r e j e m p l o , si i n t e n t a m o s d e f i n i r l a restricción " p r i m a r y key" para " l i b r o s " y hay

registros con c ó d i g o s repetidos o con u n v a l o r " n u l l " , l a restricción no se e s t a b l e c e .


C u a n d o e s t a b l e c í a m o s u n a clave p r i m a r i a al d e f i n i r l a t a b l a , a u t o m á t i c a m e n t e Oracle

redefinía el c a m p o como "not n u l l " ; l o m i s m o s u c e d e al a g r e g a r u n a restricción

" p r i m a ry key", l o s c a m p o s q u e se e s t a b l e c e n como clave p r i m a r i a se redefinen

a u t o m á t i c a m e n t e "not n u l l " .

Se p e r m i t e d e f i n i r s o l a m e n t e u n a restricción " p r i m a ry key" por t a b l a , q u e a s e g u r a l a

u n i c i d a d de cada registro d e u n a t a b l a .

S i c o n s u l t a m o s el catálogo "user_constraints", podemos ver l a s restricciones " p r i m a ry

key" (y todos l o s t i p o s d e restricciones) d e todas l a s t a b l a s d e l u s u a r i o a c t u a l . E l

r e s u l t a d o es u n a t a b l a q u e nos informa el propietario de l a restricción ( O W N E R ) , el

n o m b r e de l a restricción ( C O N S T R A I N T_ N A M E ) , el t i p o ( C O N S T R A I N T_T Y P E , si es

" p r i m a ry key" muestra u n a " P " ) , el n o m b r e de l a t a b l a en l a c u a l se a p l i c a

( T A B L E _ N A M E ) , y otra i n f o r m a c i ó n q u e no a n a l i z a r e m o s por el m o m e n t o .

También p o d e m o s c o n s u l t a r el catálogo " u s e r _ c o n s _ c o l u m n s " ; nos mostrará el

propietario de l a restricción ( O W N E R ) , el n o m b r e d e l a restricción

( C O N S T R A I N T_ N A M E ) , l a t a b l a a l a c u a l se a p l i c a ( T A B L E _ N A M E ) , el c a m p o

( C O L U M N _ N A M E ) y la posición ( P O S I T I O N ) .
3 9 - Restricción u n i q u e

Anteriormente a p r e n d i m o s l a restricción " p r i m a r y key", otra restricción q u e a s e g u r a

valores ú n i c o s para cada registro es " u n i q u e " .

La restricción " u n i q u e " i m p i d e l a d u p l i c a c i ó n d e claves a l t e r n a s ( n o p r i m a r i a s ) , es

decir, especifica q u e d o s registros no p u e d a n t e n e r el m i s m o v a l o r en u n c a m p o . Se

permiten valores n u l o s .

Se p u e d e n a p l i c a r varias restricciones de este t i p o a u n a m i s m a t a b l a , y p u e d e n

a p l i c a r s e a u n o o varios c a m p o s q u e n o sean clave p r i m a r i a .

Se e m p l e a c u a n d o ya se estableció u n a clave p r i m a r i a ( como u n n ú m e r o de l e g a j o )

pero se necesita a s e g u r a r q u e otros datos t a m b i é n sean ú n i c o s y no se repitan

(como n ú m e r o d e d o c u m e n t o ) .

La sintaxis g e n e r a l es l a s i g u i e n t e :

alter table NOMBRETABLA

add constraint NOMBRERESTRICCION

unique (CAMPO);

Ejemplo:

alter table alumnos

add constraint U Q_ a l u m n o s _ d o c u m e n t o

unique (documento);

E n el e j e m p l o a n t e r i o r se a g r e g a u n a restricción " u n i q u e " sobre e l c a m p o

" d o c u m e n t o " de l a t a b l a " a l u m n o s " , esto a s e g u r a q u e no se p u e d a i n g r e s a r u n

d o c u m e n t o si ya existe. Esta restricción permite valores n u l o s , a s i q u e si se i n g r e s a

el v a l o r " n u l l " para el c a m p o " d o c u m e n t o " , se a c e p t a .

Por c o n v e n c i ó n , c u a n d o d e m o s el n o m b r e a l a s restricciones " u n i q u e " s e g u i r e m o s l a

m i s m a estructura:

" U Q _ N O M B R E T A B L A _ N O M B R E C A M P O " . Q u i z á parezca i n n e c e s a r i o c o l o c a r el

n o m b r e de l a t a b l a , pero c u a n d o e m p l e e m o s varias t a b l a s verá q u e es ú t i l i d e n t i f i c a r

l a s restricciones por t i p o , t a b l a y c a m p o .

Recuerde q u e c u a n d o a g r e g a m o s u n a restricción a u n a t a b l a q u e c o n t i e n e

i n f o r m a c i ó n , O r a c l e controla l o s datos existentes para c o n f i r m a r q u e c u m p l e n la

c o n d i c i ó n d e l a restricción, si no los c u m p l e , l a restricción no se a p l i c a y aparece u n

mensaje d e error. E n el caso d e l e j e m p l o anterior, si l a t a b l a c o n t i e n e n ú m e r o s de

d o c u m e n t o d u p l i c a d o s , l a restricción n o podrá establecerse; s i podrá establecerse s i

t i e n e valores n u l o s .
O r a c l e controla l a entrada d e datos en i n s e r c i o n e s y a c t u a l i z a c i o n e s evitando q u e se

i n g r e s e n valores d u p l i c a d o s .

U n c a m p o q u e se estableció como clave p r i m a r i a no p u e d e d e f i n i r s e como clave

ú n i c a ; si u n a t a b l a t i e n e u n a clave p r i m a r i a , p u e d e t e n e r u n a o varias claves ú n i c a s

( a p l i c a d a s a otros c a m p o s q u e no sean clave p r i m a r i a ) .

S i c o n s u l t a m o s el catálogo "user_constraints", podemos ver l a s restricciones " u n i q u e "

(y todos los tipos de restricciones) de todas l a s t a b l a s d e l u s u a r i o a c t u a l . El resultado

es u n a t a b l a q u e nos informa el propietario de la restricción ( O W N E R ) , el n o m b r e de

l a restricción ( C O N S T R A I N T_ N A M E ) , el t i p o ( C O N S T R A I N T_T Y P E , s i es " u n i q u e "

muestra u n a " U " ) , el n o m b r e d e l a t a b l a en l a c u a l se a p l i c a (TABLE_NAME), y otra

i n f o r m a c i ó n q u e no a n a l i z a r e m o s por el m o m e n t o .

También p o d e m o s c o n s u l t a r el catálogo " u s e r _ c o n s _ c o l u m n s " ; nos mostrará el

propietario de l a restricción ( O W N E R ) , el n o m b r e d e l a restricción

( C O N S T R A I N T_ N A M E ) , l a t a b l a a l a c u a l se a p l i c a ( T A B L E _ N A M E ) , el c a m p o

( C O L U M N _ N A M E ) y la posición ( P O S I T I O N ) .
40 - Restriccion c h e c k

La restricción "check" especifica los valores q u e acepta u n c a m p o , e v i t a n d o q u e se

i n g r e s e n valores i n a p r o p i a d o s .

La s i n t a x i s básica es l a s i g u i e n t e :

alter table NOMBRETABLA

add constraint NOMBRECONSTRAINT

check CONDICION;

Trabajamos con l a t a b l a " l i b r o s " de u n a l i b r e r í a q u e t i e n e los s i g u i e n t e s c a m p o s :

c o d i g o , t i t u l o , autor, e d i t o r i a l , p r e c i o m i n ( q u e i n d i c a el precio para los m i n o r i s t a s ) y

preciomay ( q u e i n d i c a el precio para los m a y o r i s t a s ) .

Los campos c o r r e s p o n d i e n t e s a los precios ( m i n o r i s t a y mayorista) se definen de t i p o

n u m b e r ( S , 2 ) , es decir, aceptan valores entre - 9 9 9 . 9 9 y 9 9 9 . 9 9 . P o d e m o s controlar

q u e no se i n g r e s e n valores negativos para d i c h o s c a m p o s a g r e g a n d o u n a restricción

"check":

alter table libros

add constraint CK_libros_precio_positivo

check (preciomin>=0 and preciomay>=0);

Este t i p o d e restricción verifica los datos cada vez q u e se ejecuta u n a s e n t e n c i a

" i n s e rt " o " u p d a t e " , es decir, actúa en i n s e r c i o n e s y a c t u a l i z a c i o n e s .

S i l a t a b l a c o n t i e n e registros q u e no c u m p l e n con l a restricción q u e se va a

establecer, l a restricción no se p u e d e establecer, hasta q u e todos los registros

c u m p l a n con d i c h a restricción.

La c o n d i c i ó n p u e d e hacer referencia a otros campos de l a m i s m a t a b l a . Por e j e m p l o ,

p o d e m o s controlar q u e el precio mayorista no sea mayor a l precio m i n o r i s t a :

alter table libros

add constraint CK_libros_preciominmay

check (preciomay<=preciomin);

Por c o n v e n c i ó n , c u a n d o d e m o s el n o m b r e a l a s restricciones "check" s e g u i r e m o s l a

m i s m a estructura: c o m e n z a m o s con " C K " , s e g u i d o d e l n o m b r e d e l a t a b l a , d e l c a m p o

y a l g u n a p a l a b r a con l a c u a l p o d a m o s i d e n t i f i c a r f á c i l m e n t e de q u é se trata la

restricción, por si t e n e m o s varias restricciones " c h e c k " para el m i s m o c a m p o .

U n c a m p o p u e d e t e n e r varias restricciones " c h e c k " y u n a restricción "check" p u e d e

i n c l u i r varios c a m p o s .

Las c o n d i c i o n e s para restricciones "check" t a m b i é n p u e d e n i n c l u i r u n a lista d e

v a l o r e s . Por e j e m p l o establecer q u e cierto c a m p o a s u m a s ó l o l o s valores q u e se


listan:

check (CAMPO in ( ' l u n e s ' , 'miercoles', 'viernes'));

Si u n campo permite valores n u l o s , " n u l l " es u n valor aceptado a u n q u e no esté

i n c l u i d o en la condición de restricción.

Si intentamos establecer u n a restricción "check" para u n campo q u e entra en

conflicto con otra restricción "check" establecida al m i s m o campo, Oracle no lo

permite. Pero si establecemos una restricción "check" para u n campo q u e entra en

conflicto con u n valor "default" establecido para el m i s m o campo, Oracle lo permite;

pero al intentar ingresar u n registro, aparece u n mensaje de error.

En las condiciones de chequeo no es posible i n c l u i r funciones (como "sysdate").

U n campo con u n a restricción " p r i m a ry key" o " u n i q u e " puede tener u n a (o varias)

restricciones "check".

En l a condición de u n a restricción "check" se puede establecer q u e u n campo no

admita valores n u l o s :

alter table libros

add constraint CK libros titulo

check (titulo is not null);


41 - Restricciones: validación y estados (validate - novalidate - e n a b l e

- disable)

Sabemos q u e si agregamos u n a restricción a u n a tabla q u e contiene datos, Oracle los controla para asegurarse

q u e c u m p l e n con l a c o n d i c i ó n de l a restricción, si a l g ú n registro no l a c u m p l e , la restricción no se establecece.

Es p o s i b l e d e s h a b i l i t a r esta comprobación estableciendo u n a restricción s i n comprobar los datos existentes en l a

tabla.

Podemos hacerlo c u a n d o agregamos l a restricción (de c u a l q u i e r t i p o ) a una t a b l a para q u e Oracle acepte los

valores ya a l m a c e n a d o s q u e infringen la restricción. Para e l l o debemos i n c l u i r la opción "novalidate" en la

instrucción "alter t a b l e " :

alter table libros

add constraint PK_libros_codigo

primary key (codigo) novalidate;

La restricción no se aplica en los datos existentes, pero si intentamos ingresar un nuevo valor q u e no c u m p l a la

restricción (o a c t u a l i z a r l o ) , Oracle no lo permite.

Para saber si u n a restricción está v a l i d a d a o n o , podemos c o n s u l t a r el catálogo "user_constraints" y fijarnos lo

q u e informa l a c o l u m n a "validated".

También podemos d e s h a b i l i t a r las restricciones para agregar o actualizar datos sin comprobarla:

alter table libros

add constraint PK_libros_codigo

primary key (codigo) disable;

Entonces, para evitar l a comprobación de datos existentes y futuros al crear la restricción, l a sintaxis básica es l a

siguiente:

alter table TABLA

add constraint NOMBRERESTRICCION

TIPOdeRESTRICCION (CAMPO o CONDICION)--campo si es primary key o unique; condición si es checl

disable novalidate;

Por defecto (si no especificamos) l a opción es "validate", es decir, controla los datos existentes y " e n a b l e " , es

decir, controla futuros ingresos y actualizaciones.

También es p o si b le alterar l a restricción l u e g o de h a b e r l a creado. Sintaxis:

alter table NOMBRETABLA

ESTADO VALIDACION

constraint NOMBRERESTRICCION;

E n el ejemplo s i g u i e n t e d e s h a b i l i t a m o s la restricción "PK_libros_codigo" para poder ingresar u n valor q u e infrija

la restricción:

alter table libros

disable validate

constraint PK_libros_codigo;

Para h a b i l i t a r u n a restricción d e s h a b i l i t a d a se ejecuta l a m i s m a instrucción pero con la c l á u s u l a " e n a b l e " :

alter table libros

enable validate

constraint PK_libros_codigo;

Para saber si u n a restricción está h a b i l i t a d a o n o , podemos consultar el catálogo "user_constraints" y fijarnos lo

q u e informa l a c o l u m n a "status".

Los estados "validate" y "novalidate" son relativamente i n d e p e n d i e n t e s de los estados " e n a b l e d " y " d i s a b l e d " .
C u a n d o h a b i l i t a m o s u n a restricción " p r i m a ry key" o " u n i q u e " con " e n a b l e " , los datos existentes D E B E N c u m p l i r

con la restricción; a u n q u e c o l o q u e m o s "novalidate" junto a " e n a b l e " , Oracle no permite que se h a b i l i t e l a

restrición y v a l i d a los datos existentes de todas maneras. N o sucede lo m i s m o con u n a restricción "check";

podemos h a b i l i t a r u n a restricción de control con " e n a b l e " y "novalidate", Oracle h a b i l i t a la restricción para futuros

ingresos y actualizaciones y N O v a l i d a los datos existentes.

Entonces, " e n a b l e " o " d i s a b l e " activa o desactiva la restricción para los nuevos datos ( " e n a b l e " es la opción

predeterminada si no se especifica); "validate" o "novalidate" es l a opción para v a l i d a r la restricción en los datos

existentes ("va l i d ate" es la predetermidada si se o m i t e ) .

U n a restricción p u e d e estar en los s i g u i e n t e s estados:

- validate y e n a b l e d : comprueba los valores existentes y los posteriores ingresos y a c t u a l i z a c i o n e s ;

- validate y d i s a b l e : comprueba los valores existentes pero no las posteriores inserciones y actualizaciones;

- novalidate y e n a b l e d : no comprueba los datos existentes, pero si los posteriores ingresos y actualizaciones;

- novalidate y d i s a b l e d : no comprueba los valores existentes n i los posteriores ingresos y a c t u a l i z a c i o n e s .


4 2 - Restricciones: i n f o r m a c i ó n

( u s e r_constraints - u s e r_ c o n s _ c o l u m n s )

E l catálogo "user_constraints" muestra l a i n f o r m a c i ó n referente a todas l a s

restricciones e s t a b l e c i d a s en l a s t a b l a s d e l u s u a r i o a c t u a l , d e v u e l v e varias c o l u m n a s ,

e x p l i c a r e m o s a l g u n a s de e l l a s :

- owner: p r o p i e t a r i o d e l a restricción;

- constraints_name: e l n o m b r e de l a restricción;

- constraint_type: t i p o de restricción. S i es u n a restricción de control muestra el

caracter " C " , si es " p r i m a ry key" muestra " P " , si es " u n i q u e " el caracter " U " .

- t a b l e _ n a m e : n o m b r e de l a t a b l a en la c u a l se e s t a b l e c i ó la restricción;

- s e a r c h _ c o n d i t i o n : s o l a m e n t e es a p l i c a b l e a restricciones de c o n t r o l ; i n d i c a la

condición de chequeo a cumplirse.

- status: i n d i c a si está h a b i l i t a d a ( e n a b l e d ) para futuras i n s e r c i o n e s y a c t u a l i z a c i o n e s

o d e s h a b i l i t a d a (d i s a b l e d )

- v a l i d a t e d : i n d i c a si v a l i d a l o s datos existentes en l a t a b l a ( v a l i d a t e d ) o no ( n o

validate)

E l catálogo "user_cons_columns" muestra la i n f o r m a c i ó n referente a todas l a s

restricciones e s t a b l e c i d a s en l a s t a b l a s d e l u s u a r i o a c t u a l , d e v u e l v e l a s s i g u i e n t e s

columnas:

- owner: p r o p i e t a r i o d l a restricción;

- c o n s t r a i n t s _ n a m e : e l n o m b r e de l a restricción;

- t a b l e _ n a m e : n o m b r e de la t a b l a en la c u a l se e s t a b l e c i ó ;

- c o l u m n _ n a m e : muestra c a d a c a m p o en el c u a l la restricción fue a p l i c a d a .

- p o s i t i o n : s o l a m e n t e es a p l i c a b l e a restricciones " p r i m a ry key" y " u n i q u e " ; i n d i c a el

orden en q u e fueron d e f i n i d o s l o s c a m p o s q u e c o m p o n e n la clave ( p r i m a r i a o ú n i c a ) .


4 3 - Restricciones: e l i m i n a c i ó n ( a l t e r t a b l e -

drop constraint)

Para e l i m i n a r u n a restricción, l a sintaxis b á s i c a es l a s i g u i e n t e :

alter table NOMBRETABLA

drop constraint NOMBRERESTRICCION;

Para e l i m i n a r l a restricción "PK_libros_codigo" de l a t a b l a l i b r o s t i p e a m o s :

alter table libros

drop constraint PK_LIBROS_CODIGO;

Recuerde c o l o c a r el n o m b r e de la restricción en m a y ú s c u l a s , s i n o Oracle no la

reconocerá.

C u a n d o e l i m i n a m o s u n a t a b l a , todas l a s restricciones q u e fueron e s t a b l e c i d a s en

e l l a , se e l i m i n a n t a m b i é n .

La c o n d i c i ó n d e control q u e d e b e c u m p l i r u n a restricción de control no p u e d e

modificarse, h a y q u e e l i m i n a r l a restricción y v o l v e r a crearla; i g u a l m e n t e con l a s

restricciones " p r i m a r y key" y " u n i q u e " , no p u e d e n modificarse l o s c a m p o s .


44 - 1 n d i c e s .

Otros objetos d e base de datos son l o s í n d i c e s .

Los í n d i c e s s i rv e n para acceder a l o s registros de u n a t a b l a r á p i d a m e n t e , a c e l e r a n d o

la localización de la información.

Los í n d i c e s se e m p l e a n para f a c i l i t a r la o b t e n c i ó n de i n f o r m a c i ó n de u n a t a b l a . E l

i n d i c e de u n a t a b l a d e s e m p e ñ a la m i s m a f u n c i ó n q u e el í n d i c e de u n l i b r o : p e r m i t e

encontrar datos r á p i d a m e n t e ; en el caso de l a s t a b l a s , l o c a l i z a registros.

O r a c l e accede a l o s datos d e dos m a n e r a s :

1 ) recorriendo l a s t a b l a s ; c o m e n z a n d o el p r i n c i p i o y extrayendo l o s registros q u e

c u m p l e n l a s c o n d i c i o n e s de l a c o n s u l t a ; l o c u a l i m p l i c a p o s i c i o n a r l a s cabezas

lectoras, l e e r el d a t o , c o n t r o l a r si c o i n c i d e con l o q u e se busca ( como si pasáramos

u n a a u n a l a s p á g i n a s de u n l i b r o b u s c a n d o u n tema e s p e c í f i c o ) .

2 ) e m p l e a n d o í n d i c e s ; recorriendo l a estructura de á r b o l d e l í n d i c e para l o c a l i z a r l o s

registros y extrayendo l o s q u e c u m p l e n l a s c o n d i c i o n e s de la c o n s u l t a ( c o m p a r a n d o

con u n l i b r o , d i r e m o s q u e es como l e e r el í n d i c e y l u e g o de encontrar el tema

b u s c a d o , i r directamente a l a p á g i n a i n d i c a d a ) .

U n í n d i c e p o s i b i l i t a el acceso directo y r á p i d o h a c i e n d o m á s eficiente l a s b ú s q u e d a s .

S i n í n d i c e , O r a c l e d e b e recorrer s e c u e n c i a l m e n t e toda la t a b l a para encontrar u n

registro.

Los í n d i c e s son estructuras a s o c i a d a s a t a b l a s , u n a t a b l a q u e a l m a c e n a los c a m p o s

i n d e x a d o s y se crean para a c e l e r a r l a s c o n s u l t a s .

E n t o n c e s , el objetivo de u n i n d i c e es acelerar l a recuperación de i n f o r m a c i ó n . La

i n d e x a c i ó n es u n a técnica q u e o p t i m i z a el acceso a los d a t o s , mejora el r e n d i m i e n t o

a c e l e r a n d o l a s c o n s u l t a s y otras o p e r a c i o n e s . Es útil c u a n d o la tabla c o n t i e n e m i l e s

de registros, c u a n d o se r e a l i z a n o p e r a c i o n e s de o r d e n a m i e n t o y a g r u p a m i e n t o y

c u a n d o se c o m b i n a n varias t a b l a s (tema q u e veremos m á s a d e l a n t e ) .

La desventaja es q u e c o n s u m e e s p a c i o en el d i s c o en d i s c o y g e n e r a costo d e

m a n t e n i m i e n t o ( t i e m p o y recursos).

Es i m p o rt a n t e i d e n t i f i c a r el o l o s c a m p o s por l o s q u e sería ú t i l crear u n í n d i c e ,

a q u e l l o s c a m p o s por l o s c u a l e s se r e a l i z a n b ú s q u e d a s con f r e c u e n c i a : claves

p r i m a r i a s , claves externas o c a m p o s q u e c o m b i n a n t a b l a s .

N o se r e c o m i e n d a crear í n d i c e s sobre c a m p o s q u e no se u s a n con frecuencia en

c o n s u l t a s o en t a b l a s m u y p e q u e ñ a s .
Los c a m b i o s sobre l a t a b l a , c o m o i n s e r c i ó n , a c t u a l i z a c i ó n o e l i m i n a c i ó n de registros,

son incorporados a u t o m á t i c a m e n t e .

C u a n d o creamos u n a restricción " p r i m a ry key" o " u n i q u e " a u n a t a b l a , Oracle

a u t o m á t i c a m e n t e crea u n í n d i c e sobre el c a m p o (o l o s c a m p o s ) de l a restricción y le

da el m i s m o n o m b r e q u e l a restricción. E n caso q u e l a t a b l a ya t e n g a u n í n d i c e ,

O r a c l e l o u s a , n o crea otro.

O r a c l e permite crear d i s t i n t o s tipos de í n d i c e s . " N o r m a l " es el standard d e O r a c l e ,

son í n d i c e s t i p o árbol b i n a r i o ; c o n t i e n e u n a entrada por cada v a l o r d e clave q u e

a l m a c e n a l a d i r e c c i ó n d o n d e se e n c u e n t r a el dato. Es el t i p o p r e d e t e r m i n a d o y el más

c o m ú n ( el ú n i c o q u e e s t u d i a r e m o s ) .
4 5 - I n d i c e s (Crear - I n f o r m a c i ó n )

D i j i m o s q u e el objetivo de u n i n d i c e es acelerar la recuperación de información y q u e

es ú t i l c u a n d o l a t a b l a c o n t i e n e m i l e s d e registros, c u a n d o se realizan o p e r a c i o n e s d e

o r d e n a m i e n t o y a g r u p a m i e n t o , etc.

Es i m p o rt a n t e identificar el o l o s c a m p o s por l o s q u e sería ú t i l crear u n í n d i c e ,

a q u e l l o s c a m p o s por l o s c u a l e s se r e a l i z a n b ú s q u e d a s con frecuencia: claves

p r i m a r i a s , claves externas o c a m p o s q u e c o m b i n a n t a b l a s .

N o se r e c o m i e n d a crear í n d i c e s sobre c a m p o s q u e no se u s a n con frecuencia en

c o n s u l t a s o en t a b l a s m u y p e q u e ñ a s .

Para crear í n d i c e s e m p l e a m o s l a i n s t r u c c i ó n "create i n d e x " .

La sintaxis básica es l a s i g u i e n t e :

create TIPOdeINDICE index NOMBREINDICE

on NOMBRETABLA{CAMPOS);

Los í n d i c e s p u e d e n ser: no ú n i c o s ( l o s valores p u e d e n estar repetidos) o ú n i c o s ( l o s

valores no p u e d e n d u p l i c a r s e ) . De m o d o p r e d e t e r m i n a d o , si n o se especifica el t i p o

de í n d i c e , se crea u n o no ú n i c o .

E n el s i g u i e n t e e j e m p l o creamos u n í n d i c e ú n i c o sobre e l c a m p o " d o c u m e n t o " de l a

tabla "empleados":

create unique index I_empleados_documento

on empleados{documento);

Para i d e n t i f i c a r l o s í n d i c e s f á c i l m e n t e , p o d e m o s a g r e g a r u n prefijo al n o m b r e d e l

í n d i c e , por e j e m p l o " I " y l u e g o el n o m b r e d e l a t a b l a y/o c a m p o .

S i se intenta crear u n í n d i c e ú n i c o para u n c a m p o q u e t i e n e valores d u p l i c a d o s ,

O r a c l e no l o p e r m i t e .

Los c a m p o s de t i p o " l o n g " y " l o n g raw" no p u e d e n i n d e x a r s e .

U n a t a b l a p u e d e indexarse por u n c a m p o (o v a r i o s ) .

C r e a m o s u n í n d i c e compuesto para l o s c a m p o s " a p e l l i d o " y " n o m b r e " :

create index I_empleados_apellidonombre

on empleado(apellido,nombre);

C u a n d o creamos u n a restricción " p r i m a ry key" o " u n i q u e " sobre u n a t a b l a , Oracle

a u t o m á t i c a m e n t e crea u n í n d i c e sobre el c a m p o (o l o s c a m p o s ) de la restricción y le


da el m i s m o n o m b r e q u e l a restricción. E n caso q u e l a t a b l a ya t e n g a u n í n d i c e ,

O r a c l e l o u s a , n o crea otro.

Para obtener i n f o r m a c i ó n sobre los í n d i c e s p o d e m o s c o n s u l t a r varios d i c c i o n a r i o s .

1 ) " u s e r _ i n d e x e s " : nos muestra l a s s i g u i e n t e s c o l u m n a s (entre otras q u e no

analizaremos):

- INDEX NAME (nombre del índice),

- INDEX TYPE (tipo de índice, nosotros crearemos el stardart normal),

- TABLE NAME (nombre de la tabla),

- UNIQUENESS (si es único o no).

2 ) " u s e r _ i n d _ c o l u m n s " : nos muestra las s i g u i e n t e s c o l u m n a s (entre otras q u e no

analizaremos):

- INDEX NAME (nombre del índice),

- TABLE_NAME (nombre de la tabla),

- COLUMN_NAME (nombre del campo),

- COLUMN_POSITION (posición del campo),

3 ) "user_objects": en l a c o l u m n a " O B J E C T_T Y P E " muestra " i n d e x " si es u n í n d i c e .

4 ) "user_constraints": si l a restricción t i e n e u n í n d i c e a s o c i a d o , aparece su n o m b r e en

la columna " I N D E X NAME".


46 - I n d i c e s ( e l i m i n a r )

Los í n d i c e s se e l i m i n a n con " d r o p i n d e x " ; l a s i g u i e n t e es l a s i n t a x i s b á s i c a :

drop index NOMBREINDICE;

E l i m i n a m o s el í n d i c e " l _ e m p l e a d o s _ d o c u m e n t o " :

drop index I_empleados_documento;

Los í n d i c e s u s a d o s por l a s restricciones " p r i m a r y key" y " u n i q u e " no p u e d e n

e l i m i n a r s e con " d r o p i n d e x " , se e l i m i n a n a u t o m á t i c a m e n t e c u a n d o q u i t a m o s l a

restricción.

S i e l i m i n a m o s u n a t a b l a , todos los í n d i c e s asociados a e l l a se e l i m i n a n .


47 - Varias tablas ( j o i n )

Hasta el m o m e n t o h e m o s trabajado con u n a s o l a t a b l a , pero g e n e r a l m e n t e , se

trabaja con m á s de u n a .

Para evitar l a repetición de datos y o c u p a r m e n o s e s p a c i o , se separa la información

en varias t a b l a s . C a d a t a b l a a l m a c e n a parte de la información q u e n e c e s i t a m o s

registrar.

Por e j e m p l o , l o s datos de nuestra t a b l a " l i b r o s " p o d r í a n separarse en 2 t a b l a s , u n a

l l a m a d a " l i b r o s " y otra " e d i t o r i a l e s " q u e g u a r d a r á la información de l a s e d i t o r i a l e s . E n

nuestra t a b l a " l i b r o s " h a r e m o s referencia a l a e d i t o r i a l c o l o c a n d o u n c ó d i g o q u e l a

i d e n t i f i q u e . Veamos:

create table libros(

codigo number(4),

titulo varchar2(40) not null,

autor varchar2(30),

codigoeditorial number(3) not null,

precio number(S,2),

primary key (codigo)

) ;

create table editoriales(

codigo number(3),

nombre varchar2(20) not null,

primary key(codigo)

) ;

De esta m a n e r a , e v i t a m o s a l m a c e n a r tantas veces l o s n o m b r e s de l a s e d i t o r i a l e s en

l a t a b l a " l i b r o s " y g u a r d a m o s el n o m b r e en l a t a b l a " e d i t o r i a l e s " ; para i n d i c a r la

e d i t o r i a l de cada l i b r o a g r e g a m o s u n c a m p o q u e hace referencia al c ó d i g o de l a

e d i t o r i a l e n l a t a b l a " l i b r o s " y en " e d i t o r i a l e s " .

Al r e c u p e r a r l o s datos de los l i b r o s con l a s i g u i e n t e i n s t r u c c i ó n :

select* from libros;

vemos q u e en el c a m p o " e d i t o r i a l " aparece el c ó d i g o , pero n o s a b e m o s el n o m b r e d e

l a e d i t o r i a l . Para o b t e n e r los datos de cada l i b r o , i n c l u y e n d o el n o m b r e d e la e d i t o r i a l ,

necesitamos c o n s u l t a r a m b a s t a b l a s , traer i n f o r m a c i ó n de l a s d o s .

C u a n d o o b t e n e m o s i n f o r m a c i ó n de m á s de u n a t a b l a d e c i m o s q u e hacemos u n " j o i n "

(combinación).

Veamos u n e j e m p l o :
select *from libros

join editoriales

on libros.codigoeditorial=editoriales.codigo;

R e s u m i e n d o : s i d i s t r i b u i m o s l a i n f o r m a c i ó n en varias t a b l a s evitamos l a r e d u n d a n c i a

de datos y o c u p a m o s m e n o s e s p a c i o físico en el d i s c o . U n j o i n es u n a o p e r a c i ó n q u e

r e l a c i o n a do s o más t a b l a s para o b t e n e r u n resultado q u e i n c l u y a datos ( c a m p o s y

registros) d e a m b a s ; l a s t a b l a s p a rt i c i p a n t e s se c o m b i n a n s e g ú n los c a m p o s

comunes a ambas tablas.

Ha y tres t i p o s d e c o m b i n a c i o n e s . E n los s i g u i e n t e s c a p í t u l o s e x p l i c a m o s cada u n a d e

ellas.
48 - C o m b i n a c i ó n i n t e r n a ( j o i n )

U n j o i n es u n a o p e r a c i ó n q u e r e l a c i o n a dos o m á s t a b l a s para obtener u n r e s u l t a d o

q u e i n c l u y a datos ( c a m p o s y registros) de a m b a s ; l a s t a b l a s p a rt i c i p a n t e s se

c o m b i n a n s e g ú n los campos comunes a ambas tablas.

H a y tres t i p o s d e c o m b i n a c i o n e s :

1) combinaciones internas (inner join o join),

2) combinaciones externas y

3) combinaciones cruzadas.

También es p o s i b l e e m p l e a r varias c o m b i n a c i o n e s en u n a c o n s u l t a " s e l e c t " , i n c l u s o

puede combinarse u n a tabla consigo m i s m a .

La c o m b i n a c i ó n interna e m p l e a " j o i n " , q u e es l a forma a b r e v i a d a d e " i n n e r j o i n " . Se

e m p l e a para o b t e n e r información de d o s t a b l a s y c o m b i n a r d i c h a información e n u n a

salida.

La s i n t a x i s básica es l a s i g u i e n t e :

select CAMPOS

from TABLAl

join TABLA2

on CONDICIONdeCOMBINACION;

Ejemplo:

select *from libros

join editoriales

on codigoeditorial=editoriales.codigo;

A n a l i c e m o s l a c o n s u l t a anterior.

- especificamos l o s c a m p o s q u e aparecerán en el resultado e n l a l i s t a de s e l e c c i ó n ;

- i n d i c a m o s el n o m b r e de l a t a b l a l u e g o d e l "from" ( " l i b r o s " ) ;

- c o m b i n a m o s esa t a b l a con " j o i n " y el n o m b r e de l a otra t a b l a ( " e d i t o r i a l e s " ) ; se

especifica q u é t a b l a s se van a c o m b i n a r y c ó m o ;

- c u a n d o se c o m b i n a información de varias t a b l a s , es necesario especificar q u é

registro de u n a t a b l a se c o m b i n a r á con q u é registro de la otra t a b l a , con " o n " . Se

d e b e especificar l a c o n d i c i ó n para e n l a z a r l a s , es decir, el c a m p o por el c u a l se

c o m b i n a r á n , q u e t i e n e n en c o m ú n . " o n " hace c o i n c i d i r registros d e a m b a s t a b l a s

b a s á n d o s e en el v a l o r de tal c a m p o , en el e j e m p l o , el c a m p o " c o d i g o e d i t o r i a l " de

" l i b r o s " y el c a m p o " c o d i g o " de " e d i t o r i a l e s " s o n l o s q u e e n l a z a r á n a m b a s t a b l a s . Se

e m p l e a n c a m p o s c o m u n e s , q u e d e b e n tener t i p o s de datos i g u a l e s o s i m i l a r e s .
La c o n d i c i o n d e c o m b i n a c i ó n , es decir, el o los campos por l o s q u e se van a

c o m b i n a r ( p a rt e " o n " ) , se especifica s e g ú n l a s claves p r i m a r i a s y externas.

Note q u e en l a c o n s u l t a , a l n o m b r a r el c a m p o u s a m o s e l n o m b r e de l a t a b l a t a m b i é n .

C u a n d o l a s t a b l a s referenciadas t i e n e n c a m p o s con i g u a l n o m b r e , esto es necesario

para evitar c o n f u s i o n e s y a m b i g u e d a d e s a l m o m e n t o de referenciar u n c a m p o . E n el

e j e m p l o , si no especificamos " e d i t o r i a l e s . c o d i g o " y s o l a m e n t e t i p e a m o s " c o d i g o " ,

O r a c l e no sabrá si nos referimos a l c a m p o " c o d i g o " d e " l i b r o s " o de " e d i t o r i a l e s " y

mostrará u n m e n s a j e d e error i n d i c a n d o q u e " c o d i g o " es a m b i g u o .

E n t o n c e s , si l a s t a b l a s q u e c o m b i n a m o s t i e n e n n o m b r e s de c a m p o s i g u a l e s , D E B E

especificarse a q u é t a b l a pertenece a n t e p o n i e n d o el n o m b r e de la t a b l a a l n o m b r e

d e l c a m p o , s e p a r a d o por u n p u n t o ( . ) .

S i u n a de l a s t a b l a s t i e n e clave p r i m a r i a c o m p u e s t a , a l c o m b i n a r l a con la otra, en la

c l á u s u l a " o n " se d e b e h a c e r referencia a l a clave c o m p l e t a , es d e c i r , l a c o n d i c i ó n

referenciará a todos l o s c a m p o s clave q u e i d e n t i f i c a n al registro.

Se p u e d e i n c l u i r en l a c o n s u l t a j o i n l a c l á u s u l a "where" para r e s t r i n g i r los registros

q u e retorna el r e s u l t a d o ; t a m b i é n "arder by", " d i s t i n c t " , etc . .

Se e m p l e a este t i p o d e c o m b i n a c i ó n para encontrar registros de la primera t a b l a q u e

se c o r r e s p o n d a n con l o s registros de la otra, es decir, q u e c u m p l a n l a c o n d i c i ó n d e l

" o n " . S i u n v a l o r d e la p r i m e r a t a b l a no se e n c u e n t r a e n l a s e g u n d a t a b l a , el registro

no a p a r e c e ; si en l a p r i m e r a t a b l a el v a l o r es n u l o , tampoco aparece.

Para s i m p l i f i c a r l a s e n t e n c i a p o d e m o s u s a r u n a l i a s para cada t a b l a :

select l.codigo,titulo,autor,nombre

from libros 1

join editoriales e

on l.codigoeditorial=e.codigo;

E n a l g u n o s casos ( como e n este e j e m p l o ) el uso d e a l i a s es para f i n e s de

s i m p l i f i c a c i ó n y hace m á s l e g i b l e l a c o n s u l t a si es l a r g a y c o m p l e j a , pero e n a l g u n a s

c o n s u l t a s es a b s o l u t a m e n t e n e c e s a r i o .
49 - C o m b i n a c i ó n externa i z q u i e r d a (left j o i n )

V i m o s q u e u n a c o m b i n a c i ó n i n t e r n a (j o i n ) encuentra registros d e l a p r i m e r a t a b l a q u e

se c o r r e s p o n d a n con l o s registros de la s e g u n d a , es decir, q u e c u m p l a n l a c o n d i c i ó n

d e l " o n " y si u n v a l o r d e l a p r i m e r a t a b l a no se e n c u e n t r a e n l a s e g u n d a t a b l a , el

registro no a p a r e c e .

S i q u e r e m o s s a b e r q u é registros de u n a t a b l a N O e n c u e n t r a n c o r r e s p o n d e n c i a en la

otra, es decir, no existe v a l o r c o i n c i d e n t e en l a s e g u n d a , necesitamos otro t i p o de

c o m b i n a c i ó n , " o u t e r j o i n " ( c o m b i n a c i ó n externa).

Las c o m b i n a c i o n e s externas c o m b i n a n registros de dos t a b l a s q u e c u m p l e n la

c o n d i c i ó n , m á s l o s registros de l a s e g u n d a t a b l a q u e no l a c u m p l e n ; es decir,

muestran todos l o s registros de l a s t a b l a s r e l a c i o n a d a s , a ú n c u a n d o no haya valores

c o i n c i d e n t e s entre e l l a s .

Este t i p o d e c o m b i n a c i ó n se e m p l e a c u a n d o se necesita u n a l i s t a completa de los

datos de u n a d e l a s t a b l a s y l a i n f o r m a c i ó n q u e c u m p l e con la c o n d i c i ó n . Las

c o m b i n a c i o n e s externas se r e a l i z a n s o l a m e n t e entre 2 t a b l a s .

H a y tres t i p o s d e c o m b i n a c i o n e s externas: "left o u t e r j o i n " , " r i g h t outer j o i n " y " f u l l

o u t e r j o i n " ; se p u e d e n a b r e v i a r con " l e ft j o i n " , " r i g h t j o i n " y " f u l l j o i n " respectivamente.

Vamos a e s t u d i a r l a s p r i m e r a s .

Se e m p l e a u n a c o m b i n a c i ó n externa i z q u i e r d a para mostrar todos los registros de la

t a b l a de l a i z q u i e r d a . S i no e n c u e n t r a c o i n c i d e n c i a con la t a b l a de l a d e r e c h a , el

registro muestra l o s c a m p o s de l a s e g u n d a t a b l a seteados a " n u l l " .

E n el s i g u i e n t e e j e m p l o s o l i c i t a m o s el t í t u l o y n o m b r e de l a e d i t o r i a l de l o s l i b r o s :

select titulo,nombre

from editoriales e

left join libros 1

on codigoeditorial = e.codigo;

E l r e s u l t a d o mostrará el t í t u l o y n o m b r e de la e d i t o r i a l ; l a s e d i t o r i a l e s de l a s c u a l e s no

hay l i b r o s , es d e c i r , cuyo c ó d i g o d e e d i t o r i a l no está presente en " l i b r o s " aparece en

el r e s u l t a d o , pero con el v a l o r " n u l l " e n el c a m p o " t i t u l o " .

Es i m p o rt a n t e l a p o s i c i ó n en q u e se c o l o c a n l a s t a b l a s e n u n "left j o i n " , l a t a b l a de l a

i z q u i e r d a es l a q u e se usa para l o c a l i z a r registros en la t a b l a d e la d e r e c h a .

E n t o n c e s , u n " l e ft j o i n " se usa para h a c e r c o i n c i d i r registros e n u n a t a b l a ( i z q u i e r d a )

con otra t a b l a ( d e r e c h a ) ; si u n v a l o r de l a t a b l a de l a i z q u i e r d a no e n c u e n t r a

c o i n c i d e n c i a en l a t a b l a de l a d e r e c h a , se genera u n a f i l a extra ( u n a por cada v a l o r no

e n c o n t r a d o ) con todos l o s c a m p o s correspondientes a la t a b l a derecha seteados a

" n u l l " . La s i n t a x i s básica es l a s i g u i e n t e :


select CAMPOS

from TABLAIZQUIERDA

left join TABLADERECHA

on CONDICION;

E n el s i g u i e n t e e j e m p l o s o l i c i t a m o s el t í t u l o y el n o m b r e la e d i t o r i a l , l a sentencia es

s i m i l a r a l a anterior, l a diferencia está en el o r d e n de las t a b l a s :

select titulo,nombre

from libros 1

left join editoriales e

on codigoeditorial = e.codigo;

E l r e s u l t a d o mostrará el t í t u l o d e l l i b r o y el n o m b r e de la e d i t o r i a l ; l o s t í t u l o s cuyo

c ó d i g o de e d i t o r i a l n o está presente en " e d i t o r i a l e s " aparecen e n el r e s u l t a d o , pero

con el v a l o r " n u l l " en e l c a m p o " n o m b r e " .

U n " l e ft j o i n " p u e d e t e n e r c l a u s u l a "where" q u e restringa el resultado de l a c o n s u l t a

c o n s i d e r a n d o s o l a m e n t e los registros q u e e n c u e n t r a n c o i n c i d e n c i a en la t a b l a de la

d e r e c h a , es d e c i r , cuyo v a l o r de c ó d i g o está presente e n " l i b r o s " :

select titulo,nombre

from editoriales e

left join libros 1

on e.codigo=codigoeditorial

where codigoeditorial is not null;

También p o d e m o s mostrar l a s e d i t o r i a l e s q u e N O están presentes en " l i b r o s " , es

decir, q u e N O e n c u e n t r a n c o i n c i d e n c i a en la t a b l a de la d e r e c h a :

select titulo,nombre

from editoriales e

left join libros 1

on e.codigo=codigoeditorial

where codigoeditorial is null;


5 0 - C o m b i n a c i ó n externa d e r e c h a ( r i g h t j o i n )

V i m o s q u e u n a c o m b i n a c i ó n externa i z q u i e r d a (left j o i n ) e n c u e n t r a registros d e l a

t a b l a i z q u i e r d a q u e se correspondan con l o s registros de l a t a b l a derecha y s i u n

v a l o r d e l a t a b l a i z q u i e r d a no se e n c u e n t r a en la t a b l a d e r e c h a , el registro muestra los

c a m p o s correspondientes a l a t a b l a de l a derecha seteados a " n u l l " .

U n a c o m b i n a c i ó n externa derecha ( " r i g h t o u t e r j o i n " o " r i g h t j o i n " ) opera d e l m i s m o

m o d o s ó l o q u e l a t a b l a derecha es l a q u e l o c a l i z a l o s registros en la t a b l a i z q u i e r d a .

E n el s i g u i e n t e e j e m p l o s o l i c i t a m o s el t í t u l o y n o m b r e de la e d i t o r i a l de l o s l i b r o s

empleando un "right j o i n " :

select titulo,nombre as editorial

from libros 1

right join editoriales e

on codigoeditorial = e.codigo;

E l r e s u l t a d o mostrará el t í t u l o y n o m b r e de la e d i t o r i a l ; l a s e d i t o r i a l e s de l a s c u a l e s no

hay l i b r o s , es d e c i r , cuyo c ó d i g o d e e d i t o r i a l no está presente en " l i b r o s " aparece en

el r e s u l t a d o , pero con el v a l o r " n u l l " e n el c a m p o " t i t u l o " .

Es F U N D A M E N T A L t e n e r en cuenta l a p o s i c i ó n en q u e se colocan las t a b l a s e n los

"outer j o i n " . E n u n "left j o i n " l a primera t a b l a ( i z q u i e r d a ) es la q u e busca c o i n c i d e n c i a s

en l a s e g u n d a t a b l a ( d e r e c h a ) ; e n el " r i g h t j o i n " l a s e g u n d a t a b l a ( d e r e c h a ) es l a q u e

busca c o i n c i d e n c i a s en l a p r i m e r a t a b l a ( i z q u i e r d a ) .

E n l a s i g u i e n t e c o n s u l t a e m p l e a m o s u n " l e ft j o i n " para c o n s e g u i r el m i s m o resultado

q u e el " r i g h t j o i n " a n t e r i o r " :

select titulo,nombre

from editoriales e

left join libros 1

on codigoeditorial = e.codigo;

Note q u e l a t a b l a q u e busca c o i n c i d e n c i a s ( " e d i t o r i a l e s " ) está e n p r i m e r l u g a r p o r q u e

es u n " l e ft j o i n " ; e n el " r i g h t j o i n " precedente, estaba e n s e g u n d o l u g a r .

U n " r i g h t j o i n " hace c o i n c i d i r registros e n u n a t a b l a ( d e r e c h a ) con otra t a b l a

( i z q u i e r d a ) ; si u n v a l o r de l a t a b l a de la derecha no encuentra c o i n c i d e n c i a e n l a t a b l a

i z q u i e r d a , se g e n e r a u n a fila extra ( u n a por cada v a l o r no encontrado) con todos los

c a m p o s correspondientes a l a t a b l a i z q u i e r d a seteados a " n u l l " . La s i n t a x i s básica es

la siguiente:

select CAMPOS

from TABLAIZQUIERDA
right JOln TABLADERECHA

on CONDICION;

U n " r i g h t j o i n " t a m b i é n p u e d e t e n e r c l á u s u l a "where" q u e restringa el r e s u l t a d o d e l a

c o n s u l t a c o n s i d e r a n d o s o l a m e n t e l o s registros q u e e n c u e n t r a n c o i n c i d e n c i a e n l a

tabla izquierda:

select titulo,nombre

from libros 1

right join editoriales e

on e.codigo=codigoeditorial

where codigoeditorial is not null;

Mostramos l a s e d i t o r i a l e s q u e N O están presentes en " l i b r o s " , es decir, q u e N O

e n c u e n t r a n c o i n c i d e n c i a en l a t a b l a de l a derecha e m p l e a n d o u n " r i g h t j o i n " :

select titulo,nombre

from libros 1

right join editoriales e

on e.codigo=codigoeditorial

where codigoeditorial is null;


51 - C o m b i n a c i ó n externa c o m p l e t a ( f u l l j o i n )

V i m o s q u e u n "left j o i n " e n c u e n t r a registros de l a t a b l a i z q u i e r d a q u e se correspondan

con l o s registros de l a t a b l a derecha y si u n v a l o r de l a t a b l a i z q u i e r d a no se

e n c u e n t r a en l a t a b l a d e r e c h a , el registro muestra l o s c a m p o s correspondientes a la

t a b l a de l a d e r e c h a seteados a " n u l l " . A p r e n d i m o s t a m b i é n q u e u n " r i g h t j o i n " opera

d e l m i s m o m o d o s ó l o q u e l a t a b l a derecha es l a q u e l o c a l i z a los registros en la t a b l a

izquierda.

U n a c o m b i n a c i ó n externa completa ( " f u l l outer j o i n " o " f u l l j o i n " ) retorna todos los

registros d e a m b a s t a b l a s . S i u n registro de u n a t a b l a i z q u i e r d a no encuentra

c o i n c i d e n c i a en l a t a b l a d e r e c h a , l a s c o l u m n a s correspondientes a c a m p o s de l a

t a b l a d e r e c h a aparecen seteadas a " n u l l " , y si l a t a b l a d e l a d e r e c h a n o e n c u e n t r a

c o r r e s p o n d e n c i a en l a t a b l a i z q u i e r d a , l o s c a m p o s de esta ú l t i m a aparecen

conteniendo " n u l l " .

Veamos u n e j e m p l o :

select titulo,nombre

from editoriales e

full join libros 1

on codigoeditorial = e.codigo;

La s a l i d a d e l " f u l l j o i n " precedente muestra todos l o s registros de a m b a s t a b l a s ,

i n c l u y e n d o l o s l i b r o s cuyo c ó d i g o de e d i t o r i a l no existe en la t a b l a " e d i t o r i a l e s " y l a s

e d i t o r i a l e s de l a s c u a l e s no hay c o r r e s p o n d e n c i a en " l i b r o s " .


5 2 - C o m b i n a c i o n e s c r u z a d a s (cross)

V i m o s q u e hay tres t i p o s d e c o m b i n a c i o n e s : 1 ) c o m b i n a c i o n e s i n t e r n a s (j o i n ) , 2 )

c o m b i n a c i o n e s externas (left, o u t e r y f u l l j o i n ) y 3) c o m b i n a c i o n e s c r u z a d a s .

Las c o m b i n a c i o n e s cruzadas (cross j o i n ) muestran todas l a s c o m b i n a c i o n e s de todos

l o s registros de l a s t a b l a s c o m b i n a d a s . Para este tipo de j o i n no se i n c l u y e u n a

c o n d i c i ó n d e e n l a c e . Se g e n e r a el producto c a rt e s i a n o en el q u e el n ú m e r o d e f i l a s

d e l r e s u l t a d o es i g u a l a l n ú m e r o de registros de la p r i m e r a t a b l a m u l t i p l i c a d o por el

n ú m e r o de registros d e l a s e g u n d a t a b l a , es decir, si hay 3 registros en u n a t a b l a y 4

en l a otra, retorna 1 2 f i l a s .

La sintaxis básica es ésta:

select CAMPOS

from TABLAl

cross join TABLA2;

Veamos u n e j e m p l o . U n p e q u e ñ o restaurante a l m a c e n a los n o m b r e s y precios de s u s

c o m i d a s e n u n a t a b l a l l a m a d a " c o m i d a s " y e n u n a t a b l a d e n o m i n a d a "postres" l o s

m i s m o s datos d e s u s postres.

S i n e c e s i t a m o s conocer todas l a s c o m b i n a c i o n e s p o s i b l e s para u n m e n ú , cada

c o m i d a con cada postre, e m p l e a m o s u n "cross j o i n " :

select e.nombre as "plato principal", p.nombre as "postre"

from comidas e

cross join postres p;

La s a l i d a muestra cada p l a t o c o m b i n a d o con cada u n o de l o s postres.

C o m o c u a l q u i e r t i p o d e " j o i n " , p u e d e e m p l e a r s e u n a c l á u s u l a "where" q u e c o n d i c i o n e

la s a l i d a .

Este t i p o d e j o i n no es m u y u t i l i z a d o .
5 3 - Autocombinación

D i j i m o s q u e es p o s i b l e c o m b i n a r u n a tabla c o n s i g o m i s m a .

U n p e q u e ñ o restaurante tiene a l m a c e n a d a s sus comidas en u n a t a b l a l l a m a d a " c o m i d a s " q u e consta de

los s i g u i e n t e s c a m p o s :

- nombre varchar(20),

- precio decimal (4,2) y

rubro char(6)-- que indica con 'plato' si es un plato principal y 'postre' si es postre.

Podemos obtener la c o m b i n a c i ó n de todos los platos e m p l e a n d o u n "cross j o i n " con u n a sola t a b l a :

select el.nombre,

c2.nombre,

cl.precio+c2.precio as total

from comidas el

cross join comidas c2;

E n l a c o n s u l t a anterior aparecerán filas d u p l i c a d a s , para evitarlo d e b e m o s e m p l e a r u n "where":

select el.nombre as "plato principal",

c2.nombre as postre,

cl.precio+c2.precio as total

from comidas el

cross join comidas c2

where cl.rubro='plato' and

c2.rubro='postre';

E n l a c o n s u l t a anterior se e m p l e ó u n "where" q u e especifica q u e se c o m b i n e "plato" con "postre".

E n u n a a u t o c o m b i n a c i ó n se c o m b i n a u n a t a b l a con u n a copia de si m i s m a . Para e l l o debemos u t i l i z a r 2

a l i a s para la t a b l a . Para evitar q u e aparezcan filas d u p l i c a d a s , d e b e m o s e m p l e a r u n "where".

También se puede realizar u n a a u t o c o m b i n a c i ó n con " j o i n " :

select el.nombre as "plato principal",

c2.nombre as postre,

cl.precio+c2.precio as total

from comidas el

join comidas c2

on cl.codigo<>c2.codigo

where cl.rubro='plato' and

c2.rubro='postre';

Para q u e no aparezcan filas d u p l i c a d a s se agrega u n "where".


5 4 - C o m b i n a c i o n e s y f u n c i o n e s de

agrupamiento

P o d e m o s u s a r " g r o u p by" y l a s f u n c i o n e s d e a g r u p a m i e n t o con c o m b i n a c i o n e s de

tablas.

Para ver l a c a n t i d a d d e l i b r o s de cada e d i t o r i a l c o n s u l t a n d o la t a b l a " l i b r o s " y

" e d i t o r i a l e s " , ti p e a m o s :

select nombre as editorial,

count(*) as cantidad

from editoriales e

join libros 1

on codigoeditorial=e.codigo

group by e.nombre;

Las e d i t o r i a l e s q u e n o t i e n e n l i b r o s no aparecen e n la s a l i d a p o r q u e e m p l e a m o s u n

"join".

E m p l e a m o s otra f u n c i ó n de a g r u p a m i e n t o con "left j o i n " . Para conocer el mayor

precio de l o s l i b r o s de cada e d i t o r i a l u s a m o s l a f u n c i ó n " m a x ( ) " , hacemos u n "left j o i n "

y a g r u p a m o s por n o m b r e d e l a e d i t o r i a l :

select nombre as editorial,

max(precio) as "mayor precio"

from editoriales e

left join libros 1

on codigoeditorial=e.codigo

group by nombre;

E n l a s e n t e n c i a anterior, mostrará, para l a e d i t o r i a l de la c u a l no haya l i b r o s , el v a l o r

" n u l l " en la c o l u m n a c a l c u l a d a .
5 5 - C o m b i n a r más de 2 t a b l a s

P o d e m o s h a c e r u n " j o i n " con más d e d o s t a b l a s .

La l i b r e r í a a l m a c e n a l o s datos de s u s l i b r o s en tres t a b l a s : l i b r o s , e d i t o r i a l e s y

autores.

E n l a t a b l a " l i b r o s " u n c a m p o " c o d i g o a u t o r " hace referencia al autor y u n campo

" c o d i g o e d i t o r i a l " referencia l a e d i t o r i a l .

Para recuperar todos l o s datos de l o s l i b r o s e m p l e a m o s la s i g u i e n t e c o n s u l t a :

select titulo,a.nombre,e.nombre

from autores a

join libros 1

on codigoautor=a.codigo

join editoriales e

on codigoeditorial=e.codigo;

A n a l i c e m o s l a c o n s u l t a anterior. I n d i c a m o s el nombre de l a t a b l a l u e g o d e l "from"

( " a u t o r e s " ) , c o m b i n a m o s esa t a b l a con l a t a b l a " l i b r o s " e s p e c i f i c a n d o con " o n " el

c a m p o por el c u a l se c o m b i n a r á n ; l u e g o d e b e m o s hacer c o i n c i d i r l o s valores para el

e n l a c e con l a t a b l a " e d i t o r i a l e s " e n l a z á n d o l a s por l o s c a m p o s c o r r e s p o n d i e n t e s .

U t i l i z a m o s a l i a s para u n a s e n t e n c i a m á s s e n c i l l a y c o m p r e n s i b l e .

Note q u e especificamos a q u é t a b l a pertenecen los campos cuyo n o m b r e se repiten

en l a s t a b l a s , esto es necesario para evitar c o n f u s i o n e s y a m b i g u e d a d e s a l m o m e n t o

de referenciar u n c a m p o .

Los l i b r o s cuyo c ó d i g o de autor no se e n c u e n t r a e n "autores" y cuya e d i t o r i a l no

existe en " e d i t o r i a l e s " , no aparecen p o r q u e r e a l i z a m o s u n a c o m b i n a c i ó n i n t e r n a .

P o d e m o s c o m b i n a r varios t i p o s de j o i n en u n a m i s m a s e n t e n c i a :

select titulo,a.nombre,e.nombre

from autores a

right join libros 1

on codigoautor=a.codigo

left join editoriales e

on codigoeditorial=e.codigo;

E n l a c o n s u l t a a n t e r i o r s o l i c i t a m o s el t í t u l o , autor y e d i t o r i a l de todos l o s l i b r o s q u e

e n c u e n t r e n o no c o i n c i d e n c i a con "autores" ( " r i g h t j o i n " ) y a ese resultado lo

c o m b i n a m o s con " e d i t o r i a l e s " , e n c u e n t r e n o no c o i n c i d e n c i a .

Es p o s i b l e r e a l i z a r v a r i a s c o m b i n a c i o n e s para o b t e n e r i n f o r m a c i ó n d e varias t a b l a s .

Las t a b l a s d e b e n t e n e r claves externas r e l a c i o n a d a s con l a s t a b l a s a c o m b i n a r .


5 6 - Otros t i p o s de c o m b i n a c i o n e s Listado completo de tutoriales

H e m o s a p r e n d i d o q u e existen varios tipos de c o m b i n a c i o n e s en O r a c l e :

1 ) combinaciones internas ( i n n e r join o simplemente j o i n ) ,

2 ) c o m b i n a c i o n e s externas (left j o i n , right j o i n y f u l l j o i n )

3 ) c o m b i n a c i o n e s cruzadas (cross j o i n ) .

También v i m o s q u e es p o s i b l e e m p l e a r varios t i p o s de c o m b i n a c i o n e s en u n a

consulta, i n c l u s o puede combinarse u n a tabla consigo m i s m a .

Existen otros t i p o s de " j o i n " en O r a c l e , q u e veremos r á p i d a m e n t e , ya q u e se

r e s u e l v e n con los q u e v i m o s a n t e r i o r m e n t e , b á s i c a m e n t e l o q u e c a m b i a es la

sintaxis.

1 ) c o m b i n a c i ó n n a t u r a l : realiza u n j o i n entre dos t a b l a s c u a n d o l o s c a m p o s por los

c u a l e s se e n l a z a n t i e n e n el m i s m o n o m b r e . I n v o l u c r a claves p r i m a r i a s y foráneas.

Sintaxis:

select CAMPOS

from TABLAl

natural join TABLA2;

Ejemplo:

select titulo,nombre as editorial

from libros

natural join

editoriales;

E n el e j e m p l o anterior l a t a b l a " l i b r o s " c o m b i n a su campo " c o d i g o e d i t o r i a l " con el

c a m p o " c o d i g o e d i t o r i a l " de " e d i t o r i a l e s " . La c l á u s u l a " o n " n o aparece, este " j o i n " no

necesita c o n d i c i ó n de e n l a c e p o r q u e Oracle busca l o s c a m p o s con n o m b r e s i g u a l e s

de a m b a s t a b l a s ( a m b a s t a b l a s d e b e n tener u n ú n i c o c a m p o con i d é n t i c o n o m b r e , si

t i e n e m á s d e u n c a m p o con i g u a l n o m b r e , Oracle no podrá realizar el e n l a c e y

mostrará u n m e n s a j e d e error).

2 ) c o m b i n a c i ó n e m p l e a n d o l a c l á u s u l a " u s i n g " : p e r m i t e especificar el c a m p o (o l o s

c a m p o s ) por el c u a l se e n l a z a r á n l a s t a b l a s ; l o s c a m p o s de a m b a s t a b l a s D E B E N

t e n e r el m i s m o n o m b r e y ser de t i p o s c o m p a t i b l e s .

Sintaxis:

select CAMPOS

from TABLAl
join TABLA2

using (CAMPOenCOMUN);

Ejemplo:

select titulo,nombre as editorial

from libros

join editoriales

using (codigoeditorial);

E n el e j e m p l o a n t e r i o r l a t a b l a " l i b r o s " c o m b i n a su c a m p o " c o d i g o e d i t o r i a l " con el

c a m p o " c o d i g o e d i t o r i a l " de " e d i t o r i a l e s " . La c l á u s u l a " o n " n o aparece, es

r e e m p l a z a d a por " u s i n g " s e g u i d o d e l n o m b r e d e l c a m p o e n c o m ú n por el c u a l se

enlazan.

3 ) c o m b i n a c i ó n i z q u i e r d a e m p l e a n d o " j o i n " y el operador o m o d i f i c a d o r " ( + ) " :

P o d e m o s obtener el m i s m o resultado q u e u n " l e ft j o i n " e m p l e a n d o " j o i n " y el

m o d i f i c a d o r "( + ) " , con lo c u a l se i n d i c a q u e se c o n s i d e r a n los registros con v a l o r n u l o .

La s i n t a x i s es l a s i g u i e n t e :

select CAMPOS

from TABLAl

join TABLA2

on CAMPOTABLA1=CAMPOTABLA2(+);

Es d e c i r , se coloca el m o d i f i c a d o r "( + )" l u e g o d e l c a m p o d e l a t a b l a de l a derecha

para i n d i c a r q u e se i n c l u y a n l o s q u e t i e n e n v a l o r n u l o .

Las s i g u i e n t e s c o n s u l t a s retornan el m i s m o r e s u l t a d o . U n a de e l l a s e m p l e a "left j o i n "

y l a otra u n " j o i n " con el m o d i f i c a d o r "( + ) " :

select titulo,nombre as editorial

from libros 1

left join editoriales 1

on l.codigoeditorial = e.codigoeditorial;

select titulo,nombre as editorial

from libros 1

join editoriales e

on l.codigoeditorial = e.codigoeditorial(+);

Ambas mostrarán el t í t u l o y n o m b r e de l a e d i t o r i a l ; l o s l i b r o s cuyo c ó d i g o de e d i t o r i a l

no esté presente en " e d i t o r i a l e s " aparecerán con el v a l o r " n u l l " e n l a c o l u m n a

"editorial".

4 ) c o m b i n a c i ó n d e r e c h a e m p l e a n d o "join" y el m o d i f i c a d o r " ( + ) " : de m o d o s i m i l a r a l

anterior, p o d e m o s o b t e n e r el m i s m o resultado q u e u n " r i g h t j o i n " e m p l e a n d o " j o i n " y

el m o d i f i c a d o r " ( + ) " , con lo c u a l se i n d i c a q u e se c o n s i d e r e n l o s registros con v a l o r

n u l o . La sintaxis es l a s i g u i e n t e :

select CAMPOS

from TABLAl
join TABLA2

on CAMPOTABLA1(+)=CAMPOTABLA2;

E n t o n c e s , se coloca el m o d i f i c a d o r " ( + ) " l u e g o d e l c a m p o d e l a t a b l a d e l a i z q u i e r d a

para i n d i c a r q u e se i n c l u y a n l o s q u e t i e n e n v a l o r n u l o .

Las s i g u i e n t e s c o n s u l t a s retornan el m i s m o r e s u l t a d o . U n a de e l l a s e m p l e a " r i g h t

j o i n " · y l a otra u n " j o i n " con el m o d i f i c a d o r " ( + ) " :

select titulo,nombre as editorial

from editoriales e

right join libros 1

on e.codigoeditorial = l.codigoeditorial;

select titulo,nombre as editorial

from editoriales e

join libros 1

on e.codigoeditorial(+) = l.codigoeditorial;

Ambas mostrarán el t í t u l o y n o m b r e de l a e d i t o r i a l ; l a s e d i t o r i a l e s q u e no e n c u e n t r a n

c o i n c i d e n c i a en " l i b r o s " , aparecen con el v a l o r " n u l l " en l a c o l u m n a " t i t u l o " .

S i l a c o n d i c i ó n d e c o m b i n a c i ó n es compuesta ( m á s de u n c a m p o ) , D E B E colocarse el

m o d i f i c a d o r "( + )" en todos los c a m p o s q u e forman parte d e l e n l a c e .

N o se p u e d e colocar el m o d i f i c a d o r en c a m p o s de d i s t i n t a s t a b l a s . La s i g u i e n t e

c o m b i n a c i ó n producirá u n mensaje de error:

select titulo,nombre as editorial

from libros 1

join editoriales e

on l.codigoeditorial(+)= e.codigoeditorial(+);
5 7 - Clave foránea

U n c a m p o q u e no es clave p r i m a r i a en u n a t a b l a y s i rv e para e n l a z a r s u s valores con

otra tabla e n l a cual es clave p r i m a r i a se d e n o m i n a clave foránea, externa o a j e n a .

E n el e j e m p l o de l a l i b r e r í a en q u e u t i l i z a m o s l a s t a b l a s " l i b r o s " y " e d i t o r i a l e s " con estos

campos:

libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio y

editoriales: codigo (clave primaria), nombre.

el c a m p o " c o d i g o e d i t o r i a l " d e " l i b r o s " es u n a clave foránea, se e m p l e a para e n l a z a r l a

tabla " l i b r o s " con " e d i t o r i a l e s " y es clave p r i m a r i a en " e d i t o r i a l e s " con el n o m b r e

"codigo".

Las claves foráneas y l a s claves p r i m a r i a s d e b e n ser d e l m i s m o t i p o para poder

e n l a z a r s e . S i m o d i f i c a m o s u n a , d e b e m o s m o d i f i c a r la otra para q u e l o s valores se

correspondan.

C u a n d o a l t e r a m o s u n a t a b l a , d e b e m o s t e n e r c u i d a d o con l a s claves foráneas. S i

m o d i f i c a m o s el t i p o , l o n g i t u d o atributos de u n a clave foránea, ésta p u e d e q u e d a r

i n h a b i l i t a d a para h a c e r los e n l a c e s .

E n t o n c e s , u n a clave foránea es u n c a m p o (o v a r i o s ) e m p l e a d o s para e n l a z a r datos de

2 t a b l a s , para establecer u n " j o i n " con otra t a b l a en l a c u a l es clave p r i m a r i a .


5 8 - Restricciones (foreign key)

H e m o s visto q u e u n a de l a s alternativas q u e Oracle ofrece para a s e g u r a r l a

i n t e g r i d a d de datos es el uso de restricciones ( constraints ) . A p r e n d i m o s q u e l a s

restricciones se establecen en t a b l a s y c a m p o s a s e g u r a n d o q u e l o s datos sean

v á l i d o s y q u e l a s r e l a c i o n e s entre l a s t a b l a s se m a n t e n g a n .

V i m o s tres t i p o s de restricciones:

primary key, unique y check. Ahora veremos "foreign key".

C o n l a restricción "foreign key" se d e f i n e u n c a m p o (o v a r i o s ) cuyos valores c o i n c i d e n

con l a clave p r i m a r i a d e l a m i s m a t a b l a o de otra, es decir, se define u n a referencia a

u n c a m p o con u n a restricción " p r i m a ry key" o " u n i q u e " d e la m i s m a t a b l a o de otra.

La i n t e g r i d a d referencial a s e g u r a q u e se m a n t e n g a n l a s referencias entre l a s claves

p r i m a r i a s y l a s externas. Por e j e m p l o , controla q u e si se agrega u n c ó d i g o de e d i t o r i a l

en l a t a b l a " l i b r o s " , tal c ó d i g o exista e n l a t a b l a " e d i t o r i a l e s " .

También controla q u e no p u e d a e l i m i n a r s e u n registro de u n a t a b l a n i modificar la

c l a v e p r i m a r i a si u n a clave externa hace referencia a l registro. Por e j e m p l o , q u e no

se p u e d a e l i m i n a r o m o d i f i c a r u n c ó d i g o de " e d i t o r i a l e s " si existen l i b r o s con d i c h o

código.

La s i g u i e n t e es l a s i n t a x i s p a r c i a l g e n e r a l para a g r e g a r u n a restricción "foreign key":

alter table NOMBRETABLAl

add constraint NOMBRERESTRICCION

foreign key (CAMPOCLAVEFORANEA)

references NOMBRETABLA2 (CAMPOCLAVEPRIMARIA);

Analicémosla:

- N O M B R E T A B L A 1 referencia el n o m b r e d e la t a b l a a l a c u a l le a p l i c a m o s la

restricción,

- N O M B R E R E S T R I C C I O N es el n o m b r e q u e l e d a m o s a l a m i s m a ,

- l u e g o de "foreign key", entre p a r é n t e s i s se coloca el c a m p o d e l a t a b l a a l a q u e le

a p l i c a m o s l a restricción q u e será e s t a b l e c i d a como clave foránea,

- l u e g o de "references" i n d i c a m o s el n o m b r e d e l a t a b l a referenciada y el c a m p o q u e

es clave p r i m a r i a en l a m i s m a , a la c u a l hace referencia la clave foránea. El c a m p o

de l a t a b l a referenciada debe tener d e f i n i d a u n a restricción " p r i m a ry key" o " u n i q u e " ;

si no l a t i e n e , aparece u n mensaje de error.

Para a g r e g a r u n a restricción "foreign key" al c a m p o " c o d i g o e d i t o r i a l " de " l i b r o s " ,

ti p e a m o s :
alter table libros

add constraint FK_libros_codigoeditorial

foreign key (codigoeditorial)

references editoriales(codigo);

E n el e j e m p l o i m p l e m e n t a m o s u n a restricción "foreign key" para a s e g u r a r n o s q u e e l

c ó d i g o de l a e d i t o r i a l de l a de l a t a b l a " l i b r o s " ( " c o d i g o e d i t o r i a l " ) esté a s o c i a d a con u n

código v á l i d o en la tabla "editoriales" ("codigo").

C u a n d o a g r e g a m o s c u a l q u i e r restricción a u n a t a b l a q u e c o n t i e n e i n f o r m a c i ó n ,

O r a c l e controla l o s datos existentes para confirmar q u e c u m p l e n con l a restricción, si

no los c u m p l e , l a restricción no se a p l i c a y aparece u n mensaje de error. Por e j e m p l o ,

si i n t e n t a m o s a g r e g a r u n a restricción "foreign key" a l a t a b l a " l i b r o s " y existe u n l i b r o

con u n v a l o r de c ó d i g o para e d i t o r i a l q u e no existe en la t a b l a " e d i t o r i a l e s " , l a

restricción no se a g r e g a .

Actúa en i n s e r c i o n e s . S i i n t e n t a m o s i n g r e s a r u n registro ( u n l i b r o ) con u n v a l o r de

clave foránea ( c o d i g o e d i t o r i a l ) q u e no existe en la t a b l a referenciada ( e d i t o r i a l e s ) ,

O r a c l e muestra u n m e n s a j e de error. S i a l i n g r e s a r u n registro ( u n l i b r o ) , no

c o l o c a m o s el v a l o r para el c a m p o clave foránea ( c o d i g o e d i t o r i a l ) , a l m a c e n a r á " n u l l " ,

p o r q u e esta restricción permite valores n u l o s (a m e n o s q u e se haya especificado lo

contrario a l d e f i n i r el c a m p o ) .

Actúa en e l i m i n a c i o n e s y a c t u a l i z a c i o n e s . S i i n t e n t a m o s e l i m i n a r u n registro o

m o d i f i c a r u n v a l o r de clave p r i m a r i a de u n a t a b l a si u n a clave foránea hace referencia

a d i c h o registro, Oracle no l o permite ( excepto si se permite la acción en cascada,

tema q u e veremos posteriormente). P o r e j e m p l o , si i n t e n t a m o s e l i m i n a r u n a e d i t o r i a l

a l a q u e se hace referencia en " l i b r o s " , aparece u n mensaje d e error.

Esta restricción (a d i f e r e n c i a de " p r i m a ry key" y " u n i q u e " ) no crea í n d i c e

automáticamente.

La c a n t i d a d y t i p o de datos de l o s c a m p o s especificados l u e g o de "foreign key"

D E B E N c o i n c i d i r con l a c a n t i d a d y t i p o de datos de l o s c a m p o s de la c l á u s u l a

"references".

Esta restricción se p u e d e d e f i n i r dentro de la m i s m a t a b l a ( l o veremos m á s a d e l a n t e )

o entre d i s t i n t a s t a b l a s .

U n a t a b l a p u e d e t e n e r varias restricciones "foreign key".

N o se p u e d e e l i m i n a r u n a t a b l a referenciada en u n a restricción "foreign key", aparece

u n mensaje de error.

U n a restriccion "foreign key" no p u e d e m o d i f i c a r s e , d e b e e l i m i n a r s e (con "alter t a b l e "

y " d r o p c o n s t r a i n t " ) y volverse a crear.

Las restricciones "foreign key" se e l i m i n a n a u t o m á t i c a m e n t e a l e l i m i n a r l a t a b l a en l a

q u e fueron d e f i n i d a s .

Para ver i n f o r m a c i ó n acerca de esta restricción p o d e m o s c o n s u l t a r los d i c c i o n a r i o s

"user_constraints" y " u s e r _ c o n s _ c o l u m n s " .


5 9 - Restricciones foreign key en la m i s m a

tabla

La restricción "foreign key", q u e d e f i n e u n a referencia a u n c a m p o con u n a restricción

" p r i m a ry key" o " u n i q u e " se p u e d e d e f i n i r entre d i s t i n t a s t a b l a s ( como h e m o s

a p r e n d i d o ) o dentro d e l a m i s m a t a b l a .

Veamos u n e j e m p l o en el c u a l d e f i n i m o s esta restricción dentro de la m i s m a t a b l a .

U n a m u t u a l a l m a c e n a l o s datos de s u s a f i l i a d o s en u n a t a b l a l l a m a d a " a f i l i a d o s " .

A l g u n o s a f i l i a d o s i n s c r i b e n a s u s f a m i l i a r e s . La t a b l a c o n t i e n e u n c a m p o q u e hace

referencia a l a f i l i a d o q u e lo incorporó a l a m u t u a l , d e l c u a l d e p e n d e n .

La estructura d e l a t a b l a es l a s i g u i e n t e :

create table afiliados(

numero number(S),

documento char(8) not null,

nombre varchar2(30),

afiliadotitular number(S),

primary key (documento),

unique (numero)

) ;

E n caso q u e u n a f i l i a d o no haya s i d o incorporado a la m u t u a l por otro a f i l i a d o , el

campo "afiliadotitular" almacenará " n u l l " .

E s t a b l e c e m o s u n a restricción "foreign key" para a s e g u r a r n o s q u e el n ú m e r o d e

a f i l i a d o q u e se i n g r e s e en el c a m p o " a f i l i a d o t i t u l a r " exista e n l a t a b l a " a f i l i a d o s " :

alter table afiliados

add constraint FK afiliados afiliadotitular


- -

foreign key (afiliadotitular)

references afiliados (numero);

La s i n t a x i s es l a m i s m a , excepto q u e la t a b l a se autoreferencia.

L u e g o de a p l i c a r esta restricción, cada vez q u e se i n g r e s e u n v a l o r en el c a m p o

" a f i l i a d o t i t u l a r " , Oracle controlará q u e d i c h o n ú m e r o exista e n l a t a b l a , si no existe,

mostrará u n m e n s a j e d e error.

S i i n t e n t a m o s e l i m i n a r u n a f i l i a d o q u e es t i t u l a r de otros a f i l i a d o s , no se podrá hacer,

a m e n o s q u e se haya especificado l a acción en cascada (próximo t e m a ) .

S i i n t e n t a m o s m o d i f i c a r u n a f i l i a d o q u e es t i t u l a r de otros a f i l i a d o s , n o se podrá hacer,

a m e n o s q u e se haya especificado l a acción en cascada para a c t u a l i z a c i o n e s

(próximo tema).
61 - Restricciones foreign key d e s h a b i l i t a r y

validar

A p r e n d i m o s ( c u a n d o v i m o s l o s otros t i p o s de restricciones) q u e si a g r e g a m o s u n a

restricción a u n a t a b l a q u e c o n t i e n e datos, Oracle l o s controla para asegurarse q u e

c u m p l e n con l a restricción y q u e es p o s i b l e d e s h a b i l i t a r esta c o m p r o b a c i ó n . Lo

h a c e m o s i n c l u y e n d o l a o p c i ó n " n o v a l i d a t e " en l a i n s t r u c c i ó n " a l t e r t a b l e " ; en tal caso,

La restricción no se a p l i c a en l o s datos existentes, pero si i n t e n t a m o s i n g r e s a r u n

n u e v o v a l o r q u e no c u m p l a l a restricción ( o a c t u a l i z a r l o ) , Oracle no lo p e r m i t e .

E n el s i g u i e n t e e j e m p l o a g r e g a m o s u n a restricción "foreign key" sobre e l c a m p o

" c o d i g o e d i t o r i a l " d e " l i b r o s " especificando q u e no v a l i d e l o s datos existentes:

alter table libros

add constraint FK_libros_codigoeditorial

foreign key (codigoeditorial)

references editoriales novalidate;

La restricción no se a p l i c a en l o s datos existentes, pero si i n t e n t a m o s i n g r e s a r u n

n u e v o registro en " l i b r o s " cuyo c ó d i g o d e e d i t o r i a l no exista en " e d i t o r i a l e s " , Oracle no

lo permitirá.

Para s a b e r si u n a restricción está v a l i d a d a o n o , p o d e m o s c o n s u l t a r el catálogo

"user_constraints" y fijarnos lo q u e informa l a c o l u m n a " v a l i d a t e d " .

También a p r e n d i m o s q u e p o d e m o s d e s h a b i l i t a r l a s restricciones para agregar o

a c t u a l i z a r datos s i n c o m p r o b a r l a . Para evitar l a c o m p r o b a c i ó n de datos e n

inserciones y actualizaciones agregamos "disable" en l a instrucción "alter table".

E n el e j e m p l o s i g u i e n t e d e s h a b i l i t a m o s l a restricción " F K _ l i b r o s _ c o d i g o e d i t o r i a l " para

p o d e r i n g r e s a r u n v a l o r q u e infrija l a restricción:

alter table libros

disable validate

constraint FK_libros_codigoeditorial;

Para h a b i l i t a r u n a restricción "foreign key" d e s h a b i l i t a d a se ejecuta l a m i s m a

i n s t r u c c i ó n pero con l a c l á u s u l a " e n a b l e " .

Por defecto (si no se especifica) l a s o p c i o n e s son " v a l i d a t e " (es d e c i r , controla l o s

datos existentes) y " e n a b l e " (controla futuros i n g r e s o s y a c t u a l i z a c i o n e s ) .

Para s a b e r si u n a restricción está h a b i l i t a d a o n o , p o d e m o s c o n s u l t a r el catálogo

"user_constraints" y fijarnos lo q u e informa l a c o l u m n a "status".

P o d e m o s h a b i l i t a r u n a restricción "foreign key" con " e n a b l e " y " n o v a l i d a t e " , en tal

caso O r a c l e h a b i l i t a l a restricción para futuros i n g r e s o s y a c t u a l i z a c i o n e s y N O v a l i d a


los datos existentes.

Entonces, " e n a b l e " o " d i s a b l e " activa o desactiva la restricción para los nuevos datos

("enable" es la opción predeterminada si no se especifica); "validate" o "novalidate"

es l a opción para v a l i d a r la restricción en los datos existentes ("validate" es l a

predeterminada si se omite).

La sintaxis básica al agregar la restriccción "foreign key" es l a s i g u i e n t e :

alter table NOMBRETABLAl

add constraint NOMBRECONSTRAINT

foreign key (CAMPOCLAVEFORANEA)

references NOMBRETABLA2 (CAMPOCLAVEPRIMARIA)

ESTADO VALIDACION;

La sintaxis para modificar u n a restricción es:

alter table NOMBRETABLA

ESTADO VALIDACION

constraint NOMBRERESTRICCION;
6 2 - Restricciones foreign key ( a c c i o n e s )

C o n t i n u a m o s con l a restricción "foreign key". S i i n t e n t a m o s e l i m i n a r u n registro d e l a

t a b l a referenciada por u n a restricción "foreign key" cuyo v a l o r d e clave p r i m a r i a existe

referenciada en l a t a b l a q u e t i e n e d i c h a restricción, l a acción no se ejecuta y aparece

u n mensaje de error. Esto sucede p o r q u e , por defecto, para e l i m i n a c i o n e s , la o p c i ó n

de l a restricción "foreign key" es " n o a c t i o n " .

La restricción "foreign key" t i e n e l a c l á u s u l a " o n d e l e t e " , q u e son o p c i o n a l e s . Esta

c l á u s u l a especifica cómo d e b e actuar Oracle frente a e l i m i n a c i o n e s en l a s t a b l a s

referenciadas e n l a restricción.

Las o p c i o n e s para estas c l á u s u l a s son l a s s i g u i e n t e s :

- "set n u l l " : i n d i c a q u e si e l i m i n a m o s u n registro d e l a t a b l a referenciada (TABLA2)

cuyo v a l o r existe en l a t a b l a p r i n c i p a l (TABLA 1 ) , d i c h o registro se e l i m i n e y los

valores c o i n c i d e n t e s en l a t a b l a p r i n c i p a l se seteen a " n u l l " .

- " c a s c a d e " : i n d i c a q u e si e l i m i n a m o s u n registro d e l a t a b l a referenciada en u n a

"foreign key" (TABLA2), l o s registros c o i n c i d e n t e s e n l a t a b l a p r i n c i p a l (TABLA 1 ) ,

t a m b i é n se e l i m i n e n ; es d e c i r , si e l i m i n a m o s u n registro a l c u a l u n a clave foránea

referencia, d i c h a e l i m i n a c i ó n se extiende a la otra t a b l a ( i n t e g r i d a d referencial e n

cascada).

- " n o a c t i o n " : es l a p r e d e t e r m i n a d a ; i n d i c a q u e s i se i n t e n t a e l i m i n a r u n registro de l a

t a b l a referenciada por u n a "foreign key", Oracle no l o permita y muestre u n m e n s a j e

de error. Se establece o m i t i e n d o la c l á u s u l a "on d e l e t e " al establecer l a restricción.

La sintaxis c o m p l e t a p a a r a g r e g a r esta restricción a u n a t a b l a es la s i g u i e n t e :

alter table TABLAl

add constraint NOMBRERESTRICCION

foreign key (CAMPOCLAVEFORANEA)

references TABLA2(CAMPOCLAVEPRIMARIA)

on delete OPCION;

Veamos u n e j e m p l o . D e f i n i m o s u n a restricción "foreign key" a l a t a b l a " l i b r o s "

e s t a b l e c i e n d o el c a m p o " c o d i g o e d i t o r i a l " como clave foránea q u e referencia a l c a m p o

" c o d i g o " d e l a t a b l a " e d i t o r i a l e s " . La t a b l a " e d i t o r i a l e s " t i e n e como clave p r i m a r i a el

c a m p o " c o d i g o " . Especificamos la acción e n cascada para l a s e l i m i n a c i o n e s :

alter table libros

add constraint FK_libros_codigoeditorial

foreign key (codigoeditorial)

references editoriales(codigo)

on delete cascade;
S i l u e g o de establecer l a restricción anterior, e l i m i n a m o s u n a e d i t o r i a l de " e d i t o r i a l e s "

cuyo v a l o r d e c ó d i g o está presente en " l i b r o s " , se e l i m i n a d i c h a e d i t o r i a l y todos los

l i b r o s de t a l e d i t o r i a l .

S i c o n s u l t a m o s "user_constraints", en l a c o l u m n a "delete_rule" mostrará "cascade".

Para d e f i n i r u n a restricción "foreign key" sobre l a t a b l a " l i b r o s " e s t a b l e c i e n d o el

c a m p o " c o d i g o e d i t o r i a l " como clave foránea q u e referencia a l c a m p o " c o d i g o " d e la

t a b l a " e d i t o r i a l e s " e s p e c i f i c a n d o l a a c c i ó n d e seteo a " n u l l " t i p e a m o s :

alter table libros

add constraint FK_libros_codigoeditorial

foreign key (codigoeditorial)

references editoriales(codigo)

on delete set null;

S i l u e g o de establecer l a restricción anterior, e l i m i n a m o s u n a e d i t o r i a l de " e d i t o r i a l e s "

cuyo v a l o r d e c ó d i g o está presente en " l i b r o s " , se e l i m i n a d i c h a e d i t o r i a l y todos los

valores de l i b r o s q u e c o i n c i d e n con tal e d i t o r i a l se setean a n u l l . S i c o n s u l t a m o s

"user_constraints", e n l a c o l u m n a " d e l e t e _ r u l e " mostrará "set n u l l " .

S i n t e t i z a n d o , si a l a g r e g a r u n a restricción "foreign key":

- no se especifica acción para e l i m i n a c i o n e s , y se intenta e l i m i n a r u n registro de l a

t a b l a referenciada en l a "foreign key" ( e d i t o r i a l e s ) cuyo v a l o r d e clave p r i m a r i a

( c o d i g o ) existe en l a t a b l a p r i n c i p a l ( l i b r o s ) , la acción no se r e a l i z a .

- se especifica "cascade" para e l i m i n a c i o n e s ( " o n d e l e t e cascade") y e l i m i n a u n

registro de l a t a b l a referenciada ( e d i t o r i a l e s ) cuyo v a l o r de clave p r i m a r i a ( c o d i g o )

existe en la t a b l a p r i n c i p a l ( l i b r o s ) , l a e l i m i n a c i ó n de l a t a b l a referenciada ( e d i t o r i a l e s )

se r e a l i z a y se e l i m i n a n de l a t a b l a p r i n c i p a l ( l i b r o s ) todos l o s registros cuyo v a l o r

c o i n c i d e con el registro e l i m i n a d o de la t a b l a referenciada ( e d i t o r i a l e s ) .

- se especifica a c c i ó n para e l i m i n a c i o n e s ( " o n d e l e t e set n u l l " ) y se e l i m i n a u n registro

de l a t a b l a referenciada en l a "foreign key" ( e d i t o r i a l e s ) cuyo v a l o r d e clave p r i m a r i a

( c o d i g o ) existe en l a t a b l a p r i n c i p a l ( l i b r o s ) , la acción se realiza y se setean a " n u l l "

todos l o s v a l o r e s c o i n c i d e n t e s en l a t a b l a p r i n c i p a l ( l i b r o s ) .

La restricción "foreign key" N O t i e n e u n a c l á u s u l a para especificar a c c i o n e s para

actualizaciones.

S i i n t e n t a m o s a c t u a l i z a r u n registro de l a t a b l a referenciada por u n a restricción

"foreign key" cuyo v a l o r de clave p r i m a r i a existe referenciada en l a t a b l a q u e t i e n e

d i c h a r e s t r i c c i ó n , l a a c c i ó n no se ejecuta y aparece u n mensaje de error. Esto s u c e d e

p o r q u e , por defecto (y como ú n i c a o p c i ó n ) , para a c t u a l i z a c i o n e s existe " n o a c t i o n " .


6 3 - I n f o r m a c i ó n de u s e r_constraints

El diccionario "user constraints" d e v u e l v e m u c h a i n f o r m a c i ó n referente a l a s

restricciones, l a s q u e e s t u d i a m o s son l a s s i g u i e n t e s c o l u m n a s :

- owner: p r o p i e t a r i o d e l a restricción;

- constraint_name: nombre de la restricción;

- constraint_type: t i p o de restricción. S i es u n a restricción " p r i m a r y key" aparece " P " ,

si es d e c o n t r o l , " C " , s i es ú n i c a , " U " , si es u n a "foreign key" " R " ;

- t a b l e _ n a m e : n o m b r e de la t a b l a sobre l a c u a l está a p l i c a d a la restricción;

- s e a r c h _ c o n d i t i o n : s o l a m e n t e es a p l i c a b l e a restricciones de c o n t r o l ; i n d i c a la

condición de chequeo a cumplirse.

- d e l e t e _ r u l e : s o l a m e n t e a p l i c a b l e a restricciones "foreign key". P u e d e c o n t e n e r 3

v a l o r e s : 1 ) "set n u l l " : i n d i c a q u e si e l i m i n a m o s u n registro d e l a t a b l a referenciada

(TABLA2) cuyo v a l o r existe en l a t a b l a p r i n c i p a l (TABLA 1 ) , d i c h o registro se e l i m i n a y

l o s valores c o i n c i d e n t e s en l a t a b l a p r i n c i p a l se seteen a " n u l l " ; 2 ) "cascade": i n d i c a

q u e si e l i m i n a m o s u n registro de la t a b l a referenciada en u n a "foreign key" (TABLA2),

l o s registros c o i n c i d e n t e s en l a t a b l a p r i n c i p a l (TABLA 1 ) , t a m b i é n se e l i m i n a n ; 3 ) " n o

a c t i o n " : i n d i c a q u e si se intenta e l i m i n a r u n registro d e l a t a b l a referenciada por u n a

"foreign key", Oracle no l o p e r m i t e .

- status: i n d i c a si está h a b i l i t a d a ( e n a b l e d ) para futuras i n s e r c i o n e s y a c t u a l i z a c i o n e s

o d e s h a b i l i t a d a (d i s a b l e d )

- v a l i d a t e d : i n d i c a si v a l i d a l o s datos existentes en l a t a b l a ( v a l i d a t e d ) o no ( n o

validate).
64 - Restricciones a l crear la t a b l a

Hasta el m o m e n t o h e m o s a g r e g a d o restricciones a t a b l a s existentes con " a l t e r t a b l e " ;

t a m b i é n p u e d e n establecerse a l m o m e n t o de crear u n a t a b l a ( en la i n s t r u c c i ó n

"create t a b l e " ) .

E n el s i g u i e n t e e j e m p l o creamos l a t a b l a " l i b r o s " con varias restricciones:

create table libros(

codigo number(S),

titulo varchar2(40),

codigoautor number(4),

codigoeditorial number(3),

precio number(S,2) default 0,

constraint PK_libros_codigo

primary key (codigo),

constraint U Q_ l i b r o s _ t i t u l o a u t o r

unique (titulo,codigoautor),

constraint CK_libros_codigoeditorial

check (codigoeditorial is not null),

constraint FK libros editorial


- -

foreign key (codigoeditorial)

references editoriales(codigo)

on delete cascade,

constraint FK libros autores


- -

foreign key (codigoautor)

references autores(codigo)

on delete set null,

constraint CK_libros_preciononulo

check (precio is not null) disable,

constraint CK_precio_positivo

check (precio>=0)

) ;

E n el e j e m p l o d e f i n i m o s l a s s i g u i e n t e s restricciones:

- " p r i m a ry key" sobre el c a m p o " c o d i g o " ;

- " u n i q u e " para los c a m p o s " t i t u l o " y " c o d i g o a u t o r " ;

- de control sobre " c o d i g o e d i t o r i a l " q u e no permite valores n u l o s ;

- "foreign key" para establecer el c a m p o " c o d i g o e d i t o r i a l " como clave externa q u e

h a g a referencia a l c a m p o " c o d i g o " de " e d i t o r i a l e s y permita e l i m i n a c i o n e s e n

cascada;

- "foreign key" para establecer el c a m p o "codigoautor" como clave externa q u e h a g a

referencia a l c a m p o " c o d i g o " de "autores" y permita e l i m i n a c i o n e s "set n u l l " ;


- de control sobre " p r e c i o " para q u e no a d m i t a valores n u l o s , d e s h a b i l i t a d a ;

- "check" para el c a m p o " p r e c i o " q u e no a d m i t a valores negativos.

Las restricciones se a g r e g a n a la t a b l a , s e p a r a d a s por c o m a s ; c o l o c a n d o " c o n s t r a i n t "

s e g u i d o d e l n o m b r e d e l a restricción, el t i p o y l o s c a m p o s (si es u n a " p r i m a r y key",

" u n i q u e " o "foreign key") o l a c o n d i c i ó n (si es de control); t a m b i é n p u e d e

especificarse el estado y l a v a l i d a c i ó n de datos ( p o r defecto es " e n a b l e " y " v a l i d a t e " ) ;

y en el caso de l a s "foreign key", l a o p c i ó n para e l i m i n a c i o n e s .

S i d e f i n i m o s u n a restricción "foreign key" al crear u n a t a b l a , l a t a b l a referenciada

d e b e existir y d e b e t e n e r d e f i n i d a l a clave p r i m a r i a o ú n i c a a la c u a l hace referencia l a

"foreig n key".
65 - Unión

Las o p e r a c i o n e s de conjuntos c o m b i n a n l o s resultados de dos o más c o n s u l t a s

"select" e n u n ú n i c o r e s u l t a d o .

Se u s a n c u a n d o l o s datos q u e se q u i e r e n o b t e n e r p e rt e n e c e n a d i s t i n t a s t a b l a s y no

se p u e d e acceder a e l l o s con u n a s o l a c o n s u l t a .

Es n e c e s a r i o q u e l a s t a b l a s referenciadas t e n g a n t i p o s de datos s i m i l a r e s , la m i s m a

c a n t i d a d de c a m p o s y el m i s m o orden de campos en la l i s t a d e selección de cada

consulta.

H a y tres operadores d e c o n j u n t o s : u n i o n , intersect y m i n u s . Veremos en p r i m e r l u g a r

"union".

La sintaxis para u n i r d o s c o n s u l t a s con el operador " u n i o n " es l a s i g u i e n t e :

CONSULTAl

u n ion

CONSULTA2;

Recuerde q u e l a s c o n s u l t a s D E B E N tener el m i s m o n u m e r o d e valores retornados y

l o s valores d e b e n ser d e l m i s m o t i p o .

Veamos u n e j e m p l o . U n a a c a d e m i a de e n s e ñ a n z a de i d i o m a s da clases de i n g l é s y

trances; a l m a c e n a l o s datos de los a l u m n o s q u e e s t u d i a n i n g l é s e n u n a t a b l a l l a m a d a

" i n g l e s " y los q u e están inscriptos en "francés" en u n a t a b l a d e n o m i n a d a "trances".

La a c a d e m i a necesita el n o m b r e y d o m i c i l i o de todos l o s a l u m n o s , d e todos l o s

cursos para e n v i a r l e s u n a tarjeta de felicitación para el d í a d e l a l u m n o .

Para obtener l o s datos necesarios de a m b a s t a b l a s en u n a s o l a c o n s u l t a

necesitamos r e a l i z a r u n a u n i ó n :

select nombre, domicilio from ingles

u n ion

select nombre, domicilio from frances;

E l p r i m e r "select" d e v u e l v e e l n o m b r e y d o m i c i l i o d e todos los a l u m n o s d e " i n g l e s " ; el

s e g u n d o , el n o m b r e y d o m i c i l i o de todos l o s a l u m n o s de "trances". Esta s e n t e n c i a d e

u n i ó n retornará l a c o m b i n a c i o n de l o s resultados de a m b a s c o n s u l t a s " s e l e c t " ,

mostrando el n o m b r e y d o m i c i l i o d e l o s registros de a m b a s t a b l a s .

Los e n c a b e z a d o s d e l resultado de u n a u n i ó n son los q u e se especifican en e l p r i m e r

" s e l e c t " . El o p e r a d o r d e c o n j u n t o " u n i o n " no retorna d u p l i c a d o s ; es decir, si u n

registro de l a p r i m e r c o n s u l t a es i g u a l a otro registro de la s e g u n d a c o n s u l t a , tal


registro aparece u n a s o l a vez. S i q u e r e m o s q u e se i n c l u y a n T O D O S los registros,

a ú n du p l ica d o s, debemos emplear " u n i o n a l l " :

select nombre,domicilio from ingles

union all

select nombre,domicilio from frances;

E n el e j e m p l o anterior, si u n registro de l a p r i m e r c o n s u l t a es i g u a l a otro registro de

l a s e g u n d a c o n s u l t a , tal registro aparece d o s veces; es decir, si u n a l u m n o está

c u r s a n d o a m b o s i d i o m a s , aparecerá d o s veces en el r e s u l t a d o .

" u n i o n " p u e d e c o m b i n a r s e con l a c l á u s u l a "arder by".


66 - Intersección

C o n t i n u a m o s a p r e n d i e n d o l a s o p e r a c i o n e s de c o n j u n t o s . A p r e n d i m o s " u n i o n " y

" u n i o n a l l " , a h o r a veremos "intersect".

C o m o c u a l q u i e r otra o p e r a c i ó n de c o n j u n t o s , "intersect" se e m p l e a c u a n d o los datos

q u e se q u i e r e n o b t e n e r pertenecen a d i s t i n t a s t a b l a s y no se p u e d e acceder a e l l o s

con u n a s o l a c o n s u l t a .

D e l m i s m o m o d o , l a s t a b l a s referenciadas D E B E N t e n e r t i p o s de datos s i m i l a r e s , l a

m i s m a c a n t i d a d d e c a m p o s y el m i s m o orden de campos en la l i s t a de s e l e c c i ó n de

cada c o n s u l t a q u e i n t e rv e n g a en la i n t e r s e c c i ó n .

"intersect" d e v u e l v e l a intersección de l a s c o n s u l t a s i n v o l u c r a d a s ; es decir, el

r e s u l t a d o retornará los registros q u e se e n c u e n t r a n en la p r i m e r a y s e g u n d a c o n s u l t a

(y d e m á s si l a s h u b i e r e ) , o s e a , los registros q u e todas l a s c o n s u l t a s t i e n e n en

común.

Sintaxis:

SENTENCIASELECTl

intersect

SENTENCIASELECT2;

N o o l v i d e q u e l a s c o n s u l t a s D E B E N tener el m i s m o n u m e r o de valores retornados y

l o s valores d e b e n ser d e l m i s m o t i p o .

U n a a c a d e m i a d e e n s e ñ a n z a de i d i o m a s da c l a s e s de i n g l é s , trances y p o rt u g u e s ;

a l m a c e n a l o s datos d e l o s a l u m n o s q u e e s t u d i a n i n g l é s en u n a t a b l a l l a m a d a " i n g l e s " ,

l o s q u e están i n s c r i p t o s en "francés" e n u n a t a b l a d e n o m i n a d a "frances" y los q u e

a p r e n d e n p o rt u g u e s en l a t a b l a " p o rt u g u e s " .

La a c a d e m i a necesita el n o m b r e y d o m i c i l i o de todos l o s a l u m n o s q u e c u r s a n los tres

i d i o m a s para e n v i a r l e s u n a tarjeta de d e s c u e n t o .

Para o b t e n e r l o s datos necesarios de l a s tres t a b l a s en u n a s o l a c o n s u l t a

necesitamos r e a l i z a r u n a i n t r e s e c c i ó n :

select nombre, domicilio from ingles

intersect

select nombre, domicilio from frances

intersect

select nombre, domicilio from portugues;

E l p r i m e r "select" d e v u e l v e e l n o m b r e y d o m i c i l i o d e todos los e s t u d i a n t e s de i n g l é s ;

el s e g u n d o , el n o m b r e y d o m i c i l i o de todos los i n s c r i p t o s a francés y l a tercera los

m i s m o s c a m p o s d e los a l u m n o s de " p o rt u g u e s " . Esta s e n t e n c i a d e intersección

retornará l o s registros q u e c o i n c i d e n e n l a s tres c o n s u l t a s " s e l e c t " .


67 - Minus

C o n t i n u a m o s a p r e n d i e n d o l a s o p e r a c i o n e s de c o n j u n t o s . A p r e n d i m o s " u n i o n " , " u n i o n

a l l " , " i n t e r s e c t " , n o s resta ver " m i n u s " (resta, d i f e r e n c i a ) .

C o m o c u a l q u i e r otra o p e r a c i ó n de c o n j u n t o s , " m i n u s " se e m p l e a c u a n d o los datos

q u e se q u i e r e n o b t e n e r pertenecen a d i s t i n t a s t a b l a s y no se p u e d e acceder a e l l o s

con u n a s o l a c o n s u l t a . D e l m i s m o m o d o , l a s t a b l a s referenciadas D E B E N t e n e r t i p o s

de datos s i m i l a r e s , l a m i s m a c a n t i d a d d e c a m p o s y el m i s m o o r d e n de campos en la

lista d e s e l e c c i ó n de cada c o n s u l t a q u e i n t e rv e n g a en la o p e r a c i ó n de resta.

" m i n u s " ( d i f e r e n c i a ) d e v u e l v e l o s registros d e l a p r i m e r a c o n s u l t a q u e no se

e n c u e n t r a n en s e g u n d a c o n s u l t a , es decir, a q u e l l o s registros q u e no c o i n c i d e n . Es e l

e q u i v a l e n t e a "except" en S Q L .

Sintaxis:

SENTENCIASELECTl

minus

SENTENCIASELECT2;

N o o l v i d e q u e l a s c o n s u l t a s D E B E N t e n e r el m i s m o n u m e r o de valores retornados y

l o s valores d e b e n ser d e l m i s m o t i p o .

U n a a c a d e m i a d e e n s e ñ a n z a de i d i o m a s da c l a s e s de i n g l é s y frances; a l m a c e n a los

datos de los a l u m n o s q u e e s t u d i a n i n g l é s en u n a t a b l a l l a m a d a " i n g l e s " y los q u e

están i n s c r i p t o s en "francés" en u n a t a b l a d e n o m i n a d a "trances".

La a c a d e m i a necesita el n o m b r e y d o m i c i l i o de todos l o s a l u m n o s q u e c u r s a n

s o l a m e n t e i n g l é s ( n o presentes en l a t a b l a "trances") para e n v i a r l e s p u b l i c i d a d

referente a l curso de francés. E m p l e a m o s el operador " m i n u s " para o b t e n e r d i c h a

información:

select nombre, domicilio from ingles

minus

select nombre,domicilio from frances;

O b t e n e m o s l o s registros de l a p r i m e r c o n s u l t a q u e N O c o i n c i d e n con n i n g ú n registro

de l a s e g u n d a c o n s u l t a .

" m i n u s " p u e d e c o m b i n a r s e con l a c l á u s u l a " a r d e r by".

Se p u e d e n c o m b i n a r m á s d e dos s e n t e n c i a s con " m i n u s " .


6 8 - Agregar c a m p o s (alter t a b l e - a d d )

"alter t a b l e " p e r m i t e m o d i f i c a r l a estructura d e u n a t a b l a . P o d e m o s u t i l i z a r l a para

agregar, m o d i f i c a r y e l i m i n a r c a m p o s d e u n a t a b l a .

Para a g r e g a r u n n u e v o c a m p o a u n a t a b l a e m p l e a m o s la s i g u i e n t e s i n t a x i s b á s i c a :

alter table NOMBRETABLA

add NOMBRENUEVOCAMPO DEFINICION;

E n el s i g u i e n t e e j e m p l o a g r e g a m o s el c a m p o " c a n t i d a d " a l a t a b l a " l i b r o s " , de t i p o

n u m b e r ( 4 ) , con el v a l o r por defecto cero y q u e N O acepta valores n u l o s :

alter table libros

add cantidad number(4) default 0 not null;

P u e d e verificarse l a a l t e r a c i ó n de l a estructura de l a t a b l a t i p e a n d o :

describe libros;

Para a g r e g a r u n c a m p o "not n u l l " , l a t a b l a d e b e estar vacía o d e b e especificarse u n

v a l o r por defecto. Esto es s e n c i l l o de entender, ya q u e s i l a t a b l a t i e n e registros, el

n u e v o c a m p o se l l e n a r í a con valores n u l o s ; si no los a d m i t e , d e b e tener u n v a l o r por

defecto para l l e n a r tal c a m p o en los registros existentes.


6 9 - Modificar c a m p o s ( a l t e r table- modify)

"alter t a b l e " p e r m i t e m o d i f i c a r l a estructura d e u n a t a b l a . H e m o s a p r e n d i d o a a g r e g a r

campos, t a m b i é n podemos modificarlos.

Para m o d i f i c a r u n c a m p o e m p l e a m o s l a s i g u i e n t e s i n t a x i s :

alter table NOMBRETABLA

modify NOMBRECAMPO NUEVADEFINICION;

E n el s i g u i e n t e e j e m p l o m o d i f i c a m o s el c a m p o " p r e c i o " d e l a t a b l a " l i b r o s " para q u e

tome valores d e 6 d í g i t o s i n c l u y e n d o 2 d e c i m a l e s y no acepte valores n u l o s :

alter table libros

modify precio number(6,2) not null;

P u e d e verificarse l a a l t e r a c i ó n de l a estructura de l a t a b l a t i p e a n d o :

describe libros;

P o d e m o s m o d i f i c a r d e u n c a m p o : el t i p o de d a t o , l a escala y/o p r e c i s i ó n , l a l o n g i t u d ,

l a aceptación d e v a l o r e s n u l o s , el v a l o r por defecto.

Se p u e d e n m o d i f i c a r todos l o s atributos o a l g u n o s ; l o s q u e no se e s p e c i f i c a n , no

cambian.

A l g u n a s c o n s i d e r a c i o n e s para tener en cuenta al m o d i f i c a r l o s c a m p o s de u n a t a b l a :

a ) si se c a m b i a el t i p o de dato de u n c a m p o , l a t a b l a d e b e estar v a c í a . Por e j e m p l o ,

de n u m b e r a caracteres o viceversa.

b) no p u e d e modificarse el t i p o de dato de u n c a m p o "foreign key" o referenciado por

u n a "foreign key", a m e n o s q u e e l c a m b i o no afecte l a r e s t r i c c i ó n .

e) no se p u e d e c a m b i a r el t i p o de dato de u n c a m p o q u e es "foreign key" o q u e es

referenciado por u n a "foreign key".

d ) para m o d i f i c a r u n c a m p o d i s m i n u y e n d o la l o n g i t u d ( p r e c i s i ó n o e s c a l a ) d e l t i p o de

dato, l a t a b l a D E B E estar v a c í a , los registros D E B E N tener valores n u l o s en tal

c a m p o o los datos existentes d e b e n s e r inferiores o i g u a l e s a l a n u e v a l o n g i t u d . Para

alterar l a l o n g i t u d ( e s c a l a o p r e c i s i ó n ) a u m e n t á n d o l a , no es necesario q u e la t a b l a

esté v a c í a .

e) se p u e d e m o d i f i c a r u n c a m p o d e f i n i d o " n u l l " a " n o t n u l l " , s i e m p r e q u e l a t a b l a esté

vacía o no c o n t e n g a valores n u l o s .

f) no p u e d e redefinirse como "not n u l l " u n c a m p o q u e es clave p r i m a r i a .


g ) si u n c a m p o t i e n e u n v a l o r por defecto y se modifica el t i p o de dato de tal c a m p o ,

O r a c l e a n a l i z a q u e el v a l o r por defecto p u e d a convertirse a l nuevo t i p o d e dato

c u a n d o sea n e c e s a r i o i n s e rt a r l o ; si el v a l o r por defecto no se p u e d e c o n v e rt i r al

n u e v o tipo de dato q u e se intenta modificar, la m o d i f i c a c i ó n d e l c a m p o no se r e a l i z a .

Por e j e m p l o , si u n c a m p o d e f i n i d o c h a r ( 8 ) t i e n e u n v a l o r por defecto ' 0 0 0 0 0 0 0 0 ' y se

modifica t a l c a m p o a t i p o n u m b e r ( 8 ) , Oracle p e r m i t e el c a m b i o ya q u e a l i n s e rt a r el

v a l o r por defecto, l o c o n v i e rt e a n ú m e r o (O) a u t o m á t i c a m e n t e ; si el v a l o r por defecto

no se p u e d e convertir ( p o r e j e m p l o ' a O O O O O O ' ) a v a l o r n u m é r i c o , l a m o d i f i c a c i ó n d e l

c a m p o no se r e a l i z a .
70 - E l i m i n a r c a m p o s ( a l t e r t a b l e - d r o p )

V i m o s q u e " a l t e r t a b l e " permite m o d i f i c a r l a estructura de u n a t a b l a , a g r e g a n d o ,

modificando y e l i m i n a n d o campos.

Para e l i m i n a r c a m p o s d e u n a t a b l a l a s i n t a x i s básica es la s i g u i e n t e :

alter table NOMBRETABLA

drop column NOMBRECAMPO;

E n el s i g u i e n t e e j e m p l o e l i m i n a m o s el c a m p o "precio" d e l a t a b l a " l i b r o s " :

alter table libros

drop column precio;

N o p u e d e n e l i m i n a r s e l o s c a m p o s a l o s c u a l e s hace referencia u n a restricción

"foreig n key".

S i e l i m i n a m o s u n c a m p o q u e t i e n e u n a restricción " p r i m a ry key", " u n i q u e " , "check" o

"foreign key", la restricción t a m b i é n se e l i m i n a .

S i e l i m i n a m o s u n c a m p o i n d e x a d o , el í n d i c e t a m b i é n se e l i m i n a .

N O p u e d e e l i m i n a r s e u n c a m p o si es e l ú n i c o en la t a b l a .

P u e d e verificarse l a a l t e r a c i ó n de l a estructura de l a t a b l a t i p e a n d o :

describe libros;
71 - Agregar c a m p o s y restricciones (alter

table)

P o d e m o s a g r e g a r u n c a m p o a u n a t a b l a y en el m i s m o m o m e n t o a p l i c a r l e u n a

restricción.

Para a g r e g a r u n c a m p o y establecer u n a restricción, l a s i n t a x i s básica es la s i g u i e n t e :

alter table TABLA

add CAMPO DEFINICION

constraint NOMBRERESTRICCION TIPO;

Agregamos a l a t a b l a " l i b r o s " , el c a m p o " t i t u l o " de t i p o v a r c h a r 2 ( 3 0 ) y u n a restricción

"unique":

alter table libros

add titulo varchar2(30)

constraint U Q_ l i b r o s _ a u t o r unique;

Agregamos a l a t a b l a " l i b r o s " , el c a m p o " c o d i g o " d e t i p o n u m b e r ( 4 ) not n u l l y u n a

restricción " p r i m a ry key":

alter table libros

add codigo number(4) not null

constraint PK_libros_codigo primary key;

Agregamos a l a t a b l a " l i b r o s " , el c a m p o " p r e c i o " de t i p o n u m b e r ( 6 , 2 ) y u n a restricción

"check":

alter table libros

add precio number(6,2)

constraint CK_libros_precio check (precio>=0);


7 2 - S u b c o n s u ltas

U n a s u b c o n s u l t a ( s u b q u e r y ) es u n a s e n t e n c i a "select" a n i d a d a e n otra s e n t e n c i a

" s e l e c t " , " i n s e rt " , " u p d a t e " o " d e l e t e " (o en otra s u b c o n s u l t a ) .

Las s u b c o n s u l t a s se e m p l e a n c u a n d o u n a c o n s u l t a es m u y c o m p l e j a , entonces se l a

d i v i d e en varios pasos l ó g i c o s y se o b t i e n e el resultado con u n a ú n i c a i n s t r u c c i ó n y

c u a n d o l a c o n s u l t a d e p e n d e de los resultados de otra c o n s u l t a .

G e n e r a l m e n t e , u n a s u b c o n s u l t a se p u e d e r e e m p l a z a r por c o m b i n a c i o n e s y estas

ú l t i m a s son m á s eficientes.

Las s u b c o n s u l t a s g e n e r a l m e n t e se i n c l u y e n entre p a r é n t e s i s .

P u e d e h a b e r s u b c o n s u l t a s dentro de s u b c o n s u l t a s .

G e n e r a l m e n t e l a s s u b c o n s u l t a s se colocan en l a c l á u s u l a "where".

U n a s u b c o n s u l t a p u e d e retornar:

- u n s o l o valor,

- u n a lista d e v a l o r e s d e u n a s o l a c o l u m n a ,

- u n conjunto d e registros d e varios c a m p o s .

P o d e m o s a v e r i g u a r si u n v a l o r de l a c o n s u l t a externa pertenece o no al conjunto

devuelto por u n a s u b c o n s u l t a ( " i n " , " n o t i n " ) , si es mayor, m e n o r o i g u a l a todos ( " a l l " )

o a a l g u n o s valores ( " s o rn e " , " a n y " ) d e l conjunto d e v u e l t o .

Se p u e d e n e m p l e a r s u b c o n s u l t a s :

- en l u g a r d e u n a e x p r e s i ó n , s i e m p r e q u e d e v u e l v a n u n s o l o v a l o r o u n a l i s t a de

valores.

- q u e retornen u n conjunto de registros de varios c a m p o s en l u g a r d e u n a t a b l a o

para obtener el m i s m o r e s u l t a d o q u e u n a c o m b i n a c i ó n (l o i n ) ,

H a y varios t i p o s b á s i c o s de s u b c o n s u l t a s :

- l a s q u e retornan u n s o l o v a l o r e s c a l a r q u e se u t i l i z a con u n operador de

c o m p a r a c i ó n o en l u g a r de u n a e x p r e s i ó n .

- l a s q u e retornan u n a l i s t a de v a l o r e s , se c o m b i n a n con " i n " , o los operadores " a n y " ,

" s o rn e " y " a l l " .

- l o s q u e testean l a existencia con "exists".


7 3 - S u b c o n s u l t a s c o m o expresion

U n a subconsulta puede reemplazar u n a expresión. Dicha subconsulta debe devolver

u n v a l o r e s c a l a r ( o u n a l i s t a de valores de u n c a m p o ) .

Las s u b c o n s u l t a s q u e retornan u n s o l o v a l o r e s c a l a r se u t i l i z a con u n o p e r a d o r de

c o m p a r a c i ó n o en l u g a r de u n a e x p r e s i ó n :

select CAMPOS

from TABLA

where CAMPO OPERADOR (SUBCONSULTA);

select CAMPO OPERADOR (SUBCONSULTA)

from TABLA;

S i q u e r e m o s s a b e r el precio de u n d e t e r m i n a d o l i b r o y la diferencia con el precio d e l

l i b r o m á s costoso, anteriormente d e b í a m o s a v e r i g u a r en u n a c o n s u l t a el precio d e l

l i b r o m á s costoso y l u e g o , en otra c o n s u l t a , c a l c u l a r l a diferencia con el v a l o r d e l l i b r o

q u e s o l i c i t a m o s . P o d e m o s c o n s e g u i r l o en u n a sola s e n t e n c i a c o m b i n a n d o dos

consultas:

select titulo,precio,

precio-(select max(precio) from libros) as diferencia

from libros

where titulo='Uno';

E n el e j e m p l o a n t e r i o r se muestra el t í t u l o , el precio de u n l i b r o y la diferencia entre el

precio d e l l i b r o y el m á x i m o v a l o r d e p r e c i o .

Q u e r e m o s s a b e r el t í t u l o , a u t o r y precio d e l l i b r o m á s costoso:

select titulo,autor, precio

from libros

where precio=

(select max(precio) from libros);

Note q u e el c a m p o d e l "where" d e l a c o n s u l t a exterior es c o m p a t i b l e con el v a l o r

retornado por l a expresión de l a s u b c o n s u l t a .

Se p u e d e n e m p l e a r en " s e l e c t " , " i n s e rt " , " u p d a t e " y " d e l e t e " .

Para a c t u a l i z a r u n registro e m p l e a n d o s u b c o n s u l t a l a s i n t a x i s básica es la s i g u i e n t e :

update TABLA set CAMPO=NUEVOVALOR

where CAMPO= (SUBCONSULTA);

Para e l i m i n a r registros e m p l e a n d o s u b c o n s u l t a e m p l e a m o s la s i g u i e n t e s i n t a x i s

básica:
28/11 /2017 Descripción : Subconsultas como expresion (Oracle)

delete from TABLA

where CAMPO=(SUBCONSULTA);
74 - S u b c o n s u l t a s con i n

Vimos que u n a subconsulta puede reemplazar u n a expresión. Dicha subconsulta

d e b e devolver u n v a l o r e s c a l a r o u n a lista de valores de u n c a m p o ; l a s s u b c o n s u l t a s

q u e retornan u n a l i s t a de valores reemplazan a u n a expresión en u n a c l á u s u l a

"where" q u e c o n t i e n e l a p a l a b r a clave " i n " .

E l r e s u l t a d o de u n a s u b c o n s u l t a con " i n " ( o " n o t i n " ) es u n a l i s t a . L u e g o q u e l a

s u b c o n s u l t a retorna r e s u l t a d o s , la c o n s u l t a exterior l o s u s a .

P o d e m o s a v e r i g u a r si u n v a l o r de l a c o n s u l t a externa pertenece o no al conjunto

devuelto por u n a s u b c o n s u l t a e m p l e a n d o " i n " y " n o t i n " .

La s i n t a x i s básica es l a s i g u i e n t e :

. . . where EXPRESION in (SUBCONSULTA);

Este e j e m p l o muestra l o s n o m b r e s de l a s e d i t o r i a l e s q u e ha p u b l i c a d o l i b r o s de u n

determinado autor:

select nombre

from editoriales

where codigo in

(select codigoeditorial

from libros

where autor='Richard B a c h ' ) ;

La s u b c o n s u l t a ( c o n s u l t a i n t e r n a ) retorna u n a l i s t a de valores de u n s o l o c a m p o

( c o d i g o e d i t o r i a l ) q u e l a c o n s u l t a exterior l u e g o e m p l e a al recuperar los datos.

Se a v e r i g u a si el c ó d i g o devuelto por la c o n s u l t a externa se e n c u e n t r a dentro d e l

conjunto de valores retornados por l a c o n s u l t a i n t e r n a .

P o d e m o s r e e m p l a z a r por u n " j o i n " l a c o n s u l t a a n t e r i o r :

select distinct nombre

from editoriales e

join libros

on codigoeditorial=e.codigo

where autor='Richard B a c h ' ;

U n a c o m b i n a c i ó n (j o i n ) s i e m p r e p u e d e ser expresada como u n a s u b c o n s u l t a ; pero

u n a s u b c o n s u l t a no s i e m p r e p u e d e reemplazarse por u n a c o m b i n a c i ó n q u e retorne el

m i s m o r e s u l t a d o . S i es p o s i b l e , es a c o n s e j a b l e e m p l e a r c o m b i n a c i o n e s e n l u g a r de

s u b c o n s u l t a s , son m á s eficientes.

Se r e c o m i e n d a probar l a s s u b c o n s u l t a s antes de i n c l u i r l a s en u n a c o n s u l t a exterior,

a s í p u e d e verificar q u e retorna lo n e c e s a r i o , p o r q u e a veces resulta d i f í c i l verlo en


consultas a n i d a d a s .

También p o d e m o s b u s c a r valores N o c o i n c i d e n t e s con u n a l i s t a de valores q u e

retorna u n a s u b c o n s u l t a ; por e j e m p l o , l a s e d i t o r i a l e s q u e no h a n p u b l i c a d o l i b r o s d e

u n a u t o r específico:

select nombre

from editoriales

where codigo not in

(select codigoeditorial

from libros

where autor='Richard Bach');


7 5 - S u b c o n s u l t a s any- s o rn e - a l l

" a n y " y " s o rn e " son s i n ó n i m o s . C h e q u e a n si a l g u n a fila d e la l i s t a resultado d e u n a

s u b c o n s u l t a se e n c u e n t r a el v a l o r especificado en l a c o n d i c i ó n .

C o m p a r a u n v a l o r e s c a l a r con los v a l o r e s de u n c a m p o y d e v u e l v e n "true" si l a

c o m p a r a c i ó n con cada v a l o r de la l i s t a de la s u b c o n s u l t a es verdadera, s i n o "false".

E l t i p o de datos q u e se comparan d e b e n ser c o m p a t i b l e s .

La sintaxis básica e s :

. . . VALORESCALAR OPERADORDECOMPARACION

any (SUBCONSULTA);

Q u e r e m o s s a b e r l o s t í t u l o s d e l o s l i b r o s de "Borges" q u e p e rt e n e c e n a e d i t o r i a l e s q u e

h a n p u b l i c a d o t a m b i é n l i b r o s de " R i c h a r d B a c h " , es d e c i r , s i los l i b r o s d e "Borges"

c o i n c i d e n con A L G U N A de l a s e d i t o r i a l e s q u e p u b l i c ó l i b r o s de " R i c h a r d B a c h " :

select titulo

from libros

where autor='Borges' and

codigoeditorial = any

(select e.codigo

from editoriales e

join libros 1

on codigoeditorial=e.codigo

where l.autor='Richard B a c h ' ) ;

La c o n s u l t a i n t e r n a ( s u b c o n s u l t a ) retorna u n a l i s t a de valores de u n s o l o c a m p o

( p u e d e ejecutar l a s u b c o n s u l t a como u n a c o n s u l t a para p r o b a r l a ) , l u e g o , l a c o n s u l t a

externa c o m p a r a cada v a l o r de " c o d i g o e d i t o r i a l " con cada v a l o r d e l a l i s t a

d e v o l v i e n d o l o s t í t u l o s de " B o r g e s " q u e c o i n c i d e n .

" a l l " t a m b i é n compara u n v a l o r e s c a l a r con u n a s e r i e d e v a l o r e s . C h e q u e a s i T O D O S

l o s valores de l a lista d e l a c o n s u l t a externa se e n c u e n t r a n en l a lista de valores

devuelta por l a c o n s u l t a i n t e r n a .

Sintaxis:

VALORESCALAR OPERADORDECOMPARACION all (SUBCONSULTA);

Q u e r e m o s s a b e r si TODAS l a s e d i t o r i a l e s q u e p u b l i c a r o n l i b r o s d e " B o r g e s "

c o i n c i d e n con TODAS l a s e d i t o r i a l e s q u e p u b l i c a r o n l i b r o s d e " R i c h a r d B a c h " :

select titulo

from libros

where autor='Borges' and


codigoeditorial = all

(select e.codigo

from editoriales e

join libros 1

on codigoeditorial=e.codigo

where l.autor='Richard Bach');

La c o n s u l t a i n t e r n a ( s u b c o n s u l t a ) retorna u n a l i s t a de valores de u n s o l o c a m p o

( p u e d e ejecutar l a s u b c o n s u l t a como u n a c o n s u l t a para p r o b a r l a ) , l u e g o , l a c o n s u l t a

externa c o m p a r a cada v a l o r de " c o d i g o e d i t o r i a l " con cada v a l o r d e l a l i s t a , si T O D O S

c o i n c i d e n , devuelve los títulos.

Veamos otro e j e m p l o con u n o p e r a d o r de comparación diferente:

Q u e r e m o s s a b e r si A L G U N precio de los l i b r o s de " B o r g e s " es mayor a A L G U N

precio de l o s l i b r o s d e " R i c h a r d B a c h " :

select titulo,precio

from libros

where autor='Borges' and

precio> any

(select precio

from libros

where autor='Bach');

E l precio d e cada l i b r o de " B o r g e s " es c o m p a r a d o con cada v a l o r d e l a lista d e

valores retornada por l a s u b c o n s u l t a ; si A L G U N O c u m p l e l a c o n d i c i ó n , es decir, es

mayor a A L G U N precio de " R i c h a r d B a c h " , se l i s t a .

Veamos l a diferencia si e m p l e a m o s " a l ! " en l u g a r d e " a n y " :

select titulo,precio

from libros

where autor='borges' and

precio> all

(select precio

from libros

where autor='bach');

E l precio d e cada l i b r o de "Borqes" es c o m p a r a d o con cada v a l o r d e l a lista d e

valores retornada por l a s u b c o n s u l t a ; s i c u m p l e la c o n d i c i ó n , es d e c i r , si es mayor a

T O D O S l o s precios de " R i c h a r d B a c h " (o a l mayor), se l i s t a .

E m p l e a r " = a n y " es l o m i s m o q u e e m p l e a r " i n " .

E m p l e a r " < > a l l " es lo m i s m o q u e e m p l e a r " n o t i n " .


7 6 - S u b c o n s u ltas correlacionadas

U n a l m a c é n a l m a c e n a l a i n f o r m a c i ó n d e s u s ventas en u n a t a b l a l l a m a d a "facturas"

en l a c u a l g u a r d a el n ú m e r o de factura, l a fecha y el n o m b r e d e l c l i e n t e y u n a t a b l a

d e n o m i n a d a " d e t a l l e s " e n l a c u a l se a l m a c e n a n los d i s t i n t o s items c o r r e s p o n d i e n t e s a

cada factura: e l n o m b r e d e l a rt í c u l o , el precio ( u n i t a r i o ) y l a c a n t i d a d .

Se necesita u n a l i s t a de todas l a s facturas q u e i n c l u y a el n ú m e r o , la fecha, el c l i e n t e ,

l a c a n t i d a d de a rt í c u l o s c o m p r a d o s y el total:

select f.*,

(select count(d.numeroitem)

from Detalles d

where f.numero=d.numerofactura) as cantidad,

(select sum{d.preciounitario*cantidad)

from Detalles d

where f.numero=d.numerofactura) as total

from facturas f;

E l s e g u n d o "select" retorna u n a l i s t a d e valores d e u n a s o l a c o l u m n a con l a c a n t i d a d

de i t e m s por factura ( el n ú m e r o de factura l o toma d e l "select" exterior); e l tercer

"select" retorna u n a l i s t a d e valores d e u n a s o l a c o l u m n a con el total por factura ( e l

n ú m e r o de factura l o toma d e l "select" exterior); el p r i m e r "select" (externo) devuelve

todos l o s datos d e cada factura.

A este t i p o de s u b c o n s u l t a se l a d e n o m i n a c o n s u l t a c o r r e l a c i o n a d a . La c o n s u l t a

i n t e r n a se e v a l ú a tantas veces como registros t i e n e l a c o n s u l t a externa, se realiza la

s u b c o n s u l t a para cada registro de l a c o n s u l t a externa. El c a m p o de l a t a b l a dentro d e

l a s u b c o n s u l t a ( f . n u m e r o ) se c o m p a r a con el c a m p o de la t a b l a externa.

E n este c a s o , específicamente, la c o n s u l t a externa pasa u n v a l o r de " n u m e r o " a l a

c o n s u l t a i n t e r n a . La c o n s u l t a i n t e r n a toma ese v a l o r y d e t e r m i n a si existe en

" d e t a l l e s " , si existe, la c o n s u l t a i n t e r n a d e v u e l v e l a s u m a . E l proceso se repite para el

registro de l a c o n s u l t a externa, la c o n s u l t a externa pasa otro " n u m e r o " a l a c o n s u l t a

i n t e r n a y O r a c l e repite l a e v a l u a c i ó n .
77 - Exists y N o Exists

Los operadores "exists" y " n o t exists" se e m p l e a n para d e t e r m i n a r s i hay o no datos

en u n a l i s t a de valores.

Estos operadores p u e d e n e m p l e a r s e con s u b c o n s u l t a s c o r r e l a c i o n a d a s para

r e s t r i n g i r e l r e s u l t a d o d e u n a c o n s u l t a exterior a l o s registros q u e c u m p l e n l a

s u b c o n s u l t a ( c o n s u l t a i n t e r i o r ) . Estos operadores retornan "true" (si l a s s u b c o n s u l t a s

retornan registros) o "false" ( s i l a s s u b c o n s u l t a s no retornan registros).

C u a n d o se coloca en u n a s u b c o n s u l t a el operador "exists", O r a c l e a n a l i z a si hay

datos q u e c o i n c i d e n con la s u b c o n s u l t a , no se d e v u e l v e n i n g ú n registro, es como u n

test d e e x i s t e n c i a ; Oracle t e r m i n a l a recuperación de registros c u a n d o p o r l o m e n o s

u n registro c u m p l e l a c o n d i c i ó n "where" d e l a s u b c o n s u l t a .

La s i n t a x i s b á s i c a es l a s i g u i e n t e :

. . . where exists (SUBCONSULTA);

E n este e j e m p l o se usa u n a s u b c o n s u l t a c o r r e l a c i o n a d a con u n o p e r a d o r "exists" en

l a c l á u s u l a "where" para d e v o l v e r u n a lista d e c l i e n t e s q u e c o m p r a r o n e l a rt í c u l o

"lapiz":

select cliente,numero

from facturas f

where exists

(select *from Detalles d

where f.numero=d.numerofactura

and d . a r t i c u l o = ' l a p i z ' ) ;

P u e d e o b t e n e r el m i s m o resultado e m p l e a n d o u n a c o m b i n a c i ó n .

P o d e m o s b u s c a r l o s c l i e n t e s q u e no h a n a d q u i r i d o el a rt í c u l o " l a p i z " e m p l e a n d o " i f

not exists":

select cliente,numero

from facturas f

where not exists

(select *from Detalles d

where f.numero=d.numerofactura

and d . a r t i c u l o = ' l a p i z ' ) ;


78 - S u b c o n s u l t a s i m i l a u t o c o m b i n a c i o n

A l g u n a s s e n t e n c i a s en l a s c u a l e s l a c o n s u l t a interna y la externa e m p l e a n la m i s m a

t a b l a p u e d e n reemplazarse por u n a a u t o c o m b i n a c i ó n .

Por e j e m p l o , q u e r e m o s u n a l i s t a de l o s l i b r o s q u e h a n s i d o p u b l i c a d o s por d i s t i n t a s

editoriales.

select distinct 11.titulo

from libros 11

where 11.titulo in

(select 12.titulo

from libros 12

where 11.editorial <> 12.editorial);

E n el e j e m p l o a n t e r i o r e m p l e a m o s u n a s u b c o n s u l t a c o r r e l a c i o n a d a y las c o n s u l t a s

i n t e r n a y externa e m p l e a n l a m i s m a t a b l a . La s u b c o n s u l t a devuelve u n a l i s t a d e

valores por e l l o se e m p l e a " i n " y s u s t i t u y e u n a e x p r e s i ó n e n u n a c l á u s u l a " w h e r e " .

C o n el s i g u i e n t e " j o i n " se o b t i e n e el m i s m o r e s u l t a d o :

select distinct 11.titulo

from libros 11

join libros 12

on 11.titulo=ll.titulo and

ll.autor=l2.autor

where ll.editorial<>l2.editorial;

Otro e j e m p l o : B u s c a m o s todos los l i b r o s q u e t i e n e n el m i s m o precio q u e " E l a l e p h "

empleando subconsulta:

select titulo

from libros

where titulo<>'El aleph' and

precio=

(select precio

from libros

where titulo='El aleph');

La s u b c o n s u l t a retorna u n s o l o valor. P o d e m o s obtener l a m i s m a s a l i d a e m p l e a n d o

"join".

B u s c a m o s l o s l i b r o s cuyo precio s u p e r e el precio p r o m e d i o de l o s l i b r o s por e d i t o r i a l :

select 11.titulo,ll.editorial,ll.precio

from libros 11

where 11.precio >

(select avg{l2.precio)
from libros 12

where 11.editorial= 12.editorial);

Por cada v a l o r d e 1 1 , se e v a l ú a la s u b c o n s u l t a , si el precio es mayor q u e el p r o m e d i o .

Se p u e d e c o n s e g u i r el m i s m o r e s u l t a d o e m p l e a n d o u n " j o i n " con " h a v i n g " .


79 - S u b c o n s u l t a con update y delete

D i j i m o s q u e p o d e m o s e m p l e a r s u b c o n s u l t a s en s e n t e n c i a s " i n s e rt " , " u p d a t e " ,

" d e l e t e " , a d e m á s d e "select".

La s i n t a x i s básica para r e a l i z a r a c t u a l i z a c i o n e s con s u b c o n s u l t a es l a s i g u i e n t e :

update TABLA set CAMPO=NUEVOVALOR

where CAMPO= (SUBCONSULTA);

A c t u a l i z a m o s el precio de todos los l i b r o s de e d i t o r i a l " E m e c e " :

update libros set precio=precio+(precio*0.1)

where codigoeditorial=

(select codigo

from editoriales

where nombre='Emece');

La s u b c o n s u l t a retorna u n ú n i c o valor. También p o d e m o s hacerlo con u n j o i n .

La sintaxis básica para r e a l i z a r e l i m i n a c i o n e s con s u b c o n s u l t a es la s i g u i e n t e :

delete from TABLA

where CAMPO OPERADOR (SUBCONSULTA);

E l i m i n a m o s todos los l i b r o s d e l a s e d i t o r i a l e s q u e t i e n e p u b l i c a d o s l i b r o s de " J u a n

Perez":

delete from libros

where codigoeditorial in

(select e.codigo

from editoriales e

join libros

on codigoeditorial=e.codigo

where autor='Juan Perez');

La s u b c o n s u l t a es u n a c o m b i n a c i ó n q u e retorna u n a lista de valores q u e la c o n s u l t a

externa e m p l e a a l s e l e c c i o n a r los registros para la e l i m i n a c i ó n .


80 - S u b c o n s u l t a e i n s e r t

A p r e n d i m o s q u e u n a s u b c o n s u l t a p u e d e estar dentro de u n "select", " u p d a t e " y

" d e l e t e " ; t a m b i é n p u e d e estar dentro d e u n " i n s e rt " .

P o d e m o s i n g r e s a r registros en u n a t a b l a e m p l e a n d o u n s u b s e l e c t .

La sintaxis básica es l a s i g u i e n t e :

insert into TABLAENQUESEINGRESA (CAMPOSTABLAl)

select (CAMPOSTABLACONSULTADA)

from TABLACONSULTADA;

U n profesor a l m a c e n a l a s notas de s u s a l u m n o s en u n a t a b l a l l a m a d a " a l u m n o s " .

T i e n e otra t a b l a l l a m a d a " a p r o b a d o s " , con a l g u n o s campos i g u a l e s a l a t a b l a

" a l u m n o s " pero e n e l l a s o l a m e n t e a l m a c e n a r á los a l u m n o s q u e h a n a p r o b a d o el c i c l o .

I n g r e s a m o s registros en l a t a b l a " a p r o b a d o s " s e l e c c i o n a n d o registros d e l a t a b l a

"alumnos":

insert into aprobados (documento,nota)

select (documento,nota)

from alumnos;

E n t o n c e s , se p u e d e i n s e rt a r registros en u n a t a b l a con la s a l i d a devuelta por u n a

c o n s u l t a a otra t a b l a ; para e l l o e s c r i b i m o s l a c o n s u l t a y le a n t e p o n e m o s " i n s e rt into"

j u n t o a l n o m b r e de l a t a b l a en la c u a l i n g r e s a r e m o s l o s registros y l o s campos q u e se

cargarán (si se i n g r e s a n todos los c a m p o s n o es necesario l i s t a r l o s ) .

La c a n t i d a d de c o l u m n a s d e v u e l t a s en l a c o n s u l t a d e b e ser la m i s m a q u e la cantidad

de c a m p o s a c a r g a r en el " i n s e rt " .

Se p u e d e n i n s e rt a r valores en u n a t a b l a con el resultado de u n a c o n s u l t a q u e i n c l u y a

c u a l q u i e r tipo de "join".
81 - Crear tabla a partir de otra (create table-

select)

P o d e m o s crear u n a t a b l a e i n s e rt a r datos en e l l a en u n a s o l a s e n t e n c i a c o n s u l t a n d o

otra t a b l a ( o v a r i a s ) con esta s i n t a x i s :

create table NOMBRENUEVATABLA

as SUBCONSULTA;

Es decir, se crea u n a n u e v a t a b l a y se i n s e rt a en e l l a el resultado d e u n a c o n s u l t a a

otra t a b l a .

Tenemos l a t a b l a " l i b r o s " d e u n a l i b r e r í a y q u e r e m o s crear u n a t a b l a l l a m a d a

" e d i t o r i a l e s " q u e c o n t e n g a l o s n o m b r e s de l a s e d i t o r i a l e s .

La t a b l a " e d i t o r i a l e s " , q u e n o existe, c o n t e n d r á s o l a m e n t e u n c a m p o l l a m a d o

" n o m b r e " . La t a b l a l i b r o s c o n t i e n e varios registros.

P o d e m o s crear l a t a b l a " e d i t o r i a l e s " con el c a m p o " n o m b r e " c o n s u l t a n d o l a t a b l a

" l i b r o s " y e n el m i s m o m o m e n t o i n s e rt a r l a i n f o r m a c i ó n :

create table editoriales

as (select distinct editorial as nombre from libros);

La t a b l a " e d i t o r i a l e s " se ha creado con el c a m p o " n o m b r e " s e l e c c i o n a d o d e l c a m p o

"editorial" de "libros".

Los campos de l a n u e v a t a b l a t i e n e n el m i s m o n o m b r e , t i p o de dato y valores

a l m a c e n a d o s q u e l o s c a m p o s l i s t a d o s de la t a b l a c o n s u l t a d a ; si se q u i e r e d a r otro

n o m b r e a l o s c a m p o s d e l a n u e v a t a b l a se d e b e n especificar a l i a s .

P o d e m o s e m p l e a r " g r o u p by", f u n c i o n e s de a g r u p a m i e n t o y "arder by" e n l a s

c o n s u l t a s . T a m b i é n p o d e m o s crear u n a t a b l a q u e c o n t e n g a datos d e 2 o m á s t a b l a s

empleando combinaciones.
8 2 - Vistas (create view)

U n a vista es u n objeto. U n a vista es u n a alternativa para mostrar datos de varias

t a b l a s ; es como u n a t a b l a v i rt u a l q u e a l m a c e n a u n a c o n s u l t a . Los datos a c c e s i b l e s a

través de l a vista no están a l m a c e n a d o s en l a base de d a t o s , en la base de datos se

g u a r d a l a d e f i n i c i ó n d e l a vista y no el resultado de e l l a .

E n t o n c e s , u n a vista a l m a c e n a u n a c o n s u l t a como u n objeto para u t i l i z a r s e

posteriormente. Las t a b l a s c o n s u l t a d a s en u n a vista se l l a m a n t a b l a s b a s e . E n

g e n e r a l , se p u e d e d a r u n n o m b r e a c u a l q u i e r c o n s u l t a y a l m a c e n a r l a como u n a vista.

U n a vista s u e l e l l a m a r s e t a m b i é n t a b l a v i rt u a l porque l o s resultados q u e retorna y la

m a n e r a de referenciarlas es l a m i s m a q u e para u n a t a b l a .

Las vistas p e r m i t e n :

- s i m p l i f i c a r l a a d m i n i s t r a c i ó n de los p e r m i s o s d e u s u a r i o : se p u e d e n d a r al u s u a r i o

permisos para q u e s o l a m e n t e p u e d a acceder a l o s datos a través d e vistas, e n l u g a r

de c o n c e d e r l e p e r m i s o s para acceder a ciertos c a m p o s , a s í se protegen l a s t a b l a s

base de c a m b i o s en su estructura.

- mejorar e l r e n d i m i e n t o : se p u e d e evitar t i p e a r i n s t r u c c i o n e s repetidamente

a l m a c e n a n d o en u n a vista el r e s u l t a d o de u n a c o n s u l t a c o m p l e j a q u e i n c l u y a

información de varias t a b l a s .

P o d e m o s crear vistas c o n : u n s u b c o n j u n t o d e registros y c a m p o s de u n a t a b l a ; u n a

u n i ó n de varias t a b l a s ; u n a c o m b i n a c i ó n de varias t a b l a s ; u n s u b c o n j u n t o de otra

v i s t a , c o m b i n a c i ó n de vistas y t a b l a s .

U n a vista se define u s a n d o u n " s e l e c t " .

La s i n t a x i s básica para crear u n a vista es l a s i g u i e n t e :

create view NOMBREVISTA as

SUBCONSULTA;

E l c o n t e n i d o d e u n a vista se muestra con u n " s e l e c t " :

select *from NOMBREVISTA;

E n el s i g u i e n t e e j e m p l o creamos l a vista " v i s t a _ e m p l e a d o s " , q u e es r e s u l t a d o d e u n a

c o m b i n a c i ó n en l a c u a l se m u e s t r a n 4 c a m p o s :

create view vista_empleados as

select (apellido! 1 ' ' 1 le.nombre) as nombre,sexo,

s.nombre as seccion, cantidadhijos

from empleados e
JOln secciones s

on codigo=seccion;

Para ver l a i n f o r m a c i ó n c o n t e n i d a en la vista creada a n t e r i o r m e n t e t i p e a m o s :

select *from vista_empleados;

P o d e m o s r e a l i z a r c o n s u l t a s a u n a vista como si se tratara de u n a t a b l a :

select seccion,count(*) as cantidad

from vista_empleados;

Los n o m b r e s para vistas d e b e n s e g u i r l a s m i s m a s reglas q u e c u a l q u i e r identificador.

Para d i s t i n g u i r u n a t a b l a de u n a vista p o d e m o s fijar u n a c o n v e n c i ó n para d a r l e

n o m b r e s , por e j e m p l o , c o l o c a r el sufijo ?vista? y l u e g o el n o m b r e de l a s t a b l a s

c o n s u l t a d a s en e l l a s .

Los campos y expresiones d e l a c o n s u l t a q u e define u n a vista D E B E N t e n e r u n

n o m b r e . Se d e b e c o l o c a r n o m b r e de c a m p o c u a n d o es u n c a m p o c a l c u l a d o o si hay

2 c a m p o s con el m i s m o n o m b r e . Note q u e en el e j e m p l o , a l concatenar los campos

" a p e l l i d o " y " n o m b r e " c o l o c a m o s u n a l i a s ; si no lo h u b i é s e m o s h e c h o aparecería u n

mensaje d e error p o r q u e d i c h a expresión D E B E tener u n e n c a b e z a d o , Oracle no lo

coloca por defecto.

Los n o m b r e s d e l o s c a m p o s y e x p r e s i o n e s d e l a c o n s u l t a q u e define u n a vista

D E B E N s e r ú n i c o s ( n o p u e d e h a b e r dos c a m p o s o encabezados con i g u a l n o m b r e ) .

Note q u e en l a vista d e f i n i d a en el e j e m p l o , a l c a m p o " s . n o m b r e " l e colocamos u n

a l i a s p o r q u e ya h a b í a u n e n c a b e z a d o (el a l i a s de l a c o n c a t e n a c i ó n ) l l a m a d o

" n o m b r e " y no p u e d e n repetirse, si s u c e d i e r a , a p a r e c e r í a u n mensaje d e error.

Otra s i n t a x i s es l a s i g u i e n t e :

create view NOMBREVISTA (NOMBRESDEENCABEZADOS)

as

SUBCONSULTA;

C r e a m o s otra vista d e " e m p l e a d o s " d e n o m i n a d a "vista_empleados_ingreso" q u e

a l m a c e n a l a c a n t i d a d de e m p l e a d o s por a ñ o :

create view vista_empleados_ingreso (fecha,cantidad)

as

select extract(year from fechaingreso),count(*)

from empleados

group by extract(year from fechaingreso);

La diferencia es q u e se colocan entre paréntesis los e n c a b e z a d o s d e l a s c o l u m n a s

q u e aparecerán en la v i s t a . S i no l o s colocamos y e m p l e a m o s l a s i n t a x i s vista

a n t e r i o r m e n t e , se e m p l e a n l o s n o m b r e s de l o s c a m p o s o a l i a s ( q u e en este caso

h a b r í a q u e a g r e g a r ) colocados en el "select" q u e d e f i n e l a vista. Los n o m b r e s q u e se

c o l o c a n entre p a r é n t e s i s d e b e n ser tantos como los c a m p o s o expresiones q u e se

definen e n l a vista.
Las vistas se crean en l a base de datos activa.

Al crear u n a vista, O r a c l e verifica q u e existan l a s t a b l a s a l a s q u e se h a c e n referencia

en e l l a ; no se p u e d e crear u n a vista q u e referencie t a b l a s i n e x i s t e n t e s . No se p u e d e

crear u n a vista si existe u n objeto con ese n o m b r e .

Se aconseja probar l a s e n t e n c i a "select" con l a c u a l d e f i n i r e m o s l a vista antes de

crearla para a s e g u r a r n o s q u e el resultado q u e retorna es el i m a g i n a d o .

U n a vista s i e m p r e está a c t u a l i z a d a ; si m o d i f i c a m o s l a s t a b l a s base (a l a s c u a l e s

referencia l a v i s t a ) , l a vista mostrará l o s c a m b i o s .

Se p u e d e n c o n s t r u i r vistas sobre otras v i s t a s .


8 3 - Vistas ( i n f o r m a c i ó n )

Las vistas son objetos, a s í q u e para obtener información de e l l o s p u e d e n c o n s u l t a r s e

los siguientes catálogos.

"user_catalog" nos muestra todos l o s objetos d e l u s u a r i o a c t u a l , i n c l u i d a s l a s v i s t a s .

E n l a c o l u m n a "table_type" aparece "view" s i es u n a v i s t a . E j e m p l o :

select *from user_catalog where table_type='VIEW';

"user_objects" nos muestra i n f o r m a c i ó n sobre todos los objetos d e l u s u a r i o a c t u a l .

E n l a c o l u m n a " O B J E C T_TYPE" muestra "view" si es u n a vista, aparece la fecha de

creación y d e m á s información q u e no a n a l i z a r e m o s por el m o m e n t o .

Para ver todos l o s objetos d e l u s u a r i o actual q u e s o n vistas t i p e a m o s :

select *from user_catalog where object_type='VIEW';

"user_views" nos muestra i n f o r m a c i ó n referente a todas l a s vistas d e l u s u a r i o a c t u a l ,

el n o m b r e d e l a vista, l a l o n g i t u d d e l texto, el texto q u e la d e f i n e , etc.

C o n l a s i g u i e n t e s e n t e n c i a o b t e n e m o s información sobre todas l a s vistas cuyo

n o m b r e c o m i e n c e con l a c a d e n a "VISTA":

select *from user views where view name like 'VISTA%';


84 - Vistas e l i m i n a r ( drop view)

Para q u i t a r u n a vista se e m p l e a " d r o p v i e w " :

drop view NOMBREVISTA;

E l i m i n a m o s l a vista d e n o m i n a d a " v i s t a _ e m p l e a d o s " :

drop view vista_empleados;

S i se e l i m i n a u n a t a b l a a l a q u e hace referencia u n a vista, la vista no se e l i m i n a , hay

que e l i m i n a r l a explícitamente.
8 5 - Vistas ( m o d i f i c a r datos a través de e l l a )

S i se m o d i f i c a n l o s datos d e u n a v i s t a , se modifica l a t a b l a b a s e .

Se p u e d e i n s e rt a r , a c t u a l i z a r o e l i m i n a r datos de u n a t a b l a a través de u n a v i s t a ,

t e n i e n d o en cuenta l o s i g u i e n t e , l a s m o d i f i c a c i o n e s q u e se realizan a l a s vistas:

- no p u e d e n afectar a m á s de u n a t a b l a c o n s u l t a d a . P u e d e n modificarse y e l i m i n a r s e

datos de u n a vista q u e c o m b i n a varias t a b l a s pero l a m o d i f i c a c i ó n o e l i m i n a c i ó n

s o l a m e n t e d e b e afectar a u n a s o l a t a b l a .

- no se p u e d e n c a m b i a r l o s c a m p o s resultado de u n c á l c u l o .

- p u e d e n g e n e r a r errores si afectan a c a m p o s a l a s q u e la vista no hace referencia.

Por e j e m p l o , si se i n g r e s a u n registro en u n a vista q u e c o n s u l t a u n a t a b l a q u e t i e n e

c a m p o s not n u l l q u e no están i n c l u i d o s en la vista.


8 6 - Vistas (with read o n ly)

C o n l a c l á u s u l a "with read o n l y " ( s ó l o lectura) evitamos q u e se p u e d a n r e a l i z a r

inserciones, actualizaciones y e l i m i n a c i o n e s mediante una vista.

Sintaxis:

create view NOMBREVISTA

as SUBCONSULTA

with read only;

E v i t a m o s q u e Oracle acepte " i n s e rt " , " u p d a t e " o "delete" sobre l a vista si colocamos

"with read o n l y " l u e g o d e l a s u b c o n s u l t a q u e define u n a v i s t a .

Por e j e m p l o , creamos l a s i g u i e n t e v i s t a :

create view vista_empleados

as

select apellido, nombre, sexo, seccion

from empleados

with read only;

O r a c l e r e s p o n d e con u n m e n s a j e de error ante c u a l q u i e r " i n s e rt " , " u p d a t e " o "delete"

r e a l i z a d o sobre l a v i s t a .
8 7 - Vistas modificar (create or replace view)

Para m o d i f i c a r u n a vista p u e d e e l i m i n a r l a y volver a crearla o e m p l e a r "create or

replace".

Sintaxis:

create or replace view NOMBREVISTA

as SUBCONSULTA;

Con "create or rep lace view" se modifica l a d e f i n i c i ó n d e u n a vista existente o se crea

si no existe.
8 8 - Vistas (with c h e c k o p t i o n )

Es p o s i b l e o b l i g a r a todas l a s i n s t r u c c i o n e s de modificación de datos q u e se ejecutan

en u n a vista a c u m p l i r ciertos criterios.

Por e j e m p l o , creamos l a s i g u i e n t e v i s t a :

create view vista_empleados

as

select apellido, nombre, sexo, seccion

from empleados

where seccion='Administracion'

with check option;

La vista d e f i n i d a anteriormente muestra s o l a m e n t e a l g u n o s registros y a l g u n o s

c a m p o s de " e m p l e a d o s " , l o s d e l a sección " A d m i n i s t r a c i o n " .

C o n l a c l á u s u l a "with c h e c k o p t i o n " , no se p e r m i t e n m o d i f i c a c i o n e s en a q u e l l o s

campos q u e afecten a l o s registros q u e retorna la vista. Es decir, no p o d e m o s

m o d i f i c a r e l c a m p o " s e c c i ó n " p o r q u e al h a c e r l o , tal registro ya no aparecería e n l a

v i s t a ; si p o d e m o s a c t u a l i z a r l o s d e m á s c a m p o s . Por e j e m p l o , si intentamos a c t u a l i z a r

a " S i s t e m a s " el c a m p o " s e c c i o n " de u n registro m e d i a n t e l a v i s t a , Oracle muestra u n

mensaje d e error.

La m i s m a restricción s u r g e a l ejecutar u n " i n s e rt " sobre l a v i s t a ; s o l a m e n t e p o d e m o s

i n g r e g a r registros con el v a l o r " A d m i n i s t r a c i o n " para " s e c c i o n " ; si i n t e n t a m o s i n g r e s a r

u n registro con u n v a l o r diferente de " A d m i n i s t r a c i o n " para el c a m p o " s e c c i o n " ,

O r a c l e mostrará u n m e n s a j e de error.

Sintaxis básica:

create view NOMBREVISTA

as SUBCONSULTA

with check option;


8 9 - Vistas (otras c o n s i d e r a c i o n e s )

C u a n d o creamos u n a v i s t a , Oracle verifica q u e l a s t a b l a s a l a s c u a l e s se hace

referencia en e l l a e x i s t a n . S i l a vista q u e se intenta crear hace referencia a t a b l a s

i n e x i s t e n t e s , O r a c l e muestra u n mensaje de error.

P o d e m o s "forzar" a Oracle a crear u n a vista a u n q u e no existan los objetos ( t a b l a s ,

vistas, e t c . ) q u e referenciamos e n l a m i s m a . Para e l l o d e b e m o s a g r e g a r "force" a l

crearla:

create force view NOMBREVISTA

as SUBCONSULTA;

De esta m a n e r a , p o d e m o s crear u n a vista y d e s p u é s l a s t a b l a s i n v o l u c r a d a s ; l u e g o ,

a l c o n s u l t a r l a vista, D E B E N existir l a s t a b l a s .

Al crear l a vista l a o p c i ó n p r e d e t e r m i n a d a es " n o force". Se r e c o m i e n d a crear l a s

t a b l a s y l u e g o l a s vistas n e c e s a r i a s .

Otra c u e s t i ó n a c o n s i d e r a r es l a s i g u i e n t e : si crea u n a vista con "select *" y l u e g o

agrega c a m p o s a l a estructura de l a s t a b l a s i n v o l u c r a d a s , l o s nuevos c a m p o s n o

aparecerán en l a v i s t a ; esto es p o r q u e l o s c a m p o s se s e l e c c i o n a n al ejecutar "create

v i e w " ; d e b e volver a crear l a vista ( con "create view" o "create or replace v i e w " ) .
90 - Vistas materializadas ( m a t e r i a l i z e d view)

U n a vista m a t e r i a l i z a d a se define como u n a vista c o m ú n , pero en l u g a r de a l m a c e n a r

l a d e f i n i c i ó n de l a vista, a l m a c e n a el r e s u l t a d o de la c o n s u l t a , es decir, la m a t e r i a l i z a ,

como u n objeto persistente en la base de datos.

Sintaxis:

create materialized view NOMBREVISTAMATERIALIZADA

as SUBCONSULTA;

Existen v a r i a s c l á u s u l a s q u e p o d e m o s a g r e g a r a l crear u n a vista m a t e r i a l i z a d a , pero

no l a s e s t u d i a r e m o s .

E n el "from" de l a c o n s u l t a p u e d e n listarse t a b l a s , vistas y vistas m a t e r i a l i z a d a s .

E n t o n c e s , u n a vista m a t e r i a l i z a d a a l m a c e n a su r e s u l t a d o físicamente. U n a vista

m a t e r i a l i z a d a ( m a t e r i a l i z e d view) es u n a i n s t a n t á n e a ( s n a p s h o t ) , son s i n ó n i m o s .

Para o b t e n e r i n f o r m a c i ó n acerca de l a s vistas m a t e r i a l i z a d a s p o d e m o s c o n s u l t a r el

d i c c i o n a r i o "user_objects", e n l a c o l u m n a "object_type" aparecerá " m a t e r i a l i z e d view"

si es u n a vista m a t e r i a l i z a d a . E j e m p l o :

select *from user_objects where object_type='MATERIALIZED VIEW';

También p o d e m o s c o n s u l t a r "user_mviews" para o b t e n e r i n f o r m a c i ó n d e todas l a s

vistas m a t e r i a l i z a d a s d e l u s u a r i o a c t u a l :

select *from user_mviews;

Este d i c c i o n a r i o muestra m u c h a i n f o r m a c i ó n q u e n o e x p l i c a r e m o s en d e t a l l e .

Para e l i m i n a r u n a vista m a t e r i a l i z a d a e m p l e a m o s " d r o p m a t e r i a l i z e d view":

drop materialized view NOMBREVISTAMATERIALIZADA;

Ejemplo:

drop materialized view vm_promedios;

N o se permite r e a l i z a r " i n s e rt " , " u p d a t e " n i " d e l e t e " e n l a s vistas m a t e r i a l i z a d a s .


91 - Procedimientos almacenados

U n p r o c e d i m i e n t o a l m a c e n a d o es u n conjunto de i n s t r u c c i o n e s a l a s q u e se l e s da u n

n o m b r e , se a l m a c e n a en l a base de datos activa. Permiten a g r u p a r y o r g a n i z a r

tareas repetitivas.

Ventajas:

- c o m p a rt e n l a l ó g i c a d e l a a p l i c a c i ó n con las otras a p l i c a c i o n e s , con l o c u a l el acceso

y l a s m o d i f i c a c i o n e s d e l o s datos se h a c e n en u n s o l o s i t i o .

- permiten r e a l i z a r todas l a s o p e r a c i o n e s q u e l o s u s u a r i o s necesitan evitando q u e

t e n g a n acceso directo a l a s t a b l a s .

- r e d u c e n el tráfico de red; en vez de e n v i a r m u c h a s i n s t r u c c i o n e s , los u s u a r i o s

r e a l i z a n o p e r a c i o n e s e n v i a n d o u n a ú n i c a i n s t r u c c i ó n , lo c u a l d i s m i n u y e el n ú m e r o d e

s o l i c i t u d e s entre el c l i e n t e y el servidor.

U n p r o c e d i m i e n t o a l m a c e n a d o s p u e d e hacer referencia a objetos q u e no existen al

m o m e n t o d e c r e a r l o . Los objetos d e b e n existir c u a n d o se ejecute el p r o c e d i m i e n t o

almacenado.
9 2 - P r o c e d i m i e n t o s A l m a c e n a d o s (crear­

ejecutar)

Al crear u n p r o c e d i m i e n t o a l m a c e n a d o , l a s i n s t r u c c i o n e s q u e c o n t i e n e se a n a l i z a n

para verificar si son correctas s i n t á c t i c a m e n t e . S i se e n c u e n t r a a l g ú n error, el

p r o c e d i m i e n t o se c o m p i l a , pero aparece u n mensaje "con advertencias" q u e i n d i c a tal

situación.

U n p r o c e d i m i e n t o a l m a c e n a d o se invoca l l a m á n d o l o .

E n p r i m e r l u g a r se d e b e n t i p e a r y probar l a s i n s t r u c c i o n e s q u e se i n c l u y e n en el

p r o c e d i m i e n t o a l m a c e n a d o , l u e g o , si se o b t i e n e el resultado e s p e r a d o , se crea el

procedimiento.

Los p r o c e d i m i e n t o s a l m a c e n a d o s p u e d e n hacer referencia a t a b l a s , vistas, a

f u n c i o n e s d e f i n i d a s p o r el u s u a r i o , a otros p r o c e d i m i e n t o s a l m a c e n a d o s .

U n procedimiento almacenado pueden i n c l u i r c u a l q u i e r cantidad y tipo de

i n s t r u c c i o n e s D M L ( d e m a n i p u l a c i ó n d e d a t o s , como i n s e rt , u p d a t e , d e l a t e ) , no

i n s t r u c c i o n e s D D L ( d e d e f i n i c i ó n de datos, como create . . . , drop . . . alter . . . ) .

Para crear u n p r o c e d i m i e n t o a l m a c e n a d o e m p l e a m o s la i n s t r u c c i ó n "create

p r o c e d u r e " . La s i n t a x i s b á s i c a p a r c i a l e s :

create or replace procedure NOMBREPROCEDIMIENTO

as

be g i n

INSTRUCCIONES

end;

E l b l o q u e d e i n s t r u c c i o n e s c o m i e n z a l u e g o de " b e g i n " y a c a b a con " e n d " .

S i e m p l e a m o s " o r r e p l a c e " , se sobreescribe (se r e e m p l a z a ) u n p r o c e d i m i e n t o

existente; si se omite y existe u n p r o c e d i m i e n t o con el n o m b r e q u e le a s i g n a m o s ,

O r a c l e mostrará u n m e n s a j e de error i n d i c a n d o tal s i t u a c i ó n .

Para d i f e r e n c i a r l o s p r o c e d i m i e n t o s a l m a c e n a d o s d e l s i s t e m a de l o s p r o c e d i m i e n t o s

a l m a c e n a d o s creados por el u s u a r i o u s e u n prefijo, por e j e m p l o "pa_" c u a n d o l e s d e

el n o m b r e .

C o n l a s s i g u i e n t e s i n s t r u c c i o n e s creamos u n p r o c e d i m i e n t o a l m a c e n a d o l l a m a d o

" p a _ l i b r o s _ a u m e n t a r 1 O" q u e i n c r e m e n t a e n u n 1 0 % e l precio d e todos l o s l i b r o s :

create procedure pa_libros_aumentar10

as

update libros set precio=precio+precio*0.1;


E n t o n c e s , creamos u n p r o c e d i m i e n t o a l m a c e n a d o c o l o c a n d o "create procedure" (o

"create or r e p l a c e " , s i es q u e desea r e e m p l a z a r el existente), l u e g o el n o m b r e d e l

p r o c e d i m i e n t o y s e g u i d o de "as" l a s s e n t e n c i a s q u e d e f i n e n el p r o c e d i m i e n t o .

Para ejecutar e l p r o c e d i m i e n t o a l m a c e n a d o creado anteriormente t i p e a m o s :

execute pa_libros_aumentar10;

E n t o n c e s , para ejecutar u n p r o c e d i m i e n t o a l m a c e n a d o colocamos "execute" s e g u i d o

del nombre del procedimiento.


9 3 - P r o c e d i m i e n t o s Almacenados ( e l i m i n a r )

Los p r o c e d i m i e n t o s a l m a c e n a d o s se e l i m i n a n con " d r o p p r o c e d u r e " . S i n t a x i s :

drop procedure NOMBREPROCEDIMIENTO;

E l i m i n a m o s el p r o c e d i m i e n t o a l m a c e n a d o l l a m a d o " p a _ l i b r o s _ a u m e n t a r 1 0 " :

drop procedure pa_libros_aumentar10;

S i el p r o c e d i m i e n t o q u e q u e r e m o s e l i m i n a r no existe, aparece u n mensaje de error

i n d i c a n d o tal s i t u a c i ó n .

P o d e m o s e l i m i n a r u n a t a b l a referenciada en u n p r o c e d i m i e n t o a l m a c e n a d o , Oracle lo

p e r m i t e , pero l u e g o , a l ejecutar el p r o c e d i m i e n t o , aparecerá u n mensaje de error

p o r q u e l a t a b l a referenciada no existe.

S i a l crear u n p r o c e d i m i e n t o a l m a c e n a d o colocamos "create or replace procedure . . . " ,

el n u e v o p r o c e d i m i e n t o r e e m p l a z a a l anterior.
94 - Procedimientos almacenados (parámetros de entrada)

Los procedimientos a l m a c e n a d o s p u e d e n recibir y devolver información; para e l l o se e m p l e a n parámetros.

Veamos los primeros. Los parámetros de entrada p o s i b i l i t a n pasar información a un procedimiento. Para q u e un

procedimiento a l m a c e n a d o admita parámetros de entrada se deben declarar al crearlo. La sintaxis e s :

create or replace procedure NOMBREPROCEDIMIENTO (PARAMETRO in TIPODEDATO)

as

begin

INSTRUCCIONES;

end;

Los parámetros se definen l u e g o del nombre del procedimiento. Pueden declararse varios parámetros por procedimiento,

se separan por comas.

C u a n d o el procedimiento es ejecutado, deben explicitarse valores para cada u n o de los parámetros (en el orden q u e

fueron d e f i n i d o s ) , a menos q u e se haya definido un valor por defecto, en tal caso, pueden omitirse.

Creamos un procedimiento q u e recibe el nombre de u n a editorial como parámetro y l u e g o lo utiliza para aumentar los

precios de tal editoria l:

create or replace procedure pa_libros_aumentar10(aeditorial in varchar2)

as

be g i n

update libros set precio=precio+(precio*0.1)

where editorial=aeditorial;

end;

El procedimiento se ejecuta colocando "execute" ( o "exec") s e g u i d o del nombre del procedimiento y un v a l o r para el

parámetro:

execute pa_libros_aumentar10('Planeta');

Luego de definir un parámetro y su tipo, o p c i o n a l m e n t e , se p u e d e especificar un valor por defecto; tal v a l o r es el q u e

asume el procedimiento al ser ejecutado si no recibe parámetros. Si no se coloca valor por defecto, un procedimiento

definido con parámetros no puede ejecutarse s i n valores para e l l o s . El v a l o r por defecto puede ser " n u l l " o u n a constante.

Creamos otro procedimiento q u e recibe 2 parámetros, el nombre de u n a editorial y el valor de incremento ( q u e tiene por

defecto el valor 1 O):

create or replace procedure pa_libros_aumentar(aeditorial in varchar2,aporcentaje in number default 10

as

be g i n

update libros set precio=precio+(precio*aporcentaje/100)

where editorial=aeditorial;

end;

El procedimiento se ejecuta colocando "execute" ( o "exec") s e g u i d o del nombre del procedimiento y los valores para los

parámetros separados por comas:

execute pa_libros_aumentar('Planeta',30);

Podemos o m i t i r el s e g u n d o parámetro al invocar el procedimiento porque tiene establecido u n valor por defecto:

execute pa_libros_aumentar('Planeta');

En caso q u e u n procedimiento tenga definidos varios parámetros con valores por defecto y al invocarlo colocamos u n o

s o l o , Oracle a s u m e q u e es el primero de e l l o s . si son de tipos de datos diferentes, Oracle los convierte. Por ejemplo,

definimos u n procedimiento a l m a c e n a d o de la s i g u i e n t e manera:

create or replace procedure pa_libros_insertar

(atitulo in varchar2 default null, aautor in varchar2 default 'desconocido',

aeditorial in varchar2 default 'sin especificar', aprecio in number default 0)

as

be g i n

insert into libros values (atitulo,aautor,aeditorial,aprecio);

end;
Si l u e g o l l a m a m o s al procedimiento e n v i á n d o l e s solamente el p r i m e r y cuarto parámetro correspondientes al título y

precio:

execute pa_libros_insertar('Uno',100);

Oracle a s u m e que los argumentos son el primero y s e g u n d o , el registro q u e se almacenará será:

Uno,100,sin especificar,0;
9 5 - P r o c e d i m i e n t o s a l m a c e n a d o s (variables)

Los p r o c e d i m i e n t o s a l m a c e n a d o s p u e d e n c o n t e n e r en su d e f i n i c i ó n , v a r i a b l e s l o c a l e s ,

q u e existen d u r a n t e el p r o c e d i m i e n t o .

La sintaxis para d e c l a r a r v a r i a b l e s dentro d e u n p r o c e d i m i e n t o a l m a c e n a d o es l a

siguiente:

create or replace procedure NOMBREPROCEDIMIENTO (PARAMETRO in TIPODEDATO)

as

NOMBREVARIABLE TIPO;

be g i n

INSTRUCCIONES;

end;

Las v a r i a b l e s se d e f i n e n antes d e l b l o q u e d e s e n t e n c i a s ; p u e d e n declararse v a r i a s .

Cr ea m o s u n p r o c e d i m i e n t o q u e recibe el n o m b r e de u n l i b r o , en u n a v a r i a b l e

g u a r d a m o s el n o m b r e d e l autor de tal l i b r o , l u e g o b u s c a m o s todos los l i b r o s de ese

autor y l o s a l m a c e n a m o s en u n a t a b l a :

create or replace procedure pa_autorlibro(atitulo in varchar2)

as

vautor varchar2;

be g i n

vautor= select autor from libros where titulo=atitulo;

drop table tablal;

create table tablal(

titulo varchar2(40),

precio number(6,2)

) ;

insert into tablal

select titulo,precio

from libros

where autor=vautor;

end;

Ejecutamos el p r o c e d i m i e n t o : execute p a _ a u t o r l i b r o ( ' l l u s i o n e s ' ) ;

L u e g o de d e f i n i r u n parámetro y su t i p o , o p c i o n a l m e n t e , se p u e d e especificar u n v a l o r

por defecto; tal v a l o r es el q u e a s u m e el p r o c e d i m i e n t o a l ser ejecutado si no recibe

parámetros. S i no se coloca valor por defecto, u n p r o c e d i m i e n t o d e f i n i d o con

parámetros no p u e d e ejecutarse s i n valores para e l l o s .


9 6 - P r o c e d i m i e n t o s Almacenados

(informacion)

Los p r o c e d i m i e n t o s a l m a c e n a d o s son objetos, a s í q u e para o b t e n e r i n f o r m a c i ó n de

e l l o s p u e d e n consultarse los s i g u i e n t e s d i c c i o n a r i o s :

- "user_objects": nos muestra todos los objetos d e l a base d e datos s e l e c c i o n a d a ,

i n c l u i d o s los p r o c e d i m i e n t o s . E n la c o l u m n a "object_type" aparece " p r o c e d u r e " si es

un procedimiento almacenado.

E n el s i g u i e n t e e j e m p l o s o l i c i t a m o s todos l o s objetos q u e son p r o c e d i m i e n t o s :

select *from user_objects where object_type='PROCEDURE';

- "user_procedures": nos muestra todos l o s p r o c e d i m i e n t o s a l m a c e n a d o s de l a base

de datos a c t u a l . E n el s i g u i e n t e e j e m p l o s o l i c i t a m o s información de todos l o s

p r o c e d i m i e n t o s q u e c o m i e n z a n con "PA":

select *from user_procedures where object_name like 'PA_%';


97 - Funciones

O r a c l e ofrece varios tipos de f u n c i o n e s para r e a l i z a r d i s t i n t a s o p e r a c i o n e s . H e m o s e m p l e a d o

varias d e e l l a s .

Se p u e d e n e m p l e a r l a s f u n c i o n e s d e l sistema e n c u a l q u i e r l u g a r e n el q u e se permita u n a

expresión en u n a s e n t e n c i a "select".

Ahora a p r e n d e r e m o s a crear nuestras p r o p i a s f u n c i o n e s .

Las f u n c i o n e s , como l o s p r o c e d i m i e n t o s a l m a c e n a d o s son b l o q u e s d e código q u e permiten

a g r u p a r y o r g a n i z a r sentencias S Q L q u e se ejecutan a l invocar l a f u n c i ó n .

Las f u n c i o n e s t i e n e n u n a estructura s i m i l a r a l a d e l o s p r o c e d i m i e n t o s . C o m o los

p r o c e d i m i e n t o s , l a s f u n c i o n e s t i e n e n u n a cabecera, u n a sección d e d e c l a r a c i ó n d e v a r i a b l e s y

e l b l o q u e " b e g i n . . . e n d " q u e encierra l a s a c c i o n e s . U n a f u n c i ó n , a d e m á s c o n t i e n e l a c l á u s u l a

"return".

U n a f u n c i ó n acepta parámetros, se invoca con su n o m b r e y retorna u n valor.

Para crear u n a f u n c i ó n e m p l e a m o s l a instrucción "create function" o "create or r e p l a c e

f u n c t i o n " . S i e m p l e a m o s "or r e p l a c e " , se sobreescribe (se r e e m p l a z a ) u n a f u n c i ó n existente; si

se o m i t e y existe u n a f u n c i ó n con e l n o m b r e q u e l e a s i g n a m o s , O r a c l e mostrará u n mensaje d e

error i n d i c a n d o tal s i t u a c i ó n .

La s i n t a x i s básica parcial e s :

create o replace function NOMBREFUNCION(PARAMETROl TIPODATO, PARAMETRON TIPODATO)

return TIPODEDATO is

DECLARACION DE VARIABLES

be g i n

ACCIONES;

return VALOR;

end;

La s i g u i e n t e f u n c i o n recibe 1 parámetro, u n v a l o r a i n c r e m e n t a r y retorna e l v a l o r i n g r e s a d o

como a r g u m e n t o con el i n c r e m e n t o d e l 1 0 % :

create or replace function f incremento10 (avalor number)

return number

is

be g i n

return avalor+(avalor*0.1);

end;

Podemos e m p l e a r l a s f u n c i o n e s e n c u a l q u i e r l u g a r e n e l q u e se permita u n a e x p r e s i ó n e n u n a

s e n t e n c i a "select", p o r e j e m p l o :

select titulo,precio,f_incremento10(precio) from libros;

E l resultado mostrará e l t í t u l o d e cada l i b r o , e l precio y e l precio i n c r e m e n t a d o e n u n 1 0 %

d e v u e l t o por l a f u n c i ó n .
La s i g u i e n t e f u n c i o n recibe 2 parámetros, u n v a l o r a i n c r e m e n t a r y el i n c r e m e n t o y retorna el

valor i n g r e s a d o como p r i m e r a r g u m e n t o con el i n c r e m e n t o especificado por el s e g u n d o

argumento:

create or replace function f incremento (avalar number, aincremento number)

return number

is

be g i n

return avalor+(avalor*aincremento/100);

end;

R e a l i z a m o s u n "select" y l l a m a m o s a l a f u n c i ó n creada a n t e r i o r m e n t e , e n v i a n d o como p r i m e r

a r g u m e n t o el campo " p r e c i o " y como s e g u n d o a r g u m e n t o el v a l o r " 2 0 " , es d e c i r , incrementará

en u n 20" l o s precios de los l i b r o s :

select titulo,precio,f_incremento(precio,20) from libros;

El resultado nos mostrará el t í t u l o de cada l i b r o , el precio y el precio incrementado en u n 2 0 %

d e v u e l t o por la f u n c i ó n .

Podemos r e a l i z a r otros "select" l l a m a n d o a l a f u n c i ó n con otro v a l o r como s e g u n d o a r g u m e n t o ,

por e j e m p l o :

select titulo,precio,f_incremento(precio,50) from libros;

La s i g u i e n t e f u n c i ó n recibe u n parámetro de t i p o n u m é r i c o y retorna u n a cadena de caracteres.

Se define u n a v a r i a b l e en la zona de d e f i n i c i ó n de v a r i a b l e s d e n o m i n a d a "valorretornado" de

tipo varchar. En el cuerpo de la f u n c i ó n e m p l e a m o s u n a estructura c o n d i c i o n a l (if) para

a v e r i g u a r si el v a l o r e n v i a d o como argumento es m e n o r o i g u a l a 2 0 , si l o e s , a l m a c e n a m o s en

la v a r i a b l e "valorretornado" l a c a d e n a " e c o n o m i c o " , en caso contrario g u a r d a m o s en tal v a r i a b l e

la c a d e n a "costoso"; al f i n a l i z a r la estructura c o n d i c i o n a l retornamos l a v a r i a b l e

"val orretornado":

create or replace function f costoso (avalar number)

return varchar

is

valorretornado varchar(20);

be g i n

valorretornado:=' ' ;

if avalor<=20 then

valorretornado:='economico';

else valorretornado:='costoso';

end if;

return valorretornado;

end;

R e al i z a m os u n "select" y l l a m a m o s a l a f u n c i ó n creada a n t e r i o r m e n t e , e n v i a n d o como

a r g u m e n t o el campo " p r e c i o " :

select titulo,precio,f_costoso(precio) from libros;

El resultado mostrará el t í t u l o de cada l i b r o , el precio y el r e s u l t a d o devuelto por la f u n c i ó n (si el

precio es m e n o r o mayor a $ 2 0 , l a cadena " e c o n o m i c o " o "costoso" respectivamente).

Entonces, u n a f u n c i ó n es u n b l o q u e de código q u e i m p l e m e n t a acciones y q u e es referenciado

por u n n o m b r e . P u e d e recibir a r g u m e n t o s . La diferencia con l o s procedimientos es q u e retornan

un valor siempre.
Para a s i g n a r u n v a l o r a u n a v a r i a b l e , dentro de u n a f u n c i ó n D E B E u s a r s e " : = " (dos puntos e

igual).

Si no se l e definen parámetros a u n a f u n c i ó n , no d e b e n colocarse los paréntesis.

Podemos e m p l e a r u n a f u n c i ó n s i n i n c l u i r campos de u n a t a b l a . Por e j e m p l o :

select f_costoso (10) from dual;

Para a l m a c e n a r los valores de u n "select" d e b e m o s t i p e a r :

select . . . into VARIABLE from . . .

Por e j e m p l o :

select sum(precio) into variable from libros where autor='';

La s i g u i e n t e f u n c i ó n recibe dos valores n u m é r i c o s como parámetros y retorna el p r o m e d i o :

create or replace function f_promedio (avalorl number, avalor2 number)

return number

is

be g i n

return (avalorl+avalor2)/2;

end;

L l a m a m o s a l a f u n c i ó n "f_ p r o m e d i o " :

exec f_promedio (10,20);


9 8 - C o n t r o l de f l u j o (if)

Las estructuras d e control p u e d e n ser c o n d i c i o n a l e s y repetitivas.

Estructuras de control de flujo, bifurcaciones c o n d i c i o n a l e s y b u c l e s . Veremos l a s

c o n d i c i o n a l e s . existen 2 : if y c a s e .

Existen p a l a b r a s e s p e c i a l e s q u e pertenecen a l l e n g u a j e de control d e flujo q u e

c o n t r o l a n l a ejecución de l a s s e n t e n c i a s , l o s b l o q u e s de s e n t e n c i a s y p r o c e d i m i e n t o s

a l m a c e n a d o s . Tales p a l a b r a s s o n : " b e g i n . . . e n d " , " i f . . . e l s e " , " w h i l e " , "break" y

" c o n t i n u e " , "return" y "waitfor".

" i f . . . e l s e " testea u n a c o n d i c i ó n ; se e m p l e a c u a n d o u n b l o q u e d e s e n t e n c i a s d e b e ser

ejecutado si u n a c o n d i c i ó n se c u m p l e y si no se c u m p l e , se debe ejecutar otro b l o q u e

de s e n t e n c i a s diferente.

Sintaxis:

if (CONDICION) then

SENTENCIAS-- si la condición se cumple

else

SENTENCIAS-- si la condición resulta falsa

end if;
9 9 - C o n t r o l de f l u j o ( c a s e )

V i m o s q u e hay d o s estructuras c o n d i c i o n a l e s , a p r e n d i m o s "if", nos d e t e n d r e m o s

ahora en " c a s e " .

A p r e n d i m o s q u e el "if' se e m p l e a b a c u a n d o t e n í a m o s 2 cursos d e a c c i ó n , es d e c i r , se

e v a l ú a u n a c o n d i c i ó n y se ejecutan diferentes b l o q u e s de s e n t e n c i a s s e g ú n e l

r e s u l t a d o d e l a c o n d i c i ó n sea verdadero o falso.

La estructura "case" es s i m i l a r a " i f ' , s ó l o q u e se p u e d e n establecer varias

c o n d i c i o n e s a c u m p l i r . Con el "if' s o l a m e n t e p o d e m o s o b t e n e r dos s a l i d a s , c u a n d o l a

c o n d i c i ó n resulta verdadera y c u a n d o es f a l s a , si q u e r e m o s m á s o p c i o n e s p o d e m o s

usar "case".

Sintaxis:

case VALORACOMPARAR

when VALORl then SENTENCIAS;

when VALOR2 then SENTENCIAS;

when VALOR3 then SENTENCIAS;

else SENTENCIAS;

end case;

E n t o n c e s , se e m p l e a "case" c u a n d o t e n e m o s varios cursos d e a c c i ó n ; es d e c i r , por

cada v a l o r hay u n " w h e n . . . t h e n " ; si e n c u e n t r a u n v a l o r c o i n c i d e n t e en a l g ú n "where"

ejecuta e l " t h e n " c o r r e s p o n d i e n t e a ese " w h e r e " , si no h a y n i n g u n a c o i n c i d e n c i a , se

ejecuta e l " e l s e " . F i n a l m e n t e se coloca " e n d case" para i n d i c a r q u e el "case" ha

finalizado.

N e c e s i t a m o s , d a d a u n a fecha, obtener el n o m b r e d e l mes en e s p a ñ o l . P o d e m o s

u t i l i z a r l a estructura c o n d i c i o n a l " c a s e " . Para e l l o crearemos u n a f u n c i ó n q u e reciba

u n a fecha y retorne u n a cadena de caracteres i n d i c a n d o el n o m b r e d e l mes d e l a

fecha e n v i a d a como a r g u m e n t o :

create or replace function f_mes(afecha date)

return varchar2

is

mes varchar2(20);

be g i n

mes:='enero';

case extract(month from afecha)

when 1 then mes:='enero';

when 2 then mes:='febrero';

when 3 then mes:='marzo';

when 4 then mes:='abril';

when 5 then mes:='mayo';

when 6 then mes:='junio';


when 7 then mes:='julio';

when 8 then mes:='agosto';

when 9 then mes:='setiembre';

when 10 then mes:='octubre';

when 11 then mes:='noviembre';

else mes:='diciembre';

end case;

return mes;

end;

S i probamos l a f u n c i ó n a n t e r i o r e n v i á n d o l e la s i g u i e n t e fecha:

select f_mes('10/10/2008') from dual;

o b t e n d r e m o s como resultado " o c t u b r e " .

La s i g u i e n t e f u n c i ó n recibe u n a fecha y retorna si se e n c u e n t r a en el 1 º , 2 ° , 3° ó 4°

trimestre d e l a ñ o :

create or replace function f_trimestre(afecha date)

return varchar2

is

mes varchar2(20);

trimestre number;

begin

mes:=extract(month from afecha);

trimestre:=4;

case mes

when 1 then trimestre:=1;

when 2 then trimestre:=1;

when 3 then trimestre:=1;

when 4 then trimestre:=2;

when 5 then trimestre:=2;

when 6 then trimestre:=2;

when 7 then trimestre:=3;

when 8 then trimestre:=3;

when 9 then trimestre:=3;

else trimestre:=4;

end case;

return trimestre;

end;

La c l á u s u l a " e l s e " p u e d e o m i t i r s e , en caso q u e no se e n c u e n t r e c o i n c i d e n c i a con

n i n g u n o de l o s " w h e r e " , se s a l e d e l "case" s i n modificar el v a l o r de l a v a r i a b l e

" t r i m e s t r e " , con lo c u a l , retorna el v a l o r 4 , q u e es q u e q u e a l m a c e n a b a antes d e

entrar a l a estructura " c a s e " .

Otra d i f e r e n c i a con "if' es q u e el "case" toma valores p u n t u a l e s , no e x p r e s i o n e s . No

es p o s i b l e r e a l i z a r c o m p a r a c i o n e s en cada " w h e r e " . La s i g u i e n t e s i n t a x i s provocaría

u n error:
case mes

when >=1 then trimestre:=1;

when >=4 then trimestre:=2;

when >=7 then trimestre:=3;

when >=10 then trimestre:=4;

end case;

S i h a y m á s de u n a s e n t e n c i a en u n " w h e n . . . t h e n " N O es n e c e s a r i o d e l i m i t a r l a s con

"begin . . . end".

P o d e m o s e m p l e a r "case" dentro d e u n " s e l e c t " . Veamos u n e j e m p l o s i m i l a r a la

función anterior:

select nombre,fechanacimiento,

case extract(month from fechanacimiento)

when 1 then 1

when 2 then 1

when 3 then 1

when 4 then 2

when 5 then 2

when 6 then 2

when 7 then 3

when 8 then 3

when 9 then 3

else 4

end as trimestre

from empleados

order by trimestre;
1 0 0 - C o n t r o l de flujo ( l o o p )

Las estructuras repetitivas permiten ejecutar u n a s e c u e n c i a de s e n t e n c i a s varias veces. Hay

tres estructuras repetitivas, o b u c l e s : l o o p , for y w h i l e .

C o m e n z a m o s por " l o o p " , q u e es l a más s i m p l e . Veremos l a sintaxis d e l b u c l e " l o o p " q u e

c o m b i n a u n a c o n d i c i ó n y la p a l a b r a "exit".

Sintaxis:

loop

SENTENCIAS;

exit when CONDICION;

SENTENCIAS;

end loop;

C u a n d o se l l e g a a la l í n e a de código en l a q u e se e n c u e n t r a la c o n d i c i ó n "exit w h e n " , se

e v a l ú a d i c h a c o n d i c i ó n , si resulta c i e rt a , se salta a l a l í n e a d o n d e se encuentra "end l o o p " ,

s a l i e n d o d e l b u c l e , o m i t i e n d o l a s sentencias existentes antes d e l "end l o o p " ; en caso contrario,

si la c o n d i c i ó n resulta f a l s a , se c o n t i n ú a con l a s s i g u i e n t e s s e n t e n c i a s y a l l l e g a r a "end l o o p "

se repite el b u c l e .

La s i n t a x i s anterior es e q u i v a l e n t e a l a s i g u i e n t e :

loop

SENTENCIAS

if CONDICION then

exit;

end if;

SENTENCIAS

end loop;

En este e j e m p l o se muestra la t a b l a d e l 3 . Se va i n c r e m e n t a n d o la v a r i a b l e " m u l t i p l i c a d o r " y se

a l m a c e n a en u n a v a r i a b l e " r e s u l t a d o " ; el c i c l o se repite hasta q u e el m u l t i p l i c a d o r l l e g a a 5 , es

d e c i r , 6 veces.

set serveroutput on;

declare

resultado number;

multiplicador number:=0;

begin

loop

resultado:=3*multiplicador;

dbms_output.put_line('3x' 1 lto_char(multiplicador)I 1 ' = ' 1 lto_char(resultado));

multiplicador:=multiplicador+l;

exit when multiplicador>S;

end loop;

end;

En el s i g u i e n t e e j e m p l o se muestra la t a b l a d e l 4 . Se va i n c r e m e n t a n d o l a v a r i a b l e

" m u l t i p l i c a d o r " y se a l m a c e n a en u n a v a r i a b l e " r e s u l t a d o " ; el c i c l o se repite hasta q u e l a

v a r i a b l e resultado l l e g a o supera el v a l o r 5 0 .
declare

resultado number;

multiplicador number:=0;

begin

loop

resultado:=4*multiplicador;

exit when resultado>=50;

dbms_output.put_line('4x' 1 lto_char(multiplicador)I 1 ' = ' 1 lto_char(resultado));

multiplicador:=multiplicador+l;

end loop;

end;

C u a n d o se c u m p l e la c o n d i c i ó n d e l "exit w h e n " ( s u p e r a el v a l o r 5 0 ) , no se ejecutan l a s

s e n t e n c i a s s i g u i e n t e s ( l í n e a s de s a l i d a y de i n c r e m e n t o de " m u l t i p l i c a d o r " ) , se salta a "end

loop" f i n a l i z a n d o el b u c l e .
1 O1 - C o n t r o l de flujo (for)

Vimos q u e hay tres estructuras repetitivas, o b u c l e s , ya e s t u d i a m o s " l o o p " .

C o n t i n u a m o s con "for".

E n l a s e n t e n c i a "for. . . l o o p " se especifican dos enteros, u n l í m i t e inferior y u n l í m i t e

s u p e r i o r , es d e c i r , u n rango d e enteros, l a s s e n t e n c i a s se ejecutan u n a vez por cada

entero; e n cada repetición d e l b u c l e , l a v a r i a b l e contador d e l "for" se i n c r e m e n t a en

uno.

Sintaxis:

for VARIABLECONTADOR in LIMITEINFERIOR . . LIMITESUPERIOR loop

SENTENCIAS;

end loop;

"Variablecontador" d e b e s e r u n a v a r i a b l e n u m é r i c a entera; " l i m i t e i n f e r i o r " y

" l i m i t e s u p e r i o r " son e x p r e s i o n e s n u m é r i c a s . La v a r i a b l e q u e se e m p l e a como contador

N O se d e f i n e , se d e f i n e a u t o m á t i c a m e n t e d e t i p o entero al i n i c i a r el b u c l e y se l i b e r a r á

al finalizarlo.

E n el s i g u i e n t e e j e m p l o se muestra la t a b l a d e l 3 . La v a r i a b l e "f" c o m i e n z a en cero

( l í m i t e inferior d e l for) y se va i n c r e m e n t a n d o de a u n o ; el ciclo se repite hasta q u e "f'

l l e g a a 5 (1 í m i t e s u p e r i o r d e l for), c u a n d o l l e g a a 6 , el b u c l e f i n a l i z a .

set serveroutput on;

be g i n

for f i n 0 . . 5 loop

dbms_output.put_line('3x' 1 lto_char(f)I 1 ' = ' 1 lto_char(f*3));

end loop;

end;

S i q u e r e m o s q u e el contador se decremente en cada r e p e t i c i ó n , en l u g a r de

i n c r e m e n t a r s e , d e b e m o s colocar "reverse" l u e g o d e " i n " y antes d e l l í m i t e inferior; el

c o n t a d o r comenzará por el v a l o r d e l l í m i t e s u p e r i o r y f i n a l i z a r á a l l l e g a r a l l í m i t e inferior

d e c r e m e n t a n d o de a u n o . En este e j e m p l o mostramos la t a b l a d e l 3 d e s d e el 5 hasta el

cero:

be g i n

for f i n reverse 0 . . 5 loop

dbms_output.put_line('3*' l lto_char(f)I I ' = ' l lto_char(f*3));

end loop;

end;

Se p u e d e n colocar "for" dentro de otro "for". Por e j e m p l o , con l a s s i g u i e n t e s I íneas

i m p r i m i m o s las tablas del 2 y del 3 del 1 al 9 :

be g i n

for f i n 2 . . 3 loop
dbms_output.put_line('tabla del ' 1 lto_char(f));

for g i n 1 . . 9 loop

dbms_output.put_line(to_char(f)I 1 'x' 1 lto_char(g)I 1 ' = ' 1 lto_char(f*g));

end loop;--fin del for g

end loop;--fin del for f

end;
1 0 2 - C o n t r o l de f l u j o (whi le l o o p )

Ya e s t u d i a m o s d o s de l a s tres estructuras repetitivas. C o n t i n u a m o s con " w h i l e " .

V i m o s q u e l a s s e n t e n c i a s repetitivas p e r m i t e n ejecutar u n a s e c u e n c i a d e s e n t e n c i a s

varias veces.

Se coloca l a p a l a b r a " l o o p " antes de l a s s e n t e n c i a s y a l f i n a l " e n d l o o p " .

" w h i l e . . . l o o p " ( m i e n t r a s ) ejecuta r e p e t i d a m e n t e u n a i n s t r u c c i ó n (o b l o q u e de

i n s t r u c c i o n e s ) s i e m p r e q u e l a c o n d i c i ó n sea verdadera.

Sintaxis básica:

while CONDICION loop

SENTENCIAS

end loop;

La diferencia entre " w h i l e . . . l o o p " y "for. . . l o o p " es q u e e n la s e g u n d a se p u e d e

establecer l a c a n t i d a d de repeticiones d e l b u c l e con el v a l o r i n i c i a l y f i n a l . A d e m á s , el

s e g u n d o s i e m p r e se ejecuta, a l m e n o s u n a vez, en c a m b i o el p r i m e r o p u e d e no

ejecutarse n u n c a , caso en el c u a l a l e v a l u a r l a c o n d i c i o n por p r i m e r a vez resulte

falsa.

E n el s i g u i e n t e e j e m p l o se muestra l a t a b l a d e l 3 hasta el 5 :

set server output on;

execute dbms_output.enable (20000);

declare

numero number:=0;

resultado number;

begin

while numero<=S loop

resultado:=3*numero;

dbms_output.put_line('3*' 1 lto_char(numero)I 1 ' = ' 1 lto_char(resultado));

numero:=numero+l;

end loop;

end;

La c o n d i c i ó n establece q u e se m u l t i p l i q u e la v a r i a b l e " n u m e r o " por 3 m i e n t r a s

" n u m e r o " sea m e n o r o i g u a l a 5 . E n el b l o q u e d e s e n t e n c i a s se a l m a c e n a e n

" r e s u l t a d o " l a m u l t i p l i c a c i ó n , l u e g o se e s c r i b e tal v a l o r y f i n a l m e n t e se i n c r e m e n t a l a

v a r i a b l e " n u m e r o " en 1 .

H a c e m o s el s e g u i m i e n t o : c u a n d o se i n i c i a el b u c l e , l a v a r i a b l e " n u m e r o " t i e n e el v a l o r

O , se ejecuta l a p r i m e r l i n e a de s e n t e n c i a s y " r e s u l t a d o " a l m a c e n a el v a l o r O , se

i m p r i m e ( O ) y se i n c r e m e n t a l a v a r i a b l e " n u m e r o " , ahora c o n t i e n e el v a l o r 1 ; se v u e l v e


a l a c o n d i c i ó n , como l a c o n d i c i ó n es verdadera ( 1 es m e n o r q u e 5 ) , se v u e l v e n a

ejecutar l a s s e n t e n c i a s ( r e s u l t a d o a l m a c e n a 3 , se i m p r i m e ( 3 ) , se g u a r d a en n u m e r o

el v a l o r 2 ) , se v u e l v e a e v a l u a r l a c o n d i c i ó n , como resulta cierta (2 es m e n o r q u e 5 ) ,

se v u e l v e n a ejecutar l a s s e n t e n c i a s ( r e s u l t a d o a l m a c e n a 6 , se i m p r i m e , se g u a r d a

en n u m e r o el v a l o r 3 ) , se v u e l v e a e v a l u a r la c o n d i c i ó n , como resulta cierta (3 es

m e n o r q u e 5 ) , se v u e l v e n a ejecutar l a s s e n t e n c i a s ( r e s u l t a d o a l m a c e n a 9 , se

i m p r i m e , se g u a r d a en n u m e r o e l v a l o r 4 ) , se v u e l v e a e v a l u a r l a c o n d i c i ó n , como

resulta c i e rt a (4 es m e n o r q u e 5 ) , se v u e l v e n a ejecutar l a s s e n t e n c i a s (resultado

a l m a c e n a 1 2 , se i m p r i m e , se g u a r d a en n u m e r o el v a l o r 5 ) , se vuelve a e v a l u a r l a

c o n d i c i ó n , como resulta cierta (5 es m e n o r o i g u a l a 5 ) , se v u e l v e n a ejecutar l a s

s e n t e n c i a s ( r e s u l t a d o a l m a c e n a 1 5 , se i m p r i m e , se g u a r d a en n u m e r o el v a l o r 6 ) , se

v u e l v e a e v a l u a r l a c o n d i c i ó n , como resulta falsa (6 N O es m e n o r n i i g u a l a 5 ) , se

s a l e d e l a estructura.
1 0 3 - Disparador (trigger)

U n "trigger" ( d i s p a r a d o r o d e s e n c a d e n a d o r ) es u n b l o q u e de código q u e se ejecuta

automáticamente c u a n d o ocurre a l g ú n evento (como i n s e r c i ó n , a c t u a l i z a c i ó n o borrado)

sobre u n a d e t e r m i n a d a tabla (o vista) ; es decir, c u a n d o se intenta modificar los datos de

u n a t a b l a (o vista) a s o c i a d a al d i s p a r a d o r .

Se crean para conservar l a i n t e g r i d a d referencial y l a c o h e r e n c i a entre los datos entre

d i s t i n t a s t a b l a s ; para registrar l o s c a m b i o s q u e se efectúan sobre las tablas y la

i d e n t i d a d de q u i e n los realizó; para r e a l i z a r c u a l q u i e r acción c u a n d o u n a t a b l a es

m o d i f i c a d a ; etc.

S i se i n t e n t a m o d i f i c a r (agregar, a c t u a l i z a r o e l i m i n a r ) datos de u n a t a b l a a s o c i a d a a u n

d i s p a r a d o r , el d i s p a r a d o r se ejecuta (se d i s p a r a ) en forma a u t o m á t i c a .

La d i f e r e n c i a con los p r o c e d i m i e n t o s a l m a c e n a d o s d e l s i s te m a es q u e los triggers:

- no p u e d e n ser invocados directamente; a l i n t e n t a r m o d i f i c a r los datos d e u n a t a b l a

asociada a u n d i s p a r a d o r , el d i s p a r a d o r se ejecuta a u t o m á t i c a m e n t e .

- no reciben y retornan parámetros.

- son a p r o p i a d o s para m a n t e n e r la i n t e g r i d a d de los datos, no para o b t e n e r resultados

de c o n s u l t a s .

S i n t a x i s g e n e r a l para crear u n d i s p a r a d o r :

create or replace trigger NOMBREDISPARADOR

MOMENTO-- befare, after o instead of

EVENTO-- insert, update o delete

of CAMPOS-- solo para update

on NOMBRETABLA

NIVEL--puede ser a nivel de sentencia (statement) o de fila (far each row)

when CONDICION--opcional

begin

CUERPO DEL DISPARADOR--sentencias

end NOMBREDISPARADOR;

Los triggers se crean con la i n s t r u c c i ó n "create trigger" s e g u i d o d e l n o m b r e d e l

d i s p a r a d o r . S i se agrega "or replace" al m o m e n t o de crearlo y ya existe u n t r i g g e r con el

m i s m o n o m b r e , tal d i s p a r a d o r será borrado y vuelto a crear.

" M O M E N T O " i n d i c a c u a n d o se d i s p a r a r á el t r i g g e r en relación al evento, p u e d e ser

B E F O R E ( a n t e s ) , A F T E R ( d e s p u é s ) o I N S T E A D O F (en l u g a r d e ) . "before" s i g n i f i c a q u e

el d i s p a r a d o r se activará antes q u e se ejecute la o p e r a c i ó n ( i n s e rt , update o d e l e t e )

sobre l a t a b l a , q u e c a u s ó el d i s p a r o d e l m i s m o . "after" s i g n i f i c a q u e el tr i g ge r se activará

d e s p u é s q u e se ejecute la o p e r a c i ó n q u e c a u s ó el d i s p a r o . " i n s t e a d of' s ó l o p u e d e

d e f i n i r s e sobre vistas, a n u l a l a s e n t e n c i a d i s p a r a d o r a , se ejecuta en l u g a r de tal

s e n t e n c i a ( n i antes n i d e s p u é s ) .
" E V E N T O " especifica la operación ( a c c i ó n , t i p o de m o d i f i c a c i ó n ) q u e causa q u e el t r i g g e r

se d i s p a r e (se active), p u e d e ser " i n s e rt " , " u p d a t e " o " d e l e t e " ; D E B E colocarse a l m e n o s

u n a a c c i ó n , p u e d e ser m á s de u n a , en tal caso se separan con "or". S i " u p d a t e " l l e v a

u n a l i s t a de atributos, el t r i g g e r s ó l o se ejecuta si se a c t u a l i z a a l g ú n atributo d e l a l i s t a .

"on N O M B R E T A B L A " i n d i c a la tabla (o vista) a s o c i a d a al d i s p a r a d o r ;

" N I V E L " p u e d e ser a n i v e l d e s e n t e n c i a o de f i l a . "far each row" i n d i c a q u e el t r i g g e r es a

n i v e l de f i l a , es decir, se activa u n a vez por cada registro afectado por l a o p e r a c i ó n sobre

la t a b l a , c u a n d o u n a s o l a o p e r a c i ó n afecta a varios registros. Los triggers a n i v e l de

s e n t e n c i a , se activan u n a s o l a vez (antes o d e s p u é s de ejecutar l a o p e r a c i ó n sobre l a

t a b l a ) . S i no se especifica, o se especifica "statement", es a n i v e l d e s e n t e n c i a .

" C U E R P O D E L D I S P A R A D O R " son l a s acciones q u e se ejecutan al dispararse el trigger,

l a s c o n d i c i o n e s q u e d e t e r m i n a n c u a n d o u n i n t e n t o de i n s e r c i ó n , a c t u a l i z a c i ó n o borrado

provoca las a c c i o n e s q u e el t r i g g e r r e a l i z a r á . El b l o q u e se d e l i m i t a con " b e g i n . . . e n d " .

E n t o n c e s , u n d i s p a r a d o r es u n b l o q u e de c ó d i g o asociado a u n a t a b l a q u e se d i s p a r a

automáticamente antes o d e s p u é s d e u n a s e n t e n c i a " i n s e rt " , " u p d a t e " o "delete" sobre l a

tabla.

Se crean con la i n s t r u c c i ó n "create trigger" e s p e c i f i c a n d o el momento en q u e se

d i s p a r a r á , q u é evento lo d e s e n c a d e n a r á ( i n s e r c i ó n , a c t u a l i z a c i ó n o b o r r a d o ) , sobre q u é

t a b l a (o vista) y l a s i n s t r u c c i o n e s q u e se ejecutarán.

Los d i s p a r a d o r e s p u e d e n clasificarse s e g ú n tres parámetros:

- el m om ent o e n q u e se d i s p a r a : si se ejecutan antes (befare) o d e s p u é s (after) de la

sentencia.

- el evento q u e l o s d i s p a r a : i n s e rt , u p d a t e o d e l e t e , s e g ú n se ejecute u n a de estas

s e n t e n c i a s sobre l a t a b l a .

- n i v e l : d e p e n d i e n d o si se ejecuta para cada fi l a afectada en la s e n t e n c i a ( p o r cada f i l a ) o

b i e n u n a ú n i c a vez por s e n t e n c i a i n d e p e n d i e n t e m e n t e de la f i l a s afectadas ( n i v e l de

sentencia).

Consideraciones generales:

- Las s i g u i e n t e s i n s t r u c c i o n e s no están p e r m i t i d a s en u n d e s e n c a d e n a d o r : create

d a t a b a s e , alter d a t a b a s e , d r o p d a t a b a s e , load d a t a b a s e , restare d a t a b a s e , load l a g ,

reconfigure, restare l a g , d i s k i n i t , d i s k resize.

- Se p u e d e n crear varios triggers para cada evento, es decir, para cada ti po d e

modificación ( i n s e r c i ó n , a c t u a l i z a c i ó n o borrado) para u n a m i s m a t a b l a . Por e j e m p l o , se

p u e d e crear u n " i n s e rt trigger" para u n a t a b l a q u e ya t i e n e otro " i n s e rt t r i g g e r " .

A c o n t i n u a c i ó n veremos l a creación d e disparadores para los d i s t i n t o s sucesos

( i n s e r c i ó n , borrado, a c t u a l i z a c i ó n ) y todas l a s c l á u s u l a s a d i c i o n a l e s .
1 0 4 - Disparador ( i n f o r m a c i ó n )

Los triggers son objetos, a s í q u e para obtener información de e l l o s p u e d e n consultarse los s i g u i e n t e s

diccionarios:

- "user_objects": nos muestra todos los objetos d e la base de datos s e l e c c i o n a d a , i n c l u i d o s los triggers.

E n l a c o l u m n a "object_type" aparece "trigger" s i es u n disparador. En el s i g u i e n t e ejemplo solicitamos

todos los objetos q u e son d i s p a r a d o r e s :

select *from user_objects where object_type='TRIGGER';

- "user_triggers": nos muestra todos los triggers de l a base d e datos a c t u a l . Muestra el nombre d e l

d e s e n c a d e n a d o r (trigger_name), si es befare o after y si es a nivel d e sentencia o por fila (trigger_type),

el evento q u e lo d e s e n c a d e n a (triggering_event), a q u é objeto está asociado, si tabla o vista

(base_object_type), el nombre de la t a b l a al q u e está asociado (table_name), los c a m p o s , si hay

referencias, el estado, l a d e s c r i p c i ó n , el cuerpo (trigger_body), etc. E n el s i g u i e n t e ejemplo s o l i c i t a m o s

información de todos los disparadores q u e comienzan con " T R " :

select trigger_name, triggering_event from user_triggers where trigger_name like 'TR%'�

- "user_source": se puede v i s u a l i z a r el código fuente a l m a c e n a d o en u n d i s p a r a d o r c o n s u l t a n d o este

d i c c i o n a r i o : E n el s i g u i e n t e e j e m p l o solicitamos el código fuente d e l objeto "TR_insertar_libros":

select *from user_source where name='TR_INSERTAR_LIBROS';


1 0 5 - Dis p a rado r de i n s e r c i ó n a n i v e l de

sentencia

D i j i m o s q u e u n d i s p a r a d o r está a s o c i a d o a u n a t a b l a y a u n a operación específica

( i n s e r c i ó n , actualización o borrado).

A c o n t i n u a c i ó n veremos l a creación de u n d i s p a r a d o r para el evento de i n s e r c i ó n :

" i n s e rt t r i g e r " .

La s i g u i e n t e es l a s i n t a x i s para crear u n t r i g g e r de i n s e r c i ó n q u e se d i s p a r e cada vez

q u e se ejecute u n a s e n t e n c i a " i n s e rt " sobre l a t a b l a e s p e c i f i c a d a , es decir, cada vez

q u e se i n t e n t e n i n g r e s a r datos en l a t a b l a :

create or replace trigger NOMBREDISPARADOR

MOMENTO insert

on NOMBRETABLA

begin

CUERPO DEL TRIGGER;

end NOMBREDISPARADOR;

Analizamos la sintaxis:

L u e g o de l a i n s t r u c c i ó n "create trigger" se coloca el n o m b r e d e l d i s p a r a d o r . S i se

agrega " o r r e p l a c e " al m o m e n t o d e crearlo y ya existe u n t r i g g e r con el m i s m o

n o m b r e , t a l d i s p a r a d o r será borrado y v u e l t o a crear.

" M O M E N T O " i n d i c a c u a n d o se d i s p a r a r á el t r i g g e r en r e l a c i ó n al evento, p u e d e se

B E F O R E (antes) o A F T E R ( d e s p u é s ) . Se especifica el evento q u e causa q u e el

t r i g g e r se d i s p a r e , en este caso " i n s e rt " , ya q u e el t r i g g e r se activará cada vez q u e se

ejecute l a s e n t e n c i a " i n s e rt " sobre l a t a b l a especificada l u e g o d e " o n " .

Es u n t r i g g e r a n i v e l d e s e n t e n c i a , es decir, se d i s p a r a u n a s o l a vez por cada

s e n t e n c i a " i n s e rt " , a u n q u e l a s e n t e n c i a i n g r e s e varios registros. Es el v a l o r por

defecto si no se especifica.

F i n a l m e n t e se coloca el cuerpo d e l t r i g g e r dentro d e l b l o q u e " b e g i n . . e n d " .

Las s i g u i e n t e s s e n t e n c i a s d i s p a r a n u n t r i g g e r de i n s e r c i ó n :

.
insert into TABLA values . . . ,

insert into TABLA select . . . f rom . . . ;

E j e m p l o : Creamos u n d e s e n c a d e n a d o r q u e se d i s p a r a cada vez q u e se ejecuta u n

" i n s e rt " sobre la t a b l a " l i b r o s " :

create or replace trigger tr_ingresar_libros

befare insert

on libros
begin

insert into Control values(user,sysdate);

end tr_ingresar_libros;

A n a l i z a m o s el t r i g g e r anterior:

"create or replace trigger" j u n t o al n o m b r e d e l d i s p a r a d o r q u e t i e n e u n prefijo "tr" para

reconocer q u e es u n trigger, referencia el evento q u e lo d i s p a r a r á y l a t a b l a a s o c i a d a .

Para i d e n t i f i c a r f á c i l m e n t e l o s d i s p a r a d o r e s d e otros objetos se r e c o m i e n d a u s a r u n

prefijo y d a r l e s el n o m b r e d e l a t a b l a para la c u a l se crean j u n t o al tipo de a c c i ó n .

E l d i s p a r a d o r se activará antes ("befare") d e l evento " i n s e rt " sobre l a t a b l a " l i b r o s " , es

decir, se d i s p a r a r á A N T E S q u e se r e a l i c e u n a i n s e r c i ó n en " l i b r o s " . E l t r i g g e r está

d e f i n i d o a n i v e l d e s e n t e n c i a , se activa u n a vez por cada i n s t r u c c i ó n " i n s e rt " sobre

" l i b r o s " . El cuerpo d e l d i s p a r a d o r se d e l i m i t a con " b e g i n . . . e n d " , a l l í se especifican l a s

acciones q u e se realizarán a l o c u r r i r el evento de i n s e r c i ó n , en este caso, i n g r e s a r e n

l a t a b l a " c o n t r o l " el n o m b r e d e l u s u a r i o q u e alteró l a t a b l a " l i b r o s " ( o b t e n i d a m e d i a n t e

l a f u n c i ó n " u s e r " ) y l a fecha en q u e l o hizo ( m e d i a n t e l a f u n c i ó n " s y s d a t e " ) .


1 0 6 - Disparador de i n s e r c i o n a nivel de fila (insert

trigger for each row)

V i m o s l a creación de u n d i s p a r a d o r para el evento de i n s e r c i ó n a nivel d e s e n t e n c i a , es

decir, se d i s p a r a u n a vez por cada s e n t e n c i a " i n s e rt " sobre la tabla a s o c i a d a .

E n caso q u e u n a s o l a s e n t e n c i a " i n s e rt " i n g r e s e varios registros en la tabla a s o c i a d a , el

trigger se disparará u n a sola vez; si q u e r e m o s q u e se active u n a vez por cada registro

afectado, d e b e m o s i n d i c a r l o con "for each row".

La s i g u i e n t e es la s i n t a x i s para crear u n t r i g g e r de i n s e r c i ó n a n i v e l de f i l a , se d i s p a r e u n a

vez por cada f i l a i n g r e s a d a sobre la tabla e s p e c i f i c a d a :

create or replace trigger NOMBREDISPARADOR

MOMENTO insert

on NOMBRETABLA

far each row

be g i n

CUERPO DEL TRIGGER;

end NOMBREDISPARADOR;

C r e a m o s u n d e s e n c a d e n a d o r q u e se d i s p a r a u n a vez por cada registro i n g r e s a d o en la

tabla "ofertas":

create or replace trigger tr_ingresar_ofertas

befare insert

on ofertas

far each row

begin

insert into Control values(user,sysdate);

end tr_ingresar_ofertas;

S i al ejecutar u n " i n s e rt " sobre "ofertas" e m p l e a m o s la s i g u i e n t e s e n t e n c i a :

insert into ofertas select titulo,autor,precio from libros where precio<30;

y se i n g r e s a n 5 registros en "ofertas", en la t a b l a "control" se i n g r e s a r á n 5 registros, u n o

por cada i n s e r c i ó n en "ofertas". Si el t r i g g e r h u b i e s e s i d o d e f i n i d o a n i v e l de s e n t e n c i a

(statement), se agregaría u n a s o l a fila en " c o n t r o l " .


1 0 7 - D i s p a r a d o r de borrado ( n i v e l de

s e n t e n c i a y de fila)

D i j i m o s q u e u n d i s p a r a d o r está a s o c i a d o a u n a t a b l a y a u n a operación específica

( i n s e r c i ó n , actualización o borrado).

A c o n t i n u a c i ó n veremos l a creación de u n d i s p a r a d o r para el evento de borrado:

"delate triger".

La s i g u i e n t e es l a s i n t a x i s para crear u n t r i g g e r de e l i m i n a c i ó n q u e se d i s p a r e cada

vez q u e se ejecute u n a sentencia " d e l a t e " sobre l a t a b l a e s p e c i f i c a d a , es d e c i r , cada

vez q u e se e l i m i n e n registros de l a t a b l a :

create or replace trigger NOMBREDISPARADOR

MOMENTO delete

on NOMBRETABLA

NIVEL-- statement o for each row

begin

CUERPO DEL TRIGGER;

end NOMBREDISPARADOR;

L u e g o de l a i n s t r u c c i ó n "create trigger" o "create or replace trigger" se coloca el

nombre del disparador.

" M O M E N T O " i n d i c a c u a n d o se d i s p a r a r á el t r i g g e r en r e l a c i ó n al evento, p u e d e se

B E F O R E ( a n t e s ) o A F T E R ( d e s p u é s ) . Se especifica el evento q u e c a u s a q u e el

t r i g g e r se d i s p a r e , en este caso " d e l a t e " , ya q u e el t r i g g e r se activará c a d a vez q u e

se ejecute l a s e n t e n c i a " d e l a t e " sobre l a t a b l a especificada l u e g o de " o n " .

E n " N I V E L " se especifica s i será u n t r i g g e r a n i v e l d e s e n t e n c i a (se d i s p a r a u n a s o l a

vez por c a d a s e n t e n c i a " d e l a t e " , a u n q u e l a s e n t e n c i a e l i m i n e varios registros) o a

n i v e l d e f i l a (se d i s p a r a tantas veces como f i l a s se e l i m i n a n en l a s e n t e n c i a " d e l a t e " ) .

F i n a l m e n t e se coloca el cuerpo d e l t i g g e r dentro d e l b l o q u e " b e g i n . . e n d " .

C r e a m o s u n d e s e n c a d e n a d o r a n i v e l d e fila q u e se d i s p a r a cada vez q u e se ejecuta

u n " d e l a t e " sobre l a t a b l a " l i b r o s " , en el cuerpo d e l t r i g g e r se especifican l a s a c c i o n e s ,

en este c a s o , por cada f i l a e l i m i n a d a d e l a t a b l a " l i b r o s " , se i n g r e s a u n registro e n

"control" con el n o m b r e d e l u s u a r i o q u e realizó l a e l i m i n a c i ó n y l a fecha:

create or replace trigger tr_borrar_libros

befare delete

on libros

for each row

be g i n

insert into Control values(user,sysdate);

end tr_borrar_libros;
1 0 8 - Disparador de a c t u a l i z a c i o n a n i v e l de

s e n t e n c i a (update trigger)

D i j i m o s q u e u n d i s p a r a d o r está a s o c i a d o a u n a t a b l a y a u n a operación específica

( i n s e r c i ó n , actualización o borrado).

A c o n t i n u a c i ó n veremos l a creación de u n d i s p a r a d o r para el evento de a c t u a l i z a c i ó n :

"update triger".

La s i g u i e n t e es l a s i n t a x i s para crear u n t r i g g e r de a c t u a l i z a c i ó n a n i v e l de s e n t e n c i a ,

q u e se d i s p a r e cada vez q u e se ejecute u n a s e n t e n c i a " u p d a t e " sobre l a t a b l a

e s p e c i f i c a d a , es decir, cada vez q u e se intenten m o d i f i c a r datos en l a t a b l a :

create or replace trigger NOMBREDISPARADOR

MOMENTO update

on NOMBRETABLA

statement

begin

CUERPO DEL TRIGGER;

end NOMBREDISPARADOR;

L u e g o de l a i n s t r u c c i ó n "create trigger" se coloca el n o m b r e d e l d i s p a r a d o r . S i

a g r e g a m o s "or replace" al m o m e n t o d e crearlo y ya existe u n t r i g g e r con el m i s m o

n o m b r e , t a l d i s p a r a d o r será borrado y v u e l t o a crear.

" M O M E N T O " i n d i c a c u a n d o se d i s p a r a r á el t r i g g e r en r e l a c i ó n al evento, p u e d e ser

B E F O R E ( a n t e s ) o A F T E R ( d e s p u é s ) . Se especifica el evento q u e causa q u e el

t r i g g e r se d i s p a r e , en este caso " u p d a t e " , ya q u e el t r i g g e r se activará cada vez q u e

se ejecute l a s e n t e n c i a " u p d a t e " sobre l a t a b l a especificada l u e g o de " o n " .

"statement" s i g n i f i c a q u e es u n t r i g g e r a n i v e l de s e n t e n c i a , es d e c i r , se d i s p a r a u n a

s o l a vez por cada s e n t e n c i a " u p d a t e " , a u n q u e l a s e n t e n c i a m o d i f i q u e varios registros;

como en c u a l q u i e r trigger, es el v a l o r por defecto s i no se especifica.

F i n a l m e n t e se coloca el cuerpo d e l t i g g e r dentro d e l b l o q u e " b e g i n . . e n d " .

Las s i g u i e n t e s s e n t e n c i a s d i s p a r a n u n t r i g g e r de i n s e r c i ó n :

update TABLA set CAMPO=NUEVOVALOR;

update TABLA set CAMPO=NUEVOVALOR where CONDICION;

E j e m p l o : Creamos u n d e s e n c a d e n a d o r q u e se d i s p a r a cada vez q u e se ejecuta u n

" u p d a t e " sobre l a t a b l a " l i b r o s " :

create or replace trigger tr_actualizar_libros

befare update

on libros
begin

insert into control values(user,sysdate);

end tr_actualizar_libros;

Al o c u r r i r e l evento d e a c t u a l i z a c i ó n sobre " l i b r o s " , se i n g r e s a en l a t a b l a "control" el

n o m b r e d e l u s u a r i o q u e alteró l a t a b l a " l i b r o s " ( o b t e n i d a m e d i a n t e l a f u n c i ó n " u s e r " ) y

l a fecha e n q u e l o hizo ( m e d i a n t e l a f u n c i ó n "sysdate").


1 0 9 - Disparador de a c t u a l i z a c i ó n a n i v e l de

fila ( u p d a t e trigger)

V i m o s la creación de u n d i s p a r a d o r para e l evento d e a c t u a l i z a c i ó n a n i v e l d e

s e n t e n c i a , es decir, se d i s p a r a u n a vez por cada s e n t e n c i a " u p d a t e " sobre l a t a b l a

asociada.

E n caso q u e u n a sola s e n t e n c i a " u p d a t e " m o d i f i q u e varios registros en l a t a b l a

a s o c i a d a , el t r i g g e r se d i s p a r a r á u n a s o l a vez; si q u e r e m o s q u e se active u n a vez por

cada registro afectado, d e b e m o s i n d i c a r l o con "far each row".

La s i g u i e n t e es l a sintaxis para crear u n t r i g g e r de a c t u a l i z a c i ó n a n i v e l de f i l a , se

d i s p a r e u n a vez por cada fila m o d i f i c a d a sobre la t a b l a e s p e c i f i c a d a :

create or replace trigger NOMBREDISPARADOR

MOMENTO update

on NOMBRETABLA

far each row

begin

CUERPO DEL TRIGGER;

end NOMBREDISPARADOR;

C r e a m o s u n d e s e n c a d e n a d o r a n i v e l de f i l a , q u e se d i s p a r a u n a vez p o r cada fila

afectada por u n " u p d a t e " sobre l a t a b l a " l i b r o s " . Se i n g r e s a e n la t a b l a "control" el

n o m b r e d e l u s u a r i o q u e altera l a t a b l a " l i b r o s " ( o b t e n i d a m e d i a n t e l a f u n c i ó n " u s e r " ) y

l a fecha e n q u e l o hizo ( m e d i a n t e l a f u n c i ó n "sysdate"):

create or replace trigger tr_actualizar_libros

befare update

on libros

far each row

be g i n

insert into control values(user,sysdate);

end tr_actualizar_libros;

S i a l ejecutar u n " u p d a t e " sobre " l i b r o s " se a c t u a l i z a n 5 registros, e n la t a b l a "control"

se i n g r e s a r á n 5 registros, u n o por cada m o d i f i c a c i ó n . Si el t r i g g e r h u b i e s e s i d o

d e f i n i d o a n i v e l d e s e n t e n c i a (statement), se a g r e g a r í a u n a s o l a fila en " c o n t r o l " .


1 1 O - D i s p a r a d o r de a c t u a l i z a c i ó n - lista de

c a m p o s ( u p d a t e trigger)

E l t r i g g e r d e a c t u a l i z a c i ó n (a n i v e l de s e n t e n c i a o de f i l a ) permite i n c l u i r u n a lista de

c a m p o s . S i se i n c l u y e el n o m b r e d e u n c a m p o ( o v a r i o s ) l u e g o de " u p d a t e " , e l t r i g g e r

se d i s p a r a r á ú n i c a m e n t e c u a n d o a l g u n o de esos c a m p o s ( i n c l u i d o s en la l i s t a ) es

a c t u a l i z a d o . S i se o m i t e l a lista de c a m p o s , el t r i g g e r se d i s p a r a c u a n d o c u a l q u i e r

c a m p o de l a t a b l a a s o c i a d a es m o d i f i c a d o , es decir, por defecto toma todos los

c a m p o s de l a t a b l a .

La l i s t a de c a m p o s s o l a m e n t e p u e d e especificarse en d i s p a r a d o r e s de a c t u a l i z a c i ó n ,

n u n c a en d i s p a r a d o r e s de i n s e r c i ó n o borrado.

Sintaxis general:

create or replace trigger NOMBREDISPARADOR

MOMENTO update of CAMPOS

on TABLA

NIVEL--statement o for each row

begin

CUERPODEL DISPARADOR;

end NOMBREDISPARADOR;

" C A M P O S " son los c a m p o s d e l a t a b l a a s o c i a d a q u e activarán el t r i g g e r si son

m o d i f i c a d o s . P u e d e n i n c l u i r s e m á s de u n o , en tal c a s o , se s e p a r a n con c o m a s .

C r e a m o s u n d e s e n c a d e n a d o r a n i v e l d e fila q u e se d i s p a r a cada vez q u e se a c t u a l i z a

el c a m p o " p r e c i o " de l a t a b l a " l i b r o s " :

create or replace trigger tr_actualizar_precio_libros

befare update of precio

on libros

for each row

be g i n

insert into control values(user,sysdate);

end tr_actualizar_precio_libros;

S i r e a l i z a m o s u n " u p d a t e " sobre el c a m p o "precio" de " l i b r o s " , el t r i g g e r se d i s p a r a .

Pero si r e a l i z a m o s u n " u p d a t e " sobre c u a l q u i e r otro c a m p o , e l t r i g g e r no se d i s p a r a ,

ya q u e está d e f i n i d o s o l a m e n t e para el c a m p o " p r e c i o " .


1 1 1 - Disparador de m ú l t i p l e s eventos

Hasta el m om e nto h e m o s a p r e n d i d o a crear u n d i s p a r a d o r (trigger) asociado a u n a ú n i c a

operación ( i n s e r c i ó n , a c t u a l i z a c i ó n o b o r r a d o ) .

U n t r i g g e r p u e d e d e f i n i r s e sobre m á s de u n e ve nt o ; en tal caso se s e p a r a n con "or".

S i n t a x i s para crear u n d i s p a r a d o r para m ú l t i p l e s eventos:

create or replace trigger NOMBREDISPARADOR

MOMENTO-- befare, after o instead of

of CAMPO--si alguno de los eventos es update

EVENTOS-- insert, update y/o delete

on NOMBRETABLA

NIVEL--puede ser a nivel de sentencia (statement) o de fila (far each row)

be g i n

CUERPO DEL DISPARADOR--sentencias

end NOMBREDISPARADOR;

S i el t r i g ger se d e f i n e para más de u n evento d e s e n c a d e n a n t e , en el cuerpo d e l m i s m o

se p u e d e e m p l e a r u n c o n d i c i o n a l para controlar cu á l o p e r a c i ó n d i s p a r ó el trigger. Esto

permite ejecutar b l o q u e s de c ó d i g o s e g ú n la clase de a c c i ó n q u e d i s p a r ó el

desencadenador.

Para i d e n t i f i c a r el t i p o de o p e r a c i ó n q u e d i s p a r ó el t r i g g e r e m p l e a m o s " i n s e rt i n g " ,

"updating" y "deleting".

Veamos u n e j e m p l o . El s i g u i e n t e trigg e r está d e f i n i d o a n i v e l de s e n t e n c i a , para los

eventos " i n s e rt " , " u p d a t e " y " d e l e t e " ; c u a n d o se modifican los datos d e " l i b r o s " , se

a l m a c e n a en la t a b l a "control" el n o m b r e d e l u s u a r i o , l a fecha y el t i p o de modificación

q u e alteró l a t a b l a :

- si se realizó u n a i n s e r c i ó n , se a l m a c e n a " i n s e r c i ó n " ;

- si se realizó u n a a c t u a l i z a c i ó n ( upda te ) , se a l m a c e n a " a c t u a l i z a c i ó n " y

- si se realizó u n a e l i m i n a c i ó n ( d e l e t e ) se a l m a c e n a " b o r r a d o " .

create or replace trigger tr_cambios_libros

befare insert or update or delete

on libros

far each row

begin

if inserting then

insert into control values (user, sysdate, ' i n s e r c i ó n ' ) ;

end if;

if updating then

insert into control values (user, sysdate, ' a c t u a l i z a c i ó n ' ) ;

end if;
if deleting then

insert into control values (user, sysdate, ' b o r r a d o ' ) ;

end if;

end tr_cambios_libros;

S i ejecutamos u n " i n s e rt " sobre " l i b r o s " , el d i s p a r a d o r se activa e n t r a n d o por el p r i m e r

" i f ' ; si ejecutamos u n " u p d a t e " el t r i g g e r se d i s p a r a e n t r a n d o por el s e g u n d o " i f ' ; si

ejecutamos u n "delete" el d e s e n c a d e n a d o r se d i s p a r a e n t r a n d o por el tercer " i f ' .

Las s i g u i e n t e s s e n t e n c i a s d i s p a r a n el trigger creado a n t e r i o r m e n t e :

.
insert into TABLA values . . . ,

insert into TABLA select . . . f rom . . . ;

update TABLA set ;

delete from TABLA ;


1 1 2 - Disparador ( o l d y new)

C u a n d o trabajamos con t r i g g e r a n i v e l de f i l a , Oracle provee de dos t a b l a s t e m p o r a l e s a l a s

c u a l e s se p u e d e acceder, q u e c o n t i e n e n l o s a n t i g u o s y nuevos valores de los campos d e l

registro afectado por l a s e n t e n c i a q u e d i s p a r ó el trigger. El n u e v o v a l o r es " : n e w " y el viejo

v a l o r es " : o l d " . Para referirnos a e l l o s d e b e m o s especificar su c a m p o separado por u n p u n t o

":new.CAMPO" y ":old.CAMPO".

E l acceso a estos c a m p o s d e p e n d e d e l evento d e l d i s p a r a d o r .

E n u n t r i g g e r d i s p a r a d o por u n " i n s e rt " , se p u e d e acceder al c a m p o " : n e w " u n i c a m e n t e , el

campo " : o l d " contiene " n u l l " .

E n u n a inserción se p u e d e e m p l e a r " : n e w " para e s c r i b i r nuevos valores en l a s c o l u m n a s de

la tabla.

E n u n t r i g g e r q u e se d i s p a r a con " u p d a t e " , se p u e d e acceder a a m b o s c a m p o s . En u n a

a c t u a l i z a c i o n , se p u e d e n comparar los valores de " : n e w " y " : o l d " .

E n u n t r i g g e r de borrado, u n i c a m e n t e se p u e d e acceder a l campo " o l d " , ya q u e el campo

" : n e w " no existe l u e g o q u e el registro es e l i m i n a d o , e l c a m p o " : n e w " c o n t i e n e " n u l l " y no

p u e d e ser m o d i f i c a d o .

Los valores de " o l d " y "new" están d i s p o n i b l e s en triggers after y before.

E l v a l o r d e " : n e w " p u e d e modificarse en u n t r i g g e r before, es decir, se p u e d e acceder a los

nuevos valores antes q u e se i n g r e s e n en l a t a b l a y c a m b i a r los valores a s i g n a n d o a

" : n e w . C A M P O " otro valor.

E l v a l o r de " : n e w " N O p u e d e modificarse en u n trigg er after, esto es p o r q u e el t r i g g e r se

activa l u e g o q u e los va lo res de "new" se a l m a c e n a r o n en l a t a b l a .

E l campo " : o l d " n u n c a se m o d i f i c a , s ó l o p u e d e l e e r s e .

P u e d e n usarse en u n a c l á s u l a " w h e n " ( q u e veremos p o s t e r i o r m e n t e ) .

E n e l cuerpo el trigger, los c a m p o s " o l d " y "new" d e b e n estar precedidos p o r " : " (dos p u n t o s ) ,

pero si está en " w h e n " n o .

Veamos u n e j e m p l o .

Creamos u n trigger a n i v e l de f i l a q u e se dispara "antes" q u e se ejecute u n " u p d a t e " sobre e l

c a m p o "precio" de la t a b l a " l i b r o s " . En e l cuerpo d e l d i s p a r a d o r se d e b e i n g r e s a r en la t a b l a

" c o n t r o l " , el n o m b r e del u s u a r i o q u e realizó la a c t u a l i z a c i ó n , l a fecha, el c ó d i g o d e l l i b r o q u e

ha s i d o modificado, el precio anterior y el n u e v o :

create or replace trigger tr_actualizar_precio_libros

befare update of precio

on libros

far each row

be g i n
insert into control values(user,sysdate,:new.codigo,:old.precio,:new.precio);

end tr_actualizar_precio_libros;

C u a n d o el t r i g g e r se d i s p a r e , antes de i n g r e s a r l o s valores a l a t a b l a , a l m a c e n a r á en

" c o n t r o l " , a d e m á s d e l n o m b r e d e l u s u a r i o y la fecha, el precio anterior d e l l i b r o y el nuevo

valor.

E l s i g u i e n t e trigger d e b e c o n t r o l a r e l precio q u e se está a c t u a l i z a n d o , si s u p e r a l o s 50 p e s o s ,

se d e b e r e d o n d e a r tal v a l o r a entero, hacia abajo ( e m p l e a n d o "floor"), es decir, se modifica el

v a l o r i n g r e s a d o a c c e d i e n d o a " : n e w . p r e c i o " a s i g n á n d o l e otro v a l o r :

create or replace trigger tr_actualizar_precio_libros

befare update of precio

on libros

far each row

be g i n

if (:new.precio>50) then

:new.precio:=floor(:new.precio);

end if;

insert into control values(user,sysdate,:new.codigo,:old.precio,:new.precio);

end tr_actualizar_precio_libros;

S i a l a c t u a l i z a r el precio de u n l i b r o colocamos u n v a l o r s u p e r i o r a 5 0 , con d e c i m a l e s , tal v a l o r

se redondea al entero más cercano h a c i a abajo. Por e j e m p l o , si el nuevo v a l o r es " 5 4 . 9 9 " , se

almacenará "54".

Podemos crear u n d i s p a r a d o r para m ú l t i p l e s eventos, q u e se d i s p a r e a l ejecutar " i n s e rt " ,

" u p d a t e " y " d e l e t e " sobre " l i b r o s " . En el cuerpo d e l trigger se r e a l i z a l a s i g u i e n t e a c c i ó n : se

a l m a c e n a el n o m b r e d e l u s u a r i o , l a fecha y los a n t i g u o s y viejos valores d e l c a m p o " p r e c i o " :

create or replace trigger tr_libros

befare insert or update or delete

on libros

far each row

be g i n

insert into control values(user,sysdate,:old.codigo,:old.precio,:new.precio);

end tr_libros;

S i i n g r e s a m o s u n registro, el campo " : o l d . c o d i g o " y el c a m p o " : o l d . p r e c i o " contendrán " n u l l " .

S i r e a l i z a m o s u n a a c t u a l i z a c i ó n d e l c a m p o de u n c a m p o q u e no sea " p r e c i o " , los campos

" : o l d . p r e c i o " y " : n e w . p r e c i o " g u a r d a r á n el m i s m o v a l o r .

S i e l i m i n a m o s u n registro, el c a m p o " : n e w . p r e c i o " contendrá " n u l l " .

Entonces, se p u e d e acceder a los valores de " : n e w " y " : o l d " en d i s p a r a d o r e s a n i v e l de f i l a

( n o en disparadores a n i v e l de s e n t e n c i a ) . Están d i s p o n i b l e s en triggers after y befare. Los

valores de " : o l d " s o l a m e n t e p u e d e n l e e r s e , n u n c a modificarse. Los valores de " : n e w " p u e d e n

modificarse ú n i c a m e n t e en triggers befare ( n u n c a en triggers after).


1 1 3 - Disparador condiciones (when)

E n los triggers a n i v e l d e f i l a , se p u e d e i n c l u i r u n a restricción a d i c i o n a l , a g r e g a n d o la

c l a u s u l a " w h e n " con u n a c o n d i c i ó n q u e se e v a l ú a para cada f i l a q u e afecte el

d i s p a r a d o r ; si resulta c i e rt a , se ejecutan l a s s e n t e n c i a s d e l t r i g g e r para ese registro;

si resulta f a l s a , el t r i g g e r no se d i s p a r a para ese registro.

Limitaciones de "when":

- no p u e d e c o n t e n e r s u b c o n s u l t a s , f u n c i o n e s a g r e g a d a s n i f u n c i o n e s d e f i n i d a s por el

usuario;

- s ó l o se p u e d e hacer referencia a l o s parámetros d e l evento;

- no se p u e d e especificar en l o s trigers " i n s t e a d of" n i e n t r i g g e r a n i v e l d e s e n t e n c i a .

Creamos el siguiente disparador:

create or replace trigger tr_precio_libros

before insert or update of precio

on libros

for each row when(new.precio>50)

begin

:new.precio : = round(:new.precio);

end tr_precio_libros;

E l d i s p a r a d o r a n t e r i o r se d i s p a r a A N T E S (befare) q u e se ejecute u n " i n s e rt " sobre

" l i b r o s " o u n " u p d a t e " sobre "precio" d e " l i b r o s " . Se ejecuta u n a vez por cada f i l a

afectada (far e a c h row) y s o l a m e n t e si c u m p l e con l a c o n d i c i ó n d e l " w h e n " , es d e c i r ,

si el nuevo precio q u e se i n g r e s a o modifica es s u p e r i o r a 5 0 . S i el precio es m e n o r o

i g u a l a 5 0 , el t r i g g e r no se d i s p a r a . S i el precio es mayor a 5 0 , se modifica el v a l o r

ingresado redondeándolo a entero.

Note q u e c u a n d o h a c e m o s referencia a "new" ( i g u a l m e n t e con " o l d " ) e n l a c o n d i c i ó n

" w h e n " , no se colocan l o s dos p u n t o s p r e c e d i é n d o l o ; pero en el cuerpo d e l t r i g g e r s i .

S i i n g r e s a m o s u n registro con el v a l o r 3 0 . 8 0 para " p r e c i o " , el t r i g g e r no se d i s p a r a .

S i i n g r e s a m o s u n registro con el v a l o r " 5 5 . 6 " para " p r e c i o " , el t r i g g e r se d i s p a r a

m o d i f i c a n d o tal v a l o r a " 5 6 " .

S i a c t u a l i z a m o s el precio d e u n l i b r o a " 4 0 . 3 0 " , el t r i g g e r no se activa.

S i a c t u a l i z a m o s el precio d e u n l i b r o a " 5 0 . 3 0 " , el t r i g g e r se activa y modifica e l v a l o r

a "50".

S i a c t u a l i z a m o s el precio d e 2 registros a valores q u e s u p e r e n l o s " 5 0 " , el t r i g g e r se

activa 2 veces r e d o n d e a n d o l o s valores a entero.


S i a c t u a l i z a m o s en u n a s o l a s e n t e n c i a el precio de 2 registros y s o l a m e n t e u n o de

e l l o s s u p e r a l o s " 5 0 " , e l t r i g g e r se activa 1 s o l a vez.

E l t r i g g e r anterior p o d r í a haberse creado de l a s i g u i e n t e m a n e r a :

create or replace trigger tr_precio_libros

befare insert or update of precio

on libros

for each row

begin

if :new.precio>50 then

:new.precio := round(:new.precio);

end if;

end tr_precio_libros;

E n este c a s o , l a c o n d i c i ó n se c h e q u e a en u n "if' dentro d e l c u e r p o d e l trigger. La

diferencia con el p r i m e r t r i g g e r q u e c o n t i e n e " w h e n " es q u e l a c o n d i c i ó n e s t a b l e c i d a

en el " w h e n " se testea antes q u e el t r i g g e r se d i s p a r e y si resulta v e r d a d e r a , se

d i s p a r a e l t r i g g e r , s i n o n o . E n c a m b i o , si l a c o n d i c i ó n está dentro d e l cuerpo d e l

d i s p a r a d o r , el t r i g g e r se d i s p a r a y l u e g o se controla el precio, s i c u m p l e la c o n d i c i ó n ,

se modifica el precio, s i n o n o .

Por e j e m p l o , l a s i g u i e n t e s e n t e n c i a :

update libros set precio=40 where . . . ;

no d i s p a r a el p r i m e r trigger, ya q u e no c u m p l e con l a c o n d i c i ó n d e l " w h e n " ; pero si

d i s p a r a e l s e g u n d o trigger, q u e no realiza n i n g u n a acción ya q u e al evaluarse l a

c o n d i c i ó n d e l " i f ' , resulta f a l s a .


1 1 4 - Disparador de a c t ua l i zac i on - campos ( u p d a t i n g )

E n u n t r i g g e r d e a c t u a l i z a c i ó n a n i v e l d e f i l a , se p u e d e especificar e l n o m b r e d e u n c a m p o e n l a

c o n d i c i ó n " u p d a t i n g " para d e t e r m i n a r c u á l campo ha s i d o a c t u a l i z a d o .

Sintaxis básica:

create or replace trigger NOMBRETRIGGER

MOMENTO update . . .

begin

if updating ('CAMPO') then

end if;

end NOMBREDISPARADOR;

E l s i g u i e n t e t r i g g e r se d i s p a r a c u a n d o se a c t u a l i z a l a t a b l a " l i b r o s " . Dentro d e l cuerpo d e l t r i g g e r

se a v e r i g u a el campo q u e ha s i d o m o d i f i c a d o ; en caso de modificarse e l "precio", se ingresa e n

l a t a b l a "controlPrecios" l a fecha, e l c ó d i g o d e l l i b r o y e l a n t i g u o y n u e v o precio; en caso d e

a c t u a l i z a r s e c u a l q u i e r otro c a m p o , se a l m a c e n a en l a t a b l a "control" e l n o m b r e d e l u s u a r i o q u e

realizó l a m o d i f i c a c i ó n , l a fecha y e l código d e l l i b r o m o d i f i c a d o .

create or replace trigger tr_actualizar_libros

befare update

on libros

for each row

be g i n

if updating ('precio') then

insert into controlprecios values(sysdate,:old.codigo,:old.precio,:new.precio);

else

insert into control values(user,sysdate,:old.codigo);

end if;

end tr_actualizar_libros;
1 1 5 - Disparadores ( h a b i l i t a r y d e s h a b i l i t a r )

U n d i s p a r a d o r p u e d e estar en d o s estados: h a b i l i t a d o ( e n a b l e d ) o d e s h a b i l i t a d o

(disabled).

C u a n d o se crea u n trigger, por defecto está h a b i l i t a d o .

Se p u e d e d e s h a b i l i t a r u n trigger para q u e no se ejecute. U n t r i g g e r d e s h a b i l i t a d o

s i g u e e x i s t i e n d o , pero a l ejecutar u n a i n s t r u c c i ó n q u e lo d i s p a r a , no se activa.

S i n t a x i s para d e s h a b i l i t a r u n t r i g g e r :

alter trigger NOMBREDISPARADOR disable;

E j e m p l o : D e s h a b i l i t a m o s el t r i g g e r "tr_ingresar_empleados":

alter trigger tr_ingresar_empleados disable;

S i n t a x i s para h a b i l i t a r u n trigger q u e está d e s h a b i l i t a d o :

alter trigger NOMBREDISPARADOR enable;

E j e m p l o : H a b i l i t a m o s el trigger " t r _ a c t u a l i z a r _ e m p l e a d o s " :

alter trigger tr_actualizar_empleados enable;

Se p u e d e n h a b i l i t a r o d e s h a b i l i t a r todos l o s t r i g g e r e s t a b l e c i d o s sobre u n a t a b l a

e s p e c i f i c a , se e m p l e a l a s i g u i e n t e s e n t e n c i a ;

alter table TABLA disable all triggers;--deshabilita

alter table TABLA enable all triggers;-- habilita

La s i g u i e n t e s e n t e n c i a d e s h a b i l i t a todos l o s triggers de la t a b l a " e m p l e a d o s " :

alter table empleados enable all triggers;

P o d e m o s s a b e r si u n t r i g g e r está o no h a b i l i t a d o c o s u l t a n d o el d i c c i o n a r i o

"user_triggers", e n l a c o l u m n a "status" aparece " e n a b l e d " si está h a b i l i t a d o y

" d i s a b l e d " si está d e s h a b i l i t a d o .


1 1 6 - Disparador ( e l i m i n a r )

Para e l i m i n a r u n t r i g g e r se e m p l e a l a s i g u i e n t e s e n t e n c i a :

drop trigger NOMBRETRIGGER;

Ejemplo:

drop trigger tr_insertar_libros;

S i e l i m i n a m o s u n a t a b l a , se e l i m i n a n todos l o s triggers e s t a b l e c i d o s sobre e l l a .


1 1 7 - Errores definidos por e l usuario

Oracle permite d e f i n i r a l o s u s u a r i o s errores e s p e c i f i c a n d o u n n ú m e r o d e error y u n mensaje

e m p l e a n d o el p r o c e d i m i e n t o "raise_application_error".

Sintaxis:

raise_application_error (NUMERO,TEXTO);

E l p r o c e d i m i e n t o "raise_application_error" permite e m i t i r u n mensaje de error. E l N U M E R O de

mensaje d e b e ser u n n ú m e r o negativo entre -20000 y -20999 y el mensaje de TEXTO u n a cadena

d e caracteres de hasta 2048 bytes.

S i d u r a n t e l a ejecución d e u n trigger se produce u n error d e f i n i d o por el u s u a r i o , se a n u l a n todas

l a s a c t u a l i z a c i o n e s r e a l i z a d a s por l a acción d e l t r i g g e r a s í como e l evento q u e l a activó, es decir, se

r e a n u d a c u a l q u i e r efecto retornando u n mensaje y se deshace l a orden ejecutada.

E n caso q u e se i n c l u y a en e l cuerpo de u n d i s p a r a d o r "after" ( q u e se ejecuta d e s p u é s d e l a

s e n t e n c i a , es d e c i r , c u a n d o los datos ya h a n s i d o a c t u a l i z a d o s ) , la sentencia será d e s h e c h a

( r o l l b a c k ) . S i es u n d i s p a r a d o r "befare" ( q u e se ejecuta antes d e l a s e n t e n c i a , o sea, c u a n d o los

datos a ú n no h a n s i d o a c t u a l i z a d o s ) , l a sentencia no se ejecuta.

Veamos u n e j e m p l o : Creamos u n t r i g g e r d e a c t u a l i z a c i ó n a n i v e l d e f i l a sobre l a t a b l a " l i b r o s " . Ante

c u a l q u i e r m o d i f i c a c i ó n d e los registros de " l i b r o s " , se d e b e i n g r e s a r e n l a t a b l a "control", e l n o m b r e

d e l u s u a r i o q u e realizó l a a c t u a l i z a c i ó n y l a fecha; pero, controlamos q u e N O se p e r m i t a modificar

el campo " c o d i g o " , e n caso d e suceder, l a acción no d e b e realizarse y d e b e mostrarse u n mensaje

d e error i n d i c á n d o l o :

create or replace trigger tr_actualizar_libros

befare update

on libros

for each row

be g i n

if updating('codigo') then

raise_application_error(-20001, ' N o se puede modificar el código de los libros');

else

insert into control values(user,sysdate);

end if;

end;

Si se a c t u a l i z a c u a l q u i e r c a m p o de " l i b r o s " , se d i s p a r a el t r i g g e r ; si se actualiza el c a m p o " c o d i g o " ,

aparece u n mensaje d e error y l a a c t u a l i z a c i ó n no se r e a l i z a ; e n caso de actualizarse c u a l q u i e r otro

c a m p o , se a l m a c e n a r á en " c o n t r o l " , el nombre d e l u s u a r i o y la fecha.


1 1 8 - S e g u r i d a d y acceso a Oracle

U n a d e l a s tareas a l a d m i n i s t r a r Oracle es p e r m i t i r el acceso a bases de datos y

a s i g n a r p e r m i s o s sobre l o s objetos q u e conforman u n a base de datos.

Para conectarnos con u n s e rv i d o r O r a c l e necesitamos u n m o d o de acceso q u e

i n c l u y e los p e r m i s o s q u e d i s p o n d r e m o s d u r a n t e la c o n e x i ó n ; estos p e r m i s o s se

definen a p a rt i r d e u n n o m b r e de u s u a r i o .

U n U S U A R I O es u n i d e n t i f i c a d o r necesario para acceder a u n a base de d a t o s . U n

u s u a r i o es u n conjunto de p e r m i s o s q u e se a p l i c a n a u n a c o n e x i ó n de base d e datos.

U n u s u a r i o es a d e m á s propietario de ciertos objetos.

Los P R I V I L E G I O S ( p e r m i s o s ) especifican q u é o p e r a c i o n e s p u e d e realizar u n u s u a r i o

y sobre q u é objetos d e l a base de datos t i e n e a u t o r i z a c i ó n , es decir, q u é tarea p u e d e

r e a l i z a r con esos objetos y si p u e d e e m i t i r d e t e r m i n a d a s i n s t r u c c i o n e s . Estas

o p e r a c i o n e s p u e d e n ser de dos t i p o s : de s i s t e m a y sobre objeto.

U n rol de base d e datos es u n a a g r u p a c i ó n de p e r m i s o s de s i s t e m a y de objeto.

U n ROL ( r o l e ) es u n g r u p o d e u s u a r i o s ; permite a g r u p a r u s u a r i o s para a p l i c a r l e s

p e r m i s o s ; a s í , a l a g r e g a r u n nuevo u s u a r i o a l a base de d a t o s , no es necesario

c o n c e d e r l e p e r m i s o para cada objeto, s i n o q u e lo a g r e g a m o s a u n r o l ; c u a n d o

a s i g n a m o s p e r m i s o s sobre u n objeto a l r o l , automáticamente el p e r m i s o afectará a

l o s u s u a r i o s q u e pertenezcan a tal r o l .

Los p e r m i s o s controlan el acceso a l o s d i s t i n t o s objetos de u n a base de d a t o s ;

p u e d e n concederse a n i v e l de u s u a r i o ( i n d i v i d u a l m e n t e ) o a n i v e l d e rol (a todos l o s

u s u a r i o s de u n g r u p o ) .

Los p e r m i s o s q u e u n u s u a r i o t i e n e en u n a base de datos d e p e n d e n de l o s p e r m i s o s

de u s u a r i o y de l o s roles a l q u e pertenezca d i c h o u s u a r i o .

U s u a r i o s , roles y permisos son l a base d e l o s m e c a n i s m o s de s e g u r i d a d de O r a c l e .


1 1 9 - Usuarios ( crear)

P u e d e h a b e r varios u s u a r i o s diferentes de la base de datos. Cada u n o es propietario

de s u s objetos.

Para crear u n u s u a r i o d e b e m o s conectarnos a l a base datos como a d m i n i s t r a d o r e s

( p o r e j e m p l o "system").

S i n t a x i s básica para crear u n u s u a r i o :

create user NOMBREUSUARIO identified by CONTRASEÑA

default tablespace NOMBRETABLESPACEPORDEFECTO

quota CANTIDAD on TABLEESPACE;

** [default role ROLE, ALL];

La c l á u s u l a " i d e n t i f i e d by" permite i n d i c a r u n a c o n t r a s e ñ a .

La c l á u s u l a " d e f a u l t t a b l e s p a c e " será el t a b l e s p a c e ( e s p a c i o de t a b l a s ) por defecto en

l a creación de objetos d e l u s u a r i o . S i se o m i t e se u t i l i z a r á el tablespace S Y S T E M .

Los t a b l e s p a c e s son u n i d a d e s l ó g i c a s en l a s c u a l e s de d i v i d e u n a base de d a t o s , e n

l a s c u a l e s se a l m a c e n a n los objetos ( t a b l a s , s e c u e n c i a s , e t c . ) ; todos l o s objetos

están a l m a c e n a d o s dentro de u n t a b l e s p a c e .

La c l á u s u l a " q u o t a " p e r m i t e c o n f i g u r a r u n e s p a c i o en bytes, Kb o M b e n l a base de

datos. S i no se especifica, por defecto es cero y no podrá crear objetos.

La c l á u s u l a " d e f a u l t role" p e r m i t e a s i g n a r roles d e p e r m i s o s d u r a n t e l a creación d e l

usuario.

Ejemplo:

create user ana identified by anita;

C o n l a s e n t e n c i a a n t e r i o r se crea u n u s u a r i o d e n o m i n a d o " a n a " con l a c l a v e " a n i t a " ,

el t a b l e s p a c e por defecto es "system" p o r q u e no se especificó otro.

C o n l a s i g u i e n t e s e n t e n c i a se crea u n u s u a r i o d e n o m i n a d o " j u a n " con l a clave

" j u a n c i t o " , se le a s i g n a u n e s p a c i o d e 1 0 0 m b :

create user juan identified by juancito

default tablespace system

quota 100M on system;

S i i n t e n t a m o s crear u n u s u a r i o q u e ya existe, Oracle muestra u n mensaje de error

i n d i c a n d o tal s i t u a c i ó n .

E l d i c c i o n a r i o "dba_users" muestra i n f o r m a c i ó n sobre todos los u s u a r i o s ; el n o m b r e

de u s u a r i o ( u s e r n a m e ) , contraseña (password), estado (account_status), e s p a c i o


( d e f a u l t _ t a b l e s p a c e ) , fecha de e x p i r a c i ó n (expiry_date), fecha de creación (created),

entre otros.

L u e g o de crear u n u s u a r i o , a ú n no p o d e m o s conectarnos, ya q u e no t e n e m o s

p e r m i s o para crear u n a s e s i ó n . Los p e r m i s o s se a p r e n d e r á n p r ó x i m a m e n t e .


1 2 0 - Permiso de conexión

Los u s u a r i o s n e c e s i t a n p e r m i s o s para poder acceder a la base de datos y a los

objetos de l a m i s m a .

Los p r i v i l e g i o s p u e d e n ser d e d o s t i p o s : d e l sistema y sobre objetos.

C o m o m í n i m o , u n u s u a r i o d e b e t e n e r p e r m i s o para conectarse.

E l p e r m i s o "create s e s s i o n " es u n p r i v i l e g i o d e s i s t e m a .

Para c o n c e d e r p e r m i s o de c o n e x i ó n a u n u s u a r i o e m p l e a m o s l a i n s t r u c c i ó n " g r a n t " .

Sintaxis básica:

grant create session

to USUARIO;

E n el s i g u i e n t e e j e m p l o concedemos al u s u a r i o " j u a n " p e r m i s o para conectarse:

grant create session to juan;

P o d e m o s c o n s u l t a r el d i c c i o n a r i o "dba_sys_privs" para encontrar los p r i v i l e g i o s

c o n c e d i d o s a los u s u a r i o s . N o s mostrará el n o m b r e d e l u s u a r i o (grantee) y el p e r m i s o

( p r i v i l e g e ) , entre otra información q u e a n a l i z a r e m o s p r ó x i m a m e n t e .

L u e g o de t e n e r p e r m i s o para crear s e s i ó n , p u e d e crear u n a s e s i ó n p r e s i o n a n d o el

ícono "new c o n n e c t i o n " e n l a s o l a p a " c o n n e c t i o n s " ; se abrirá u n a ventana e n l a c u a l

deberá colocar u n n o m b r e de conexión ( " c o n n e c t i o n n a m e " , p u e d e s e r el m i s m o

n o m b r e de u s u a r i o ) , el n o m b r e d e l u s u a r i o ( " u s e r n a m e " ) y l a contraseña

( " p a s s w o r d " ) , l u e g o p r e s i o n a r el botón " c o n n e c t " ; se a b r i r á u n a n u e v a s o l a p a ( n u e v a

c o n e x i ó n ) con el n o m b r e d e l u s u a r i o ; no se a b r i r á l a n u e v a conexión s i :

a ) el u s u a r i o para q u i e n q u i e r e a b r i r u n a n u e v a s e s i ó n n o existe,

b) l a contraseña es incorrecta o

e) el u s u a r i o existe pero no t i e n e p e r m i s o "create s e s s i o n " .

S i c o n s u l t a m o s el d i c c i o n a r i o "user_sys_privs" o b t e n d r e m o s l a m i s m a i n f o r m a c i ó n

q u e "dba_sys_privs" pero ú n i c a m e n t e d e l u s u a r i o a c t u a l .

P o d e m o s a v e r i g u a r el n o m b r e d e l u s u a r i o conectado con la s i g u i e n t e s e n t e n c i a :

select user from dual;


121 - P r i v i l e g i o s d e l sistema ( c o n c e d e r )

A p r e n d i m o s q u e l o s u s u a r i o s necesitan permisos para p o d e r acceder a la base de

datos y a los objetos d e l a m i s m a . D i j i m o s q u e l o s p r i v i l e g i o s p u e d e n ser de d o s

t i p o s : a ) d e l s i s t e m a y b) sobre objetos.

H e m o s a p r e n d i d o a c o n c e d e r u n p r i v i l e g i o de s i s t e m a : "create s e s s i o n " , q u e es

necesario para p o d e r conectarse a l a base d e datos, es decir, para i n i c i a r u n a s e s i ó n .

Pero t e n i e n d o ú n i c a m e n t e este p e r m i s o , no p o d e m o s hacer m u c h o , s o l a m e n t e i n i c i a r

u n a s e s i ó n , pero no podemos crear t a b l a s , n i n i n g ú n otro objeto; por e l l o son

i m p o rt a n t e s l o s p e r m i s o s d e creación d e objetos.

A p r e n d a m o s m á s sobre l o s p r i v i l e g i o s d e s i s t e m a .

Los p r i v i l e g i o s d e s i s t e m a son p e r m i s o s para r e a l i z a r ciertas o p e r a c i o n e s en la base

de datos.

Los s i g u i e n t e s son a l g u n o s de l o s p r i v i l e g i o s de s i s t e m a existentes:

- create s e s s i o n : para conectarse a l a base de datos;

- create t a b l e : crear t a b l a s ;

- create s e q u e n c e : crear s e c u e n c i a s ;

- create v i e w : crear v i s t a s ;

- create t r i g g e r : crear d i s p a r a d o r e s en su p r o p i o e s q u e m a ;

- create p r o c e d u r e : crear p r o c e d i m i e n t o s y f u n c i o n e s ;

- execute a n y p r o c e d u r e : ejecutar c u a l q u i e r p r o c e d i m i e n t o en c u a l q u i e r e s q u e m a ;

- create u s e r : crear u s u a r i o s y especificar c l a v e s ;

- create r o l e : crear r o l e s ;

- drop u s e r : e l i m i n a r u s u a r i o s .

Se a s i g n a n p r i v i l e g i o s de sistema a u n u s u a r i o m e d i a n t e l a i n s t r u c c i ó n " g r a n t " :

Sintaxis básica:

grant PERMISODESISTEMA

to USUARIO;
O r a c l e permite c o n c e d e r m ú l t i p l e s p r i v i l e g i o s a m ú l t i p l e s u s u a r i o s en u n a m i s m a

s e n t e n c i a , d e b e m o s separarlos por c o m a s .

E n el s i g u i e n t e e j e m p l o se concede el p e r m i s o para crear s e s i ó n a los u s u a r i o s " j u a n "

y "ana":

grant create sesion

to juan, ana;

E n el s i g u i e n t e e j e m p l o se conceden los permisos para crear t a b l a s y vistas al

usuario "ana":

grant create table, create view

to ana;

E n el s i g u i e n t e e j e m p l o se conceden 2 p e r m i s o s a 2 u s u a r i o s en u n a s o l a s e n t e n c i a :

grant create trigger, create procedure

to juan, ana;

C o n s u l t a n d o el d i c c i o n a r i o "dba_sys_privs" encontramos los p r i v i l e g i o s c o n c e d i d o s a

l o s d i s t i n t o s u s u a r i o s ; y c o n s u l t a n d o "user_sys_privs" obtendremos l a m i s m a

información pero ú n i c a m e n t e d e l u s u a r i o a c t u a l .
1 2 2 - Privilegios d e l sistema (with a d m i n

option)

H e m o s a p r e n d i d o l a s i n t a x i s básica para conceder p e r m i s o s d e sistema a l o s

usuarios, mediante la instrucción "grant".

A g r e g a n d o a l a s e n t e n c i a " g r a n t " , l a c l á u s u l a "with a d m i n o p t i o n " concedemos

p e r m i s o para c e d e r a terceros l o s p r i v i l e g i o s d e sistema o b t e n i d o s . Es decir, la

c l á u s u l a "with a d m i n o p t i o n " p e r m i t e q u e el p r i v i l e g i o c o n c e d i d o a u n u s u a r i o (o rol)

p u e d a s e r otorgado a otros u s u a r i o s p o r el u s u a r i o a l q u e estamos a s i g n á n d o s e l o ; es

decir, se concede p e r m i s o para conceder el p e r m i s o o b t e n i d o , a otros u s u a r i o s .

Sintaxis:

grant PERMISODESISTEMA

to USUARIO

with admin option;

E n el s i g u i e n t e e j e m p l o , concedemos el p e r m i s o de crear t a b l a s al u s u a r i o " j u a n " y

con "with a d m i n o p t i o n " , el u s u a r i o " j u a n " podrá conceder este p e r m i s o d e crear

t a b l a s a otros u s u a r i o s :

grant create table

to juan

with grant option;

P o d e m o s c o n s u l t a r el d i c c i o n a r i o "dba_sys_privs" para e n c o n t r a r los p r i v i l e g i o s

c o n c e d i d o s a los u s u a r i o s . N o s mostrará u n a t a b l a con l a s s i g u i e n t e s c o l u m n a s :

- g r a n t e e : el n o m b r e d e l u s u a r i o ,

- p r i v i l e g e : el p e r m i s o y

- a d m i n _ o p t i o n : si el p e r m i s o a d q u i r i d o p u e d e ser c e d i d o a otros o n o , Y E S o N O .