Está en la página 1de 117

Generalidades

SQL  (Structured  Query  Language,  lenguaje  estructurado  de  consulta)  es  un  lenguaje  de  consulta  utilizado  para 
manipular bases de datos relacionales. 

Fue desarrollado a mediados de los años 70 por IBM y lo comenzó a comercializar Oracle en 1979. 

El interés del SQL reside en las siguientes características: 

Normalización 

Implementa el modelo relacional y se describe en los estándares de los principales organismos de normalización, que 
lo describen como sigue: 

l El instituto ANSI (American National Standards Institute) lo describe en sus documentos ANSI 9075­1:1999, ANSI 9075­
2:1999  y  ANSI 9075­5:1999. Puede obtener más detalles sobre estos documentos que describen la norma visitando el
sitio web de ANSI (http://webstore.ansi.org ) o bien el sitio web de NCITS (National Comittee for Information Technology
Standards) que incluye parte de los estándares ANSI sobre SQL (http://www.incits.org).

l ISO  (International  Organisation  for  Standardization)  lo  describe  en  los  documentos  ISO/IEC  9075­1:1999,  ISO/IEC
9075­2:1999  e  ISO/IEC 9075­5:1999. Puede obtener una copia de los documentos de normalización en el sitio web de
ISO: http://www.iso.ch/iso/iso_catalogue.html .

Estándar 

Debido a esta normalización, la mayor parte de los creadores de sistemas de bases de datos relacionales integran el 
SQL en sus productos (INFORMIX, DB2, MS SQL Server, SYBASE...). 

Los datos, consultas y aplicaciones pueden por tanto migrarse con bastante facilidad de una base de datos a otra. 

No procedimental 

El  SQL  es  un  lenguaje  de  consulta  que  permite  al  usuario  solicitar  un  resultado  sin  preocuparse  de  los  medios 
técnicos necesarios para obtener dicho resultado. Un componente del motor de la base de datos (el optimizador) se 
encarga de esta tarea. 

Las instrucciones se escriben en inglés, en lenguaje natural. 

El SQL permite manipular tanto registros individuales como conjuntos de registros y permite el uso del resultado en 
otro comando. Por tanto, no son necesarias estructuras de control como en los lenguajes de programación habituales 
(lenguajes de tercera generación). 

Universal 

El lenguaje SQL puede utilizarse en todos los niveles de la gestión de una base de datos: 

l administración del sistema,

l administración de la base de datos,

l desarrollo y aplicaciones,

l gestión de datos simple.

© Éditions ENI – Todos los derechos reservados - 1-


Todos los usuarios de la base de datos disponen por tanto de un lenguaje común. 

Este lenguaje permite además realizar todas las operaciones: 

l consultar datos,

l añadir, eliminar y modificar datos,

l gestionar objetos (estructuras),

l gestionar los mecanismos de seguridad de acceso a los datos.

1. Componentes de la base de datos lógica: los objetos SQL

Una  base  de  datos  relacional  está  formada  por  entidades  lógicas  o  físicas  que  el  lenguaje  SQL  puede  manipular. 
Estas entidades se denominan objetos SQL. 

El primero es la base de datos, que agrupa al conjunto de los demás objetos. 

Estos objetos pueden agruparse en diferentes categorías en función de su utilidad. 

a. La gestión de los datos

tabla (table) Conjunto de líneas (filas) y columnas. 

índice (index)  Columna o conjunto de columnas que permiten realizar búsquedas más 
rápidamente. 

vista (view)  Consulta que puede manipularse como una tabla (tabla virtual). 

sinónimo (synonym)  Nombre alternativo para una tabla o una vista. 

secuencia (sequence)  Generador de una serie de números. 

instantáneas (snapshots)  Tabla que contiene el resultado de una consulta realizada sobre una 
tabla creada en una base de datos remota. 

enlaces de base de datos (database  Vínculos con otras bases de datos remotas. 
links) 

b. Almacenamiento físico

agrupación (clúster) Agrupación física de tablas que tienen columnas comunes. 

espacio de tablas (tablespace) Agrupación lógica de archivos. 

directorio (directory) Representación en la base de datos de un directorio del sistema 
operativo del host. 

c. Almacenamiento de instrucciones

esquema (schema) Conjunto  de  objetos  de  la  base  de  datos  lógica  que  pertenecen  a  un 
mismo usuario. 

procedimiento (procedure)  Fragmento de código procedimental nominado. 

función (function)  Fragmento de código procedimental nominado que devuelve un valor. 

disparador de base de datos (database  Fragmento de código procedimental asociado con una tabla. 
trigger) 

- 2- © Éditions ENI – Todos los derechos reservados


paquetes (packages)  Colección de objetos (procedimiento, función...) almacenados de 
manera conjunta. 

biblioteca (library)  Representación de una colección de procedimientos externos a Oracle, 
almacenados en bibliotecas compartidas del sistema. 

d. Gestión de los usuarios

perfil (profile) Conjunto nominado de restricciones del sistema. 

rol (role)  Conjunto de privilegios que puede atribuirse a los usuarios. 

usuario (user)  Individuo que puede conectarse y acceder a los recursos de la base de 
datos. 

Los  objetos  creados  por  los  usuarios  del  sistema  de  gestión  de  bases  de  datos  relacionales  (RDBMS)  de  Oracle 
deben tener un nombre. 

e. Denominación de los objetos

Los nombres de los objetos deben ajustarse a las siguientes reglas:

l Deben tener una longitud de 1 a 30 caracteres, excepto la base de datos (8) y los enlaces de base de datos (128).

l No se distingue entre mayúsculas y minúsculas.

l Deben comenzar por una letra.

l Pueden emplearse los caracteres alfanuméricos + _ $ y # (además de @ y . para los enlaces de base de datos).

l No deben utilizarse palabras reservadas para designar objetos.

l Deben ser unívocos en el esquema de un usuario, incluso cuando se trate de tipos de objetos diferentes.

Convenciones 

Los nombres que se utilicen deben ser significativos y no demasiado largos. 

Es aconsejable emplear nombres idénticos para designar las mismas entidades en objetos diferentes de la base 
de datos (nombres de columnas). 

Cuando los nombres de los objetos se especifican sin comillas, Oracle no tiene en cuenta que se usen mayúsculas 
o minúsculas  (los  nombres  se  almacenan  en  mayúsculas  al  crearse  los  objetos  y  después,  cuando  se  hace
referencia a ellos, Oracle realiza automáticamente la conversión a mayúsculas).

Sin embargo, los nombres de los objetos pueden especificarse entre comillas dobles. En este caso, Oracle utiliza 
las mayúsculas y minúsculas empleadas en el nombre escrito entre comillas para hacer referencia al objeto. No es 
recomendable utilizar esta posibilidad, ya que la escritura se hace más pesada y los riesgos de cometer errores de 
sintaxis aumentan. 

2. Categorías de instrucciones

Las instrucciones SQL se agrupan en categorías en función de su utilidad y de las entidades manipuladas. 

a. DDL (Data Definition Language, lenguaje de definición de datos)

© Éditions ENI – Todos los derechos reservados - 3-


Permite gestionar las "estructuras" de los objetos: 

l Crear, modificar, eliminar objetos.

l Autorizar o prohibir el acceso a los datos.

l Activar o desactivar la auditoría.

l Añadir comentarios al diccionario de datos.

Las instrucciones DDL son: CREATE, ALTER, DROP, GRANT, REVOKE, AUDIT, NOAUDIT, ANALYZE, RENAME, TRUNCATE, 
COMMENT, FLASHBACK y PURGE. 

b. DML (Data Manipulation Language, lenguaje de manipulación de datos)

Permite la gestión de los datos contenidos en los objetos existentes:

l Añadir, eliminar y modificar filas.

l Visualizar el contenido de las tablas.

l Bloqueo de tablas.

Las instrucciones DML son: INSERT, UPDATE, DELETE, SELECT, EXPLAIN PLAN, LOCK TABLE y MERGE. 

c. TCL (Transaction Control language)

Gestiona las modificaciones realizadas por las instrucciones DML:

l Características de las transacciones.

l Validación y anulación de modificaciones.

Las instrucciones del TCL son: COMMIT, SAVEPOINT, ROLLBACK, SET TRANSACTION y SET CONSTRAINT. 

d. SCL (Session Control language)

Permite la gestión de una sesión de usuario:

l Modificación de las características de sesión.

l Activación y desactivación de los privilegios de usuario.

Las instrucciones del SCL son: ALTER SESSION, SET ROLE. 

e. Embedded SQL

Permite integrar los lenguajes DDL, DML y de control de transacciones en un lenguaje de programación:

l Declaraciones de objetos o de instrucciones.

l Ejecución de instrucciones.

l Gestión de variables y cursores.

l Tratamiento de errores.

- 4- © Éditions ENI – Todos los derechos reservados


Las  instrucciones  del  SQL  embebido  son:  DECLARE,  TYPE,  DESCRIBE,  VAR,  CONNECT,  PREPARE,  EXECUTE,  OPEN, 
FETCH, CLOSE, WHENEVER. 

© Éditions ENI – Todos los derechos reservados - 5-


Descripción de objetos

Cuando se emplea una base de datos, los primeros objetos que hay que manipular son las tablas, que "contienen" 
los datos, y los índices, que permiten obtener un mejor rendimiento de las consultas. 

Estos dos tipos de objetos se deben crear antes de comenzar a manipular los datos en sí. 

1. Tipos

CHAR (n) 

Cadena de caracteres de longitud fija de n bytes, que se completa añadiendo espacios a la derecha (n 
<= 2000). 

VARCHAR2 (n) 

Cadena de caracteres de longitud variable, de n bytes como máximo (n <= 4000 si el argumento 


MAX_STRING_SIZE es igual a STANDARD; n <= 32767 si el argumento MAX_STRING_SIZE es igual a 
EXTENDED). 

NCHAR (n) 

Cadena de caracteres de longitud fija de n bytes, que se completan añadiendo espacios a la derecha 
(n <= 2000). Los caracteres se codifican de acuerdo con el juego de caracteres nacional activo. 

NVARCHAR2 (n) 

Cadena de caracteres de longitud variable, de n bytes como máximo (n <= 4000 si el argumento 


MAX_STRING_SIZE es igual a STANDARD; n <= 32767 si el argumento MAX_STRING_SIZE es igual a 
EXTENDED). Los caracteres se codifican de acuerdo con el juego de caracteres nacional activo. 

NUMBER (p,s) 

Número con una precisión de p cifras, de las cuales s son decimales, siendo (1 <= p <= 38 y ­84 <= s 
<= +127). 

DATE 

Fecha comprendida entre el 1 de enero de 4712 a.C. y el 31 de diciembre de 9999 d.C. 

TIMESTAMP (p) 

Datos de tipo Date (año, mes, día, hora, minutos y segundos) en los que es posible especificar, con 
una precisión p, el número de cifras significativas para las fracciones de segundo. El valor 
predeterminado es 6. 

TIMESTAMP(p) WITH TIME ZONE 

Datos de tipo TIMESTAMP con desplazamiento de zona horaria. 

TIMESTAMP(p) WITH LOCAL TIME ZONE 

© Éditions ENI – Todos los derechos reservados - 1-


Datos de tipo TIMESTAMP WITH TIME ZONE que están almacenados en el servidor teniendo en cuenta 
la zona horaria del mismo, pero que se muestran en el equipo del cliente teniendo en cuenta la zona 
horaria definida en el nivel de sesión. 

BLOB 

Datos binarios no estructurados (hasta 128 TB como máximo, dependiendo del tamaño del bloque 
utilizado en la base de datos). 

CLOB 

Cadena de caracteres de longitud variable (hasta 128 TB como máximo, dependiendo del tamaño del 
bloque utilizado en la base de datos). Solo puede contener caracteres codificados con 1 byte. 

NCLOB 

Cadena de caracteres de longitud variable (hasta 128 TB como máximo, dependiendo del tamaño del 
bloque utilizado en la base de datos). Tiene en cuenta los juegos de caracteres de longitud variable. 

BFILE 

Datos binarios almacenados en archivos externos a la base de datos (hasta 264­1 bytes, excepto si 
existe alguna limitación por parte del sistema operativo). 

Los siguientes tipos de datos aseguran la compatibilidad con las versiones anteriores 

LONG 

Cadena de caracteres de longitud variable (2 GB como máximo). 

RAW (n) 

Datos binarios de longitud variable (n bytes como máximo; n < = 2000 si el argumento 
MAX_STRING_SIZE es igual a STANDARD; n <= 32767 si el argumento MAX_STRING_SIZE es igual a 
EXTENDED); cuyo contenido no es interpretado por Oracle. 

LONG RAW (n) 

Datos binarios de longitud variable (4 GB como máximo); cuyo contenido no es interpretado por Oracle. 

Tipos de datos extendidos (Extended Data Types) 

Desde  la  version  12,  el  tamaño  máximo  posible  de  una  cadena  de  caracteres  de  tipo  [N]VARCHAR2  es  de  32.767 
bytes  (4.000  bytes  en  las  versiones  anteriores).  Para  usar  esta  funcionalidad,  el  argumento  de  inicio 
MAX_STRING_SIZE debe ser igual a EXTENDED; por defecto, es igual a STANDARD y se aplica el antiguo.  

Esta funcionalidad se puede activar en una nueva base de datos definiendo el argumento MAX_STRING_SIZE con el 
valor  EXTENDED  durante  la  creación  de  la  misma.  También  se  puede  activar  en  una  base  de  datos  existente 
(consulte la descripción del argumento MAX_STRING_SIZE en la documentación Oracle® Database Reference para el 
modo operativo). Por el contrario, no es posible usar el valor del argumento MAX_STRING_SIZE igual a EXTENDED 
con valor STANDARD. 

- 2- © Éditions ENI – Todos los derechos reservados


De manera interna, los tipos de datos extendidos se almacenan de manera transparente bajo la forma de LOB, que 
no se pueden manipular directamente. 

2. Creación de una tabla

Una  tabla  es  un  conjunto  de  filas  y  columnas.  La  creación  consiste  en  definir  (en  función  del  análisis  realizado)  el 
nombre de las columnas, su formato (type, el tipo), un valor predeterminado (DEFAULT) para cuando se crea la fila y 
las reglas de gestión que se aplican a la columna (CONSTRAINT). Si una regla de gestión afecta a varias columnas 
de la fila, se define una restricción de tabla. 

Es posible definir hasta 1000 columnas por tabla. 

Sintaxis 

CREATE TABLE nombre (nombrecolumna type [DEFAULT expr]


[[CONSTRAINT nombre restricción-de-columna...],...
[,CONSTRAINT nombre restricción-de-tabla...]);

DEFAULT 

El valor por defecto solo se usa cuando la columna no está en una operación INSERT. 

La cláusula ON NULL, que apareció en la versión 12, permite especificar que el valor por defecto también se debe 
usar si un valor NULL se asigna a la columna en una operación INSERT. El valor por defecto de la columna también 
se puede asignar explícitamente a la columna en una operación INSERT o UPDATE con la palabra clave DEFAULT (). 

Desde la versión 12, el valor por defecto de una columna puede hacer referencia a una secuencia con las pseudo­
columnas  nomseq.NEXTVAL  y  nomseq.CURRVAL;  la  secuencia  debe  haberse  definido  previamente  (consulte  la 
sección SQL avanzado en este capítulo). 

a. Restricciones de columna

NULL/NOT NULL

Autoriza (NULL) o prohíbe (NOT NULL) la inserción del valor NULL en un atributo. 

PRIMARY KEY 

Designa al atributo como clave primaria de la tabla. Esta restricción solo puede aparecer una vez en 
la instrucción. 

UNIQUE 

Designa el atributo como clave secundaria de la tabla. En el caso de que la restricción UNIQUE se 
aplique a una única columna, el atributo puede tomar el valor NULL. Esta restricción puede aparecer 
varias veces en la instrucción. 

REFERENCES tabla [(columna)] [ON DELETE {CASCADE|SET NULL] 

Restricción de integridad referencial para el atributo en la tabla de detalle que se está definiendo. 
Los valores tomados por este atributo deben existir en una columna que tenga asociada una 
restricción PRIMARY KEY o UNIQUE en la tabla maestra. 

© Éditions ENI – Todos los derechos reservados - 3-


CHECK (condición) 

Verifica, al insertar filas, que el atributo cumple la condición especificada (consulte la sección 
Manipulación de los datos para ver la sintaxis de la condición). 

Preste  atención,  en  una  restricción  CHECK  no  es  posible  hacer  referencia  a  la  función  SYSDATE  o  bien 
CURRENT_DATE  para  comparar  el  valor  de  una  columna  de  tipo  fecha  con  el  resultado  de  la  ejecución  de  esta 
función. Sin embargo, sí es posible, si así se desea, comparar mediante una restricción CHECK los valores de dos 
columnas de tipo fecha. 

Si  se  quiere  comparar  el  valor  de  una  columna  de  tipo  fecha  con  la  fecha  actual  es  necesario  implementar  un 
disparador (trigger) de base de datos. Otra posibilidad consiste en crear una columna de tipo fecha con un valor 
predeterminado igual a la fecha del día más una restricción CHECK que compare los valores presentes en las dos 
columnas. 

b. Restricciones de tabla (sobre varias columnas)

PRIMARY KEY (columna,...)

Designa la concatenación de los atributos citados como clave primaria de la tabla. Esta restricción no 
puede aparecer más de una vez en la instrucción. 

UNIQUE (columna,...) 

Designa la concatenación de los atributos especificados como clave secundaria de la tabla. En el caso 
de que esta restricción UNIQUE se aplique sobre una serie de columnas concatenadas, al menos una 
de las columnas que formen parte de esta clave secundaria debe permitir distinguir la fila de manera 
unívoca. Esta restricción puede aparecer varias veces en la instrucción. 

FOREIGN KEY (columna,...) REFERENCES tabla [(columna,...)] [ON DELETE {CASCADE | SET NULL}] 

Restricción de integridad referencial para el conjunto de atributos especificados de la tabla de detalle 
que se está definiendo. Los valores que toman estos atributos deben existir en una columna que 
tenga asociada una restricción PRIMARY KEY o UNIQUE en la tabla maestra. 

CHECK (condición) 

Esta restricción permite expresar una condición que debe cumplirse para una serie de atributos de la 
fila (consulte la sección Manipulación de los datos para ver la sintaxis de la condición). 

Las  restricciones  de  tabla  se  aplican  a  varias  columnas  de  la  tabla  sobre  la  que  están  definidas.  No  es  posible 
definir una restricción de integridad utilizando columnas procedentes de dos o más tablas. Este tipo de restricción 
se implementará mediante de disparadores (triggers) de la base de datos, cuya definición se verá más adelante en el 
libro. 

c. Opciones de las restricciones

ON DELETE CASCADE

Especifica la eliminación de las filas dependientes contenidas en la tabla que se está definiendo, si se 
elimina la fila que contiene la clave primaria correspondiente en la tabla maestra. Si esta opción no se 

- 4- © Éditions ENI – Todos los derechos reservados


especifica, será imposible eliminar en la tabla maestra las filas que hacen referencia a este valor de 
clave primaria. 

ON DELETE SET NULL 

Especifica que se asigne el valor NULL a las columnas que constituyen la clave externa que hace 
referencia a la fila eliminada. Si esta opción no se especifica, será imposible eliminar en la tabla 
maestra las filas que hacen referencia a este valor de la clave. 

[NOT] DEFERRABLE 

Realiza o no (NOT) la verificación de la restricción en el momento de validar la transacción. 

d. Denominación de las restricciones

Es  posible  asignar  un  nombre  a  las  restricciones  con  el  fin  de  poder  después  manipularlas  más  fácilmente
(activación  y  eliminación).  En  el  caso  de  que  no  se  asigne  explícitamente  un  nombre  a  una  restricción,  Oracle
genera automáticamente un nombre de la forma SYS_Cn (n es un número entero exclusivo).

A  la  hora  de  asignar  explícitamente  un  nombre  a  una  restricción,  resulta  útil  emplear  el  siguiente  convenio  de
nomenclatura:

Tabla_Columna_TipoDeRestriccion

Tabla  Nombre de la tabla sobre la que se define la restricción. 

Columna  Nombre de la columna o columnas sobre las que se define la restricción. 

TipoDeRestriccion:  mnemónico asociado con el tipo de restricción: 
PK   Clave primaria 
UQ   Unique 
NN   Not Null 
CK  Check 
RF   Referencias 
FK   Clave primaria 

Ejemplos 

Creación de una tabla ARTICULOS con una sola restricción de clave primaria REFART: 

SQL> create table ARTICULOS(


2 REFART char(4) primary key,
3 DESCRIPCION varchar2(30),
4 PRECIO number(8,2),
5 CODIVA number(1),
6 CATEGORIA char(10),
7 CANTALM number(5)
8 );

Tabla creada.

SQL>

© Éditions ENI – Todos los derechos reservados - 5-


En este caso, DESCRIPCION, PRECIO y CANTALM pueden ser NULL: PRECIO y CANTALM pueden tomar valores negativos. 

Creación de una tabla CLIENTES con restricciones sobre las columnas: 

SQL> create table CLIENTES(


2 NUMCLI number(4)
3 constraint CLIENTES_PK primary key
4 constraint CLIENTES_NUMCLI_CK check (NUMCLI>0),
5 NOMCLI varchar2(30)
6 constraint CLIENTES_NOMCLI_NN not null,
7 DIRECCLI varchar2(60),
8 COD_POSTAL number(5)
9 constraint CLIENTES_COD_POSTAL_CK
10 check(COD_POSTAL between 1000 and 99999),
11 CIUDAD char(30)
12 );

Tabla creada.

SQL>

NUMCLI y NOMCLI son obligatorios; 

NUMCLI debe ser siempre positivo; 

COD_POSTAL debe pertenecer al intervalo especificado. 

Creación de la tabla de pedidos utilizando una sintaxis de tipo restricción de tabla para definir las restricciones de integridad. 

SQL> create table PEDIDOS(


2 NUMPED number(6),
3 NUMCLI number(4),
4 FECHAPED date,
5 ESTADOPED char(2),
6 constraint PK_PEDIDOS primary key (NUMPED),
7 constraint FK_PEDIDOS_CLIENTES foreign key(NUMCLI)
8 references CLIENTES(NUMCLI),
9 constraint CK_PEDIDOS_ESTADO check (ESTADOPED in (’EC’,’SU’,’SE’))
10 );

Tabla creada.

SQL>

Creación  de  la  tabla  LINPED  con  restricciones  de  referencia  sobre  las  columnas  y  una  restricción  de  tabla  para  la  clave 
primaria: 

SQL> create table LINPED(


2 NUMPED number(6)
3 constraint FK_LINPED_PEDIDOS
4 references PEDIDOS(NUMPED),
5 NUMLIN number(2)

- 6- © Éditions ENI – Todos los derechos reservados


6 constraint CK_LINPED_NUMLIN check (NUMLIN>0),
7 REFART char(4)
8 constraint FK_LINPED_ARTICULOS
9 references ARTICULOS(REFART),
10 CANTPED number(5),
11 constraint PK_LINPED primary key (NUMPED,NUMLIN)
12 );

Tabla creada.

SQL>

Sea cual sea el modo de definición de las restricciones (a nivel de columna o de tabla), el resultado es el mismo. 
Solo  las  restricciones  de  integridad  que  se  aplican  a  varias  columnas  de  la  misma  tabla  deben  obligatoriamente 
definirse empleando una sintaxis de restricción de tabla. 

e. La columna virtual

Una  columna  virtual  es  una  columna  definida  por  una  expresión  que  se  evalúa  cada  vez  que  se  produce  una
consulta;  no  se  almacena  ningún  valor  en  la  tabla  para  la  columna  en  cuestión.  Esta  funcionalidad  es  nueva  a
partir de la versión 11.

Sintaxis

nombrecolumna [tipo] [GENERATED ALWAYS] AS (expresión) [VIRTUAL]


[restricción_de_columna]

El tipo de datos es opcional; si no se especifica, Oracle lo determina a partir del tipo de datos de la expresión.

La cláusula AS permite especificar la expresión que determina el valor de la columna. Esta expresión puede hacer
referencia  a  otras  columnas  reales  (no  virtuales)  de  la  misma  tabla,  pero  no  puede  hacer  referencia  a  ninguna
columna de otra tabla.

Las  palabras  reservadas  GENERATED  ALWAYS  y  VIRTUAL  son  opcionales;  pueden  especificarse  para  hacer  la
sintaxis más clara.

Puede definirse una restricción de columna sobre una columna virtual.

Ejemplo

SQL> create table ARTICULOS (


2 REFART char(4) primary key,
3 DESCRIPCION varchar2(30),
4 PRECSINIVA number(8,2),
5 IVA number(4,2),
6 PRECCONIVA number(8,2)
7 AS ( PRECSINIVA + round(PRECSINIVA * IVA/100,2))
7 );
Tabla creada.

SQL>
SQL> insert into ARTICULOS (REFART, DESCRIPCION, PRECSINIVA, IVA)

© Éditions ENI – Todos los derechos reservados - 7-


2 values (’XT10’,’Paquete de 10 lápices’,10,21);
1 fila creada.

SQL>
SQL> insert into ARTICULOS (REFART, DESCRIPCION, PRECSINIVA, IVA)
2 values (’AD23’,’Los Tres Mosqueteros’,10,4);

1 fila creada.

SQL>
SQL> select DESCRIPCION, PRECSINIVA, PRECCONIVA from ARTICULOS;

DESCRIPCION PRECSINIVA PRECCONIVA


------------------------- ------------- ---------------
Paquete de 10 lápices 10 12,10
Los Tres Mosqueteros 10 10,40

f. Columna de tipo identidad

Una  columna  de  tipo  identidad  es  una  columna  numérica  entera  a  la  que  se  asigna  automáticamente  un  valor
creciente  (o  decreciente)  durante  un  INSERT.  De  manera  interna,  Oracle  utiliza  une  secuencia  para  generar  el
número (consulte la sección SQL avanzado en este capítulo). Esta funcionalidad apareció en la versión 12.

Sintaxis

nombrecolumna type GENERATED [ALWAYS | BY DEFAULT [ON NULL]]


AS IDENTITY [(options)][restricción-de-columna]

La  clausura  ALWAYS  fuerza  el  uso  de  la  identidad;  se  devuelve  un  error  si  un  INSERT  intenta  asignar  un  valor
(incluso  NULL)  en  la  columna  o  si  un  UPDATE  intenta  modificar  la  columna.  Es  el  valor  por  defecto  de  la  cláusula
GENERATED AS IDENTITY.

La cláusula BY DEFAULT permite al usuario asignar un valor (no NULL) a la columna en un INSERT o un UPDATE; en
ambos  casos  la  asignación  de  un  valor  NULL  genera  un  error.  La  cláusula  ON  NULL  permite  especificar  que  la
identidad también se debe usar si un valor NULL se asigna a la columna en un INSERT.

La  cláusula  options  permite  especificar  las  características  de  la  secuencia  que  usa  Oracle  para  generar  el  valor.
Esta  cláusula  ofrece  las  mismas  opciones  que CREATE  SEQUENCE  (consulte  la  sección  SQL  avanzado  en  este
capítulo).

Esta funcionalidad tiene las siguientes restricciones:

l Solo se puede definir una única columna de tipo identidad en una tabla.

l La columna de tipo identidad debe ser de tipo numérico.

l Una columna de tipo identidad no puede tener valor por defecto.

l La columna de tipo identidad es obligatoria (restricción NOT NULL implícita).

Ejemplo 

SQL> create table CATEGORIAS (

- 8- © Éditions ENI – Todos los derechos reservados


2 NOCAT number(3) generated as identity,
3 NOMBRE varchar2(30)
4 );

Tabla creada.

SQL>
SQL> insert into CATEGORIAS (NOMBRE)
2 values (’Informática’);

1 fila creada.

SQL> insert into CATEGORIAS (NOMBRE)


2 values (’Bricolaje’);

1 fila creada.

SQL> select * from CATEGORIAS;

NOCAT NOMBRE
---------- ---------------
1 Informática
2 Bricolaje

SQL>
SQL> -- Prohibición de asignar un valor a la columna en un INSERT o UPDATE.
SQL> insert into CATEGORIAS (NOCAT,NOMBRE)
2 values (123,’Libros’);
insert into CATEGORIAS (NOCAT,NOMBRE)
*
ERROR en la línea 1:
ORA-32795: imposible insertar el valor en una columna
de identidad con las palabras reservadas GENERATED ALWAYS

SQL> update CATEGORIAS set NOCAT = 456 where NOMBRE = ’Informática’;


update CATEGORIAS set NOCAT = 456 where NOMBRE = ’Informática’
*
ERROR en la línea 1:
ORA-32796: imposible modificar un columna de identidad
con las palabras reservadas GENERATED ALWAYS

SQL>
SQL> -- Recreación de la tabla con la opción BY DEFAULT.
SQL> drop table CATEGORIAS;

Tabla eliminada.

SQL> create table CATEGORIAS (


2 NOCAT number(3) generated by default as identity,
3 NOMBRE varchar2(30)
4 );

Tabla creada.

© Éditions ENI – Todos los derechos reservados - 9-


SQL>
SQL> insert into CATEGORIAS (NOMBRE)
2 values (’Informática’);

1 fila creada.

SQL> insert into CATEGORIAS (NOMBRE)


2 values (’Bricolaje’);

1 fila creada.

SQL> select * from CATEGORIAS;

NOCAT NOMBRE
---------- ---------------
1 Informática
2 Bricolaje

SQL>
SQL> -- Ahora es posible asignar un valor (no NULL) a la columna en un INSERT
SQL> -- o UPDATE.
SQL> insert into CATEGORIAS (NOCAT,NOMBRE)
2 values (123,’Libros’);

1 fila creada.

SQL> update CATEGORIAS set NOCAT = 456 where NOMBRE = ’Informática’;

1 fila modificada.

SQL> select * from CATEGORIAS;

NOCAT NOMBRE
---------- ---------------
456 Informática
2 Bricolaje
123 Libros

SQL>
SQL> -- Pero no es posible asignar un valor NULL.
SQL> insert into CATEGORIAS (NOCAT,NOMBRE)
2 values (null,’Maletas’);
values (null,’Maletas’)
*
ERROR en la línea 2:
ORA-01400: imposible insertar NULL en ("ENI"."CATEGORIAS"."NOCAT")

SQL>
SQL> -- Recreación de la tabla con la opción BY DEFAULT ON NULL.
SQL> drop table CATEGORIAS;

Tabla eliminada.

- 10 - © Éditions ENI – Todos los derechos reservados


SQL> create table CATEGORIAS (
2 NOCAT number(3) generated by default on null as identity,
3 NOMBRE varchar2(30)
4 );

Tabla creada.

SQL>
SQL> -- La identidad se usa ahora durante la asignación de un valor NULL
SQL> -- a la columna en un INSERT.
SQL> insert into CATEGORIAS (NOCAT,NOMBRE)
2 values (null,’Maletas’);

1 fila creada.

SQL> select * from CATEGORIAS;

NOCAT NOMBRE
---------- ---------------
1 Maletas

g. Columna invisible

Desde  la  version  12,  una  columna  se  puede  declarar  invisible.  Una  columna  como  esta  solo  es  visible  si  se
especifica  explícitamente  en  una  sentencia  SQL.  Las  columnas  invisibles  no  se  muestran  con  la  sentencia  SQL
SELECT * o con el comando SQL*Plus DESCRIBE.

Sintaxis

nombrecolumna type [VISIBLE | INVISIBLE] [DEFAULT [ON NULL] expr]


[restricción-de-columna]

La cláusula INVISIBLE permite declarar una columna invisible. Por defecto, las columnas de una tabla son visibles
(cláusula VISIBLE).

Exemplo

SQL> create table CATEGORIAS (


2 NOCAT number(3),
3 NOMBRE varchar2(30),
4 RESPONSABLE varchar2(30) invisible
5 );

Table creada.

SQL>
SQL> -- Un INSERT sin enumeración explícita de columnas funciona
SQL> -- como si la columna no existiera.
SQL> insert into CATEGORIAS
2 values (1,’Informática’);

1 fila creada.

© Éditions ENI – Todos los derechos reservados - 11 -


SQL> -- Pero la columna se puede especificar explícitamente
SQL> -- en un INSERT (o UPDATE).
SQL> insert into CATEGORIAS (NOCAT,NOMBRE,RESPONSABLE)
2 values (2,’Libros’,’Ángel’);

1 fila creada.

SQL>
SQL> -- Un SELECT * no muestra la columna invisible.
SQL> select * from CATEGORIAS;

NOCAT NOMBRE
---------- ---------------
1 Informática
2 Libros

SQL>
SQL> -- Es necesario seleccionarla explícitamente para verla.
SQL> select NOCAT,NOMBRE,RESPONSABLE from CATEGORIAS;

NOCAT NOMBRE RESPONSABLE


---------- --------------- ---------------
1 Informática
2 Libros Ángel

Esta  funcionalidad  es  interesante  durante  la  evolución  de  la  estructura  de  una  tabla.  Es  posible  añadir  una 
columna  invisible  a  una  tabla  sin  impactar  el  código  existente  que  funciona  como  si  la  columna  no  existiera, 
permitiendo al nuevo código o al existente modificado hacer referencia explícitamente a las columnas invisibles en 
las  consultas.  La  columna  se  puede  hacer  visible  más  adelante,  cuando  todo  el  código  existente  se  haya 
modificado para funcionar correctamente.  

3. Eliminación de una tabla

Para  borrar  una  tabla  es  necesario  eliminar  su  estructura  y  todos  los  datos  que  contenga.  Los  índices  asociados 
también  se  borran;  las  vistas  creadas  directa  o  indirectamente  sobre  esta  tabla  las  desactiva  automáticamente 
Oracle. 

Si se hace referencia a la clave primaria de la tabla en otras tablas mediante restricciones de tipo REFERENCES o 
FOREIGN  KEY,  la  cláusula  CASCADE  CONSTRAINTS  permite  suprimir  estas  restricciones  de  integridad  referencial  en 
las tablas "descendientes". 

La cláusula PURGE permite borrar la tabla y liberar el espacio físico que ocupaba. Si no se encuentra esta cláusula, la 
tabla se borra lógicamente pero no físicamente. Esto permite utilizar la instrucción FLASHBACK TABLE para recuperar 
la tabla y sus datos en el momento del borrado. 

Con  este  principio  de  funcionamiento,  Oracle  permite  dejar  de  hacer  definitiva  una  acción  de  eliminación  de  una 
tabla y facilita así la restauración de las tablas suprimidas por error. 

Sintaxis 

DROP TABLE nombre [CASCADE CONSTRAINTS] [PURGE];

- 12 - © Éditions ENI – Todos los derechos reservados


Ejemplo 

Eliminación de la tabla CLIENTES cuya columna NUMCLI es una clave externa en la tabla PEDIDOS: 

SQL>drop table CLIENTES;


drop table CLIENTES
*
ERROR en línea 1:
ORA-02449: claves únicas/primarias en la tabla referidas por claves ajenas

SQL>drop table CLIENTES cascade constraints;

Tabla borrada.

Borrado de la tabla de CLIENTES con petición de liberación del espacio físico: 

SQL> drop table CLIENTES cascade constraints purge;

Table dropped.

SQL>

4. Modificación de una tabla

Es posible modificar la estructura de una tabla en varios niveles: 

l añadiendo columnas (nombre, tipo, valor predeterminado, restricción NOT NULL),

l añadiendo restricciones de columna (únicamente la restricción NOT NULL),

l añadiendo restricciones de tabla,

l definiendo de nuevo una columna (tipo, valor predeterminado y visibilidad),

l activando o desactivando restricciones de columna o de tabla,

l eliminando restricciones de columna o de tabla,

l cambiando el nombre de la tabla,

l autorizando o no las modificaciones en la tabla.

a. Adición o modificación de columnas

Sintaxis

ALTER TABLE nombre {ADD/MODIFY} ([columna tipo [visibilidad] [defecto]


[restricción, ...])

Ejemplo

SQL> describe CLIENTES

© Éditions ENI – Todos los derechos reservados - 13 -


Nombre Nulo? Tipo
----------------------------------------- -------- -------------
NUMCLI NOT NULL NUMBER(4)
NOMCLI NOT NULL VARCHAR2(30)
DIRECCLI VARCHAR2(60)
COD_POSTAL NUMBER(5)
CIUDAD CHAR(30)

SQL> alter table CLIENTES add (TEL char(14));

Tabla modificada.

SQL> alter table CLIENTES modify (DIRECCLI char(30));

Tabla modificada.
SQL> describe CLIENTES
Nombre Nulo? Tipo
----------------------------------------- -------- ------------
NUMCLI NOT NULL NUMBER(4)
NOMCLI NOT NULL VARCHAR2(30)
DIRECCLI CHAR(30)
COD_POSTAL NUMBER(5)
CIUDAD CHAR(30)
TEL CHAR(14)
SQL>
SQL> alter table CATEGORIAS add (RESPONSABLE varchar2(30)
invisible default ’Ángel’);

Tabla modificada.

También  es  posible  añadir  o  modificar  una  columna  virtual  usando  la  misma  sintaxis  que  para  la  creación  de  la 
tabla. 

Ejemplo 

SQL> alter table ARTICULOS add


2 ( PRECIO_NETO number(8,2) AS ( PRECIO_BRUTO + round(PRECIO_BRUTO *
iva/100,2) ) );

Tabla modificada.

SQL> alter table ARTICULOS modify


2 ( PRECIO_NETO AS ( PRECIO_BRUTO + round(PRECIO_BRUTO * IVA/100,2) ) );

Tabla modificada.

De  la  misma  manera,  es  posible  añadir  o  modificar  una  columna  de  tipo  identidad  usando  la  misma  sintaxis  que 
para  la  creación  de  la  tabla,  y  eliminar  la  propiedad  de  tipo  identidad  de  una  columna.  Por  el  contrario,  no  es 
posible añadir la propiedad de tipo identidad a una columna existente. 

Ejemplo 

- 14 - © Éditions ENI – Todos los derechos reservados


SQL> alter table CATEGORIAS modify
2 (NOCAT generated by default on null as identity);

Tabla modificada.

SQL> alter table CATEGORIAS modify (NOCAT drop identity);

Tabla modificada.

b. Adición de una restricción de tabla

Sintaxis

ALTER TABLE nombre_tabla ADD[CONSTRAINT nombre] restricción

La sintaxis de declaración de restricciones es idéntica a la que se utiliza para crear una tabla.

Ejemplo

El siguiente ejemplo permite añadir una restricción de validación a la tabla ARTICULOS:

SQL> alter table ARTICULOS


2 add constraint ARTICULOS_PRECIO_CK check (PRECIO >= 0);

Tabla modificada.

SQL>

Es posible definir una restricción de tipo NOT NULL mediante el comando ALTER TABLE. 

Si los datos ya existen en la tabla en el momento en que se añade la restricción de integridad, entonces todas las 
filas de información deben verificar la restricción. En caso contrario, no se aplica la restricción a la tabla. 

La cláusula EXCEPTION INTO TABLE nombre_tabla permite conocer el rowid (identificador de fila de Oracle) de las 
filas  que  no  cumplen  la  restricción  de  integridad  que  se  intenta  aplicar  o  reactivar.  Así,  el  problema  se  puede 
corregir fácilmente. 

La  tabla  en  la  que  se  almacenarán  las  referencias  de  las  filas  que  impiden  la  creación  de  la  restricción  de 
integridad puede crearse mediante el script utlexcpt.sql (uso del identificador de fila físico) o utlexpt1.sql (uso del 
identificador de fila universal) almacenado en el directorio ORACLE_HOME\ rdbms\admin. 

Creación de la tabla de excepciones: 

SQL> create table excepciones(row_id rowid,


2 owner varchar2(30),
3 table_name varchar2(30),
4 constraint varchar2(30));

Tabla creada.

© Éditions ENI – Todos los derechos reservados - 15 -


SQL>

Incluye en la tabla de excepciones las referencias de las filas que plantean problemas. 

El siguiente fragmento de código intenta añadir una restricción de unicidad (UNIQUE) a la dirección de los clientes: 

SQL> alter table clientes


2 add constraint cli_direccli_un unique(direccli)
3 exceptions into excepciones;
add constraint cli_direccli_un unique(direccli)
*
ERROR en línea 2:
ORA-02299: no se puede validar (SCOTT.CLI_DIRECCLI_UN) - se han
encontrado claves duplicadas

SQL>

Ahora es necesario emplear los identificadores de fila para saber qué filas impiden añadir la restricción. 

El siguiente fragmento de código enumera los números de cliente que poseen la misma dirección: 

SQL> select numcli, direccli


2 from clientes, excepciones
3 where clientes.rowid=excepciones.row_id
4 and excepciones.table_name=’CLIENTES’
5 and excepciones.constraint=’CLI_DIRECCLI_UN’
6 ;

NUMCLI DIRECCLI
---------- ------------------------------
152 C/ Portugal,26
100 C/ Portugal,26

SQL>

Añadir una restricción sobre las tablas existentes es un método práctico porque, asociado a la creación de tablas, 
permite producir scripts de creación de tablas sin fijar un orden de creación que tenga en cuenta las restricciones 
de clave externa y de clave primaria. 

- 16 - © Éditions ENI – Todos los derechos reservados


c. Eliminación de una restricción

Sintaxis

ALTER TABLE nombre_tabla DROP{PRIMARY KEY/UNIQUE (columna)/CONSTRAINT} nombre

Ejemplo

SQL> alter table ARTICULOS


2 drop constraint ARTICULOS_PRECIO_CK;

Tabla modificada.

SQL>

d. Activación y desactivación de una restricción

El  comando  ALTER  TABLE  también  permite  activar  y  desactivar  las  restricciones  de  integridad.  Esta  operación
puede resultar interesante al realizar una importación masiva de datos con el fin de, por ejemplo, limitar el tiempo
necesario para llevar a cabo dicha importación.

Sintaxis

ALTER TABLE nombre_tabla {ENABLE VALIDATE/ENABLE NOVALIDATE/DISABLE} nombre_restricción

ENABLE VALIDATE

Activa la restricción si el conjunto de filas ya presentes en la tabla la cumplen. 

ENABLE NOVALIDATE 

Activa la restricción para las siguientes instrucciones de manipulación de datos (no verifica los datos 
actuales). 

DISABLE 

Desactiva la restricción. 

También  es  posible  trabajar  con  restricciones  de  clave  primaria  y  UNIQUE  proporcionando  simplemente  la 
definición de la restricción. 

Ejemplo 

En este ejemplo se desactiva la restricción sobre la columna COD_POSTAL de la tabla CLIENTES, se inserta en dicha tabla un 
valor  incompatible  con  la  restricción  desactivada  y  se  intenta  habilitar  de  nuevo  la  restricción  de  comprobación  (CHECK), 
validando los datos presentes en la tabla. 

SQL> alter table CLIENTES


2 disable constraint CLIENTES_COD_POSTAL_CK;

© Éditions ENI – Todos los derechos reservados - 17 -


Tabla modificada.

SQL> insert into CLIENTES (NUMCLI, NOMCLI, COD_POSTAL, CIUDAD)


2 values (128, ’Martín P.’, 999, ’ORENSE’);
1 fila creada.

SQL> alter table CLIENTES


2 enable validate constraint CLIENTES_COD_POSTAL_CK;
alter table CLIENTES
*

ERROR en línea 2:
ORA-02293: no se puede validar
[CLIENTES_COD_POSTAL_CK] - restricción de control violada

SQL>

e. Modificación de una restricción

No  es  posible  modificar  la  definición  de  una  restricción.  Sin  embargo,  sí  es  posible  modificar  el  estado  de  una
restricción.

Sintaxis

ALTER TABLE nombre_tabla MODIFY CONSTRAINT nombre_restricción


estado_restricción;

Los posibles estados de una restricción son los siguientes:

DEFERRABLE

La validación de la restricción puede realizarse al finalizar la transacción. 

NOT DEFERRABLE  

La restricción se verifica al completar cada instrucción DML. Esta opción está activada de manera 
predeterminada. 

INITIALLY IMMEDIATE 

En cada nueva transacción, el funcionamiento predeterminado consiste en verificar la restricción al 
completar cada instrucción DML. Esta opción está seleccionada de modo predeterminado. 

INITIALLY DEFERRED 

Implica que la restricción está en modo DEFERRABLE y que, de manera predeterminada, esta 
restricción se verifique únicamente al completarse la transacción. 

RELY o NORELY 

El valor RELY permite indicar que Oracle puede tener en cuenta una restricción en modo NOVALIDATE, 

- 18 - © Éditions ENI – Todos los derechos reservados


para la reescritura de una consulta (query rewrite). El valor por defecto es NORELY. 

USING INDEX 

Permite especificar los parámetros de los índices utilizados para establecer las restricciones de clave 
primaria y de unicidad. 

Ejemplo 

Modificación de la restricción de referencia entre las tablas LINEASPED y PEDIDOS: 

SQL> alter table LINEASPED


2 modify constraint FK_LINEASPED_PEDIDOS DEFERRABLE
3 ;

Tabla modificada.

SQL>

f. Eliminación de columnas

Se puede eliminar una columna utilizando la cláusula DROP COLUMN de la instrucción ALTER TABLE. Esta operación
permite recuperar el espacio en disco ocupado por cada columna eliminada.

Sintaxis

ALTER TABLE nombre_tabla DROP COLUMN nombre_columna;

ALTER TABLE nombre_tabla DROP (nombre_columna, nombre_columna[,...]);

Ejemplo

Eliminación de la columna TEL en la tabla CLIENTES:

SQL> alter table CLIENTES


2 drop column TEL;

Tabla modificada.

SQL>

Eliminar columnas en una tabla que posea muchas filas puede resultar una operación muy larga. En ocasiones, es 
más  adecuado  hacer  simplemente  que  la  columna  no  pueda  utilizarse,  mediante  la  cláusula  SET  UNUSED.  Esta 
opción  no  permite  liberar  el  espacio  en  disco  ocupado  por  la  columna,  pero  sí  permite  planificar  la  operación  de 
eliminación de la columna para el momento en que la carga de trabajo en el servidor sea menor. 

Sintaxis 

© Éditions ENI – Todos los derechos reservados - 19 -


ALTER TABLE nombre_tabla SET UNUSED (nombre_columna[,...]);
ALTER TABLE nombre_tabla DROP UNUSED COLUMNS [CHECKPOINT num_filas];

Ejemplo 

Convertir la columna TEL de la tabla CLIENTES en una columna no utilizable. Para ello, primero se marca la columna como no 
utilizable. 

SQL> alter table CLIENTES set unused (TEL);

Tabla modificada.

SQL>

A continuación se eliminan todas las columnas marcadas como no utilizables de la tabla CLIENTES. Después de esta operación 
se  pide  al  sistema  que  establezca  un  punto  de  sincronización  (CHECKPOINT)  cada  200  eliminaciones.  Esta  precaución  evita 
saturar la caché del búfer (o buffer) de datos con los datos que se van a eliminar y permite realizar escrituras en disco más a 
menudo. 

SQL> alter table CLIENTES drop unused columns checkpoint 200;

Tabla modificada.

SQL>

Para saber qué tablas contienen columnas que no se pueden utilizar, es necesario consultar la vista del diccionario 
de datos denominada USER_UNUSED_COL_TABS. 

SQL> select * from dba_unused_col_tabs;

OWNER TABLE_NAME COUNT


--------------------------- ------------------------------ ----------
SCOTT CLIENTES 1

SQL>

g. Cómo cambiar el nombre de una tabla

La  instrucción  RENAME  permite  cambiar  el  nombre  de  una  tabla,  así  como  de  las  vistas,  secuencias  y  sinónimos
privados.

Los sinónimos públicos no pueden cambiar de nombre; deben eliminarse y crearse de nuevo. 

Sintaxis 

RENAME nombre_antiguo TO nombre_nuevo;

- 20 - © Éditions ENI – Todos los derechos reservados


Ejemplo 

Cambiar el nombre de la tabla ARTICULOS por PRODUCTOS: 

SQL> rename ARTICULOS to PRODUCTOS;

Tabla cambiada de nombre.

SQL>

h. Hacer una tabla accesible sólo en modo lectura, o en modo lectura y escritura

A partir de la versión 11, es posible hacer una tabla accesible únicamente en modo lectura para impedir cualquier
modificación de datos en la tabla y posteriormente hacerla de nuevo accesible en modo lectura y escritura.

Sintaxis

ALTER TABLE nombre_tabla { READ ONLY / READ WRITE }

Ejemplo

SQL> alter table ARTICULOS read only;

Tabla modificada.

SQL> delete from ARTICULOS;


delete from ARTICULOS
*
Error en la línea 1:
ORA-12081: operación de actualización no permitida para
la tabla "HELIOS"."ARTICULOS"

SQL> update ARTICULOS set DESCRIPCION = upper(DESCRIPCION);


update ARTICULOS set DESCRIPCION = upper(DESCRIPCION)
*
Error en la línea 1:
ORA-12081: operación de actualización no permitida para
la tabla "HELIOS"."ARTICULOS"

SQL> alter table ARTICULOS read write;

Tabla modificada.

SQL> delete from ARTICULOS;

2 registro(s) eliminado(s).

La estructura de una tabla en modo de solo lectura no puede modificarse (agregar, modificar o eliminar columnas). 
En cambio, una tabla en modo de solo lectura puede eliminarse (DROP TABLE). 

© Éditions ENI – Todos los derechos reservados - 21 -


5. Restauración de una tabla

La instrucción FLASHBACK TABLE permite restaurar de forma automática una tabla modificada de forma accidental. El 
lapso de tiempo durante el que es posible volver a la versión anterior de la tabla es función del espacio de anulación 
reservado por la base de datos. 

No es posible incluir esta operación en una transacción. 

Oracle no puede ejecutar la instrucción FLASHBACK TABLE si se ha realizado una modificación de la estructura en la 
tabla. 

Esta instrucción permite anular el borrado de una tabla efectuado con la instrucción DROP TABLE. 

Sintaxis 

FLASHBACK TABLE nombreTabla TO BEFORE DROP;

Ejemplo 

En el ejemplo siguiente, la tabla linped se borra por error y se restaura mediante la acción de la instrucción FLASHBACK TABLE: 

SQL> drop table linped;

Table dropped.

SQL> desc linped


ERROR:
ORA-04043: object linped does not exist

SQL> flashback table linped to before drop;

Flashback complete.

SQL> desc linped


Name Null? Type
-------------------------- ----------------- -----------------------
NUMPED NOT NULL NUMBER(6)
NUMLIN NOT NULL NUMBER(2)
REFART CHAR(4)
CANTPED NUMBER(5)

SQL>

La instrucción FLASHBACK TABLE permite anular las modificaciones efectuadas por las instrucciones INSERT, UPDATE 
o DELETE  en  una  tabla.  Es  posible  incluso  restaurar  los  datos  de  una  o  más  tablas  hasta  una  fecha  y  hora
concretas.

Para poder aprovechar esta funcionalidad, la tabla debe estar configurada para tener en cuenta los movimientos de 
filas en la tabla. Es posible activar esta opción al crear la tabla, utilizando la cláusula  enable row movement, o 
bien al modificar la tabla. 

- 22 - © Éditions ENI – Todos los derechos reservados


Sintaxis 

CREATE TABLE nombretabla (...) ENABLE ROW MOVEMENT;


ALTER TABLE nombretabla ENABLE ROW MOVEMENT;
FLASHBACK TABLE nombretabla TO_TIMESTAMP fechaHora;

Ejemplo 

Activar el soporte para el movimiento de filas en la tabla de clientes: 

SQL> alter table clientes


2 enable row movement;

Table altered.

SQL>

En el ejemplo siguiente, los clientes cuyo nombre empieza por E se han borrado por error. La transacción ahora se valida y los 
datos modificados son visibles para todos los usuarios. 

SQL> delete from clientes where nomcli like ’E%’;

2 rows deleted.

SQL> commit;

Commit complete.

SQL>

Afortunadamente, el usuario ha anotado la hora en la que se ha ejecutado esta operación equivocada. De este modo, es posible 
restaurar los datos borrados sin tener que hacer una restauración completa de la base de datos. 

SQL> select count(*) from clientes;


COUNT(*)
----------------
5

SQL> flashback table clientes


2 to timestamp
3 to_timestamp(’28/07/2004 19:06:00’,’DD/MM/YYYY HH24:MI:SS’);

flashback complete.

SQL> select count(*) from clientes;

COUNT(*)
---------------
7

© Éditions ENI – Todos los derechos reservados - 23 -


SQL>

Generalmente existe a nivel de la base de datos la instrucción FLASHBACK DATABASE. 

6. Gestion de índices

Los  índices  sirven  para  mejorar  el  rendimiento  de  las  consultas.  El  optimizador  de  consultas  de  Oracle  los  utiliza 
implícitamente y se actualizan de forma automática al actualizar las filas. 

En  general,  los  índices  se  crean  sobre  todas  las  claves  externas  y  sobre  los  criterios  de  búsqueda  actuales.  Es 
posible indexar una columna virtual o invisible. 

Los  índices  que  afectan  a  las  claves  primarias  y  secundarias  (índice  UNIQUE)  se  crean  automáticamente  en  el 
momento  de  la  creación  de  la  restricción,  utilizando  como  nombre  el  nombre  de  la  restricción.  Para  crear  otros 
índices hay que utilizar la instrucción CREATE INDEX. 

El establecimiento de restricciones de clave primaria y de unicidad lleva aparejada la creación implícita de un índice. 

a. Creación de un índice

Sintaxis

CREATE INDEX nombre ON tabla (columna [DESC] [, ...]);

Ejemplos

Creación de un índice sobre la clave externa REFART de la tabla LINEASPED:

SQL>create index FK_LINART on LINEASPED(REFART);

Índice creado.

Creación  de  un  índice  sobre  la  tabla  CLIVARIOS  utilizando  las  columnas  NOMCLIENTE  y  DIRECCION  (criterio  de  búsqueda) 
concatenadas. 

SQL>create index IK_CLID on CLIVARIOS (NOMCLIENTE, DIRECCION);

Índice creado.

b. Eliminación de un índice

Sintaxis

DROP INDEX nombre;

Existen índices de diferentes tipos que tienen una incidencia directa sobre la organización física de los datos y estas 

- 24 - © Éditions ENI – Todos los derechos reservados


opciones incumben a la administración. 

© Éditions ENI – Todos los derechos reservados - 25 -


Manipulación de los datos

Las instrucciones DML permiten añadir, eliminar, modificar y visualizar las filas contenidas en las tablas existentes. 

1. Instrucciones

Las  instrucciones  SQL  manipulan  expresiones.  Estas  expresiones  hacen  referencia  a  constantes  y  nombres  de 
objetos de la base de datos, realizan llamadas a funciones estándar y establecen relaciones entre estos elementos 
mediante el uso de operadores. 

Las expresiones lógicas (condiciones) también permiten definir el ámbito de las instrucciones. 

a. Expresiones

Los términos de las expresiones pueden ser:

l constantes de caracteres
ejemplo: ’cadena de caracteres’; ’Escuela de Informática’.

l constantes literales de fecha (el formato depende del idioma que se haya configurado para la instancia)
ejemplo: ’15­JAN­94’

l constantes numéricas
ejemplo: 10; ­123.459; ­1.26e+6

l nombres de atributos de tabla
ejemplo: CLIENTES.NUMCLI; ARTICULOS.DESCRIPCION

l funciones
ejemplo: SQRT(81); REPLACE(’IAGADIGI’, ’I’, ’OU’); SYSDATE

l pseudo­columnas
ejemplo: nombresecuencia.NEXTVAL; ROWID.

b. Operadores

l Aritméticos  + ­ / * ( )
ejemplo: 1.15 * PRECIO; (2 * IMPLIN)/5; SYSDATE +15

l Sobre cadenas de caracteres: concatenación: ||
ejemplo: ’Señor’|| NOMBRE

c. Condiciones

Las condiciones emplean expresiones, operadores de comparación y operadores lógicos.

Operadores de comparación

El valor de las expresiones lógicas puede ser VERDADERO, FALSO o DESCONOCIDO. Una comparación se evaluará
como DESCONOCIDO si al menos uno de los términos es NULL.

© Éditions ENI – Todos los derechos reservados - 1-


l Comparación simple
expresión1 {=,!=,<>, <,<=, >, >=} expresión2

l Pertenencia a un conjunto de valores
expresión1 IN (expresión2,...)
VERDADERO si expresión1 aparece al menos una vez en la lista (expresión2, ...).

l Pertenencia a un intervalo de valores
expresión1 BETWEEN expresión2 AND expresión3
VERDADERO si expresión1 se encuentra entre los valores límite determinados por expresión2 y expresión3, ambos 
inclusive.

l Comparación con un formato de cadena de caracteres.
expresión1 LIKE ’formato’
El formato puede incluir los metacaracteres:

n ­ "%" para designar una serie de 0 a n caracteres

n ­ "_" para designar un único carácter.

Operadores lógicos 

Una expresión NULL no es ni VERDADERA ni FALSA. 

l Negación de una expresión lógica
NOT expresión

l Combinación de expresiones lógicas
expresión1 { AND / OR } expresión2

d. Funciones

Existen dos tipos de funciones:

l Las funciones escalares (scalar function) que se aplican a una sola fila: la función se ejecuta y devuelve un resultado 
para cada fila de la consulta.

l Las funciones sobre una agrupación de filas (group function): la función se ejecuta una vez y devuelve un resultado 
para un grupo de filas de la consulta. Estas funciones se denominan funciones de agregación.

Si se llama a una función utilizando un argumento NULL, el valor devuelto es NULL. Esta regla se aplica a todas las 
funciones excepto a CONCAT, NVL y REPLACE, y las funciones de agregación. 

Notación de los argumentos de las funciones: 

n: expresión numérica. 

d: expresión de fecha. 

c: expresión de caracteres. 

b: expresión lógica.  

- 2- © Éditions ENI – Todos los derechos reservados


Funciones escalares matemáticas 

ABS (n) 

Valor absoluto de n. 

CEIL (n) 

Primer entero mayor o igual que n. 

COS (n) 

Coseno. 

COSH (n) 

Coseno hiperbólico. 

EXP (n) 

e elevado a la potencia n (e=2,71828183...). 

FLOOR (n) 

Primer entero menor o igual que n. 

LN (n) 

Logaritmo neperiano de n. 

LOG (m,n) 

Logaritmo de n en base m. 

MOD (n1,n2) 

Resto del cociente de n1/n2. 

POWER (n1,n2) 

n1 elevado a n2. 

ROUND (n1,[n2]) 

n1 redondeado a n2 posiciones decimales. 

SIGN (n) 

­1 si n< 0; 0 si n=0; +1 si n>0. 

SIN (n) 

© Éditions ENI – Todos los derechos reservados - 3-


Seno de n. 

SINH (n) 

Seno hiperbólico de n. 

SQRT (n) 

Raíz cuadrada de n. 

TAN (n) 

Tangente de n. 

TANH (n) 

Tangente hiperbólica de n. 

TRUNC (n1,[n2]) 

n1 truncado a n2 posiciones decimales. 

La  mayor  parte  de  las  funciones  numéricas  devuelven  un  valor  con  38 cifras  significativas.  No  obstante,  las 
funciones  COS,  COSH,  EXP,  LN,  LOG,  SIN,  SINH,  SQRT,  TAN  y  TANH  devuelven  un  valor  con  solo  36 cifras 
significativas. 

Funciones escalares para cadenas de caracteres 

ASCII (c) 

Código ASCII del primer carácter de c. 

ASCIISTR (c) 

La cadena de caracteres que se pasa como parámetro se convierte al formato de la tabla ASCII de la 
base de datos. 

CHR (n) 

Carácter ASCII correspondiente al código n. 

COMPOSE (c) 

La cadena de caracteres que se pasa como parámetro se convierte a formato UNICODE. 

CONCAT (c1, c2) 

Concatenación de c1 y c2. 

DECOMPOSE (c) 

- 4- © Éditions ENI – Todos los derechos reservados


Esta función es valida únicamente para cadenas en formato UNICODE. Devuelve una cadena que 
contiene los diferentes caracteres introducidos. 

INITCAP (c) 

Devuelve c con la primera letra de cada palabra en mayúscula y las restantes en minúsculas. 

INSTR (c1,c2[,n1[n2]]) 

Posición de la enésima aparición de c2 en c1 (la primera aparición es la opción predeterminada) a 
partir de la posición n1 (1 es el valor predeterminado). 

INSTRB (c1,c2,n1[,n2]) 

Igual que INSTR con n1 y n2 en bytes. 

LENGTH (c) 

Número de caracteres de c. 

LENGTHB (c) 

Igual que LENGTH, pero devuelve el número de bytes. 

LOWER (c) 

Devuelve c en minúsculas. 

LPAD (c1,n[,c2]) 

Devuelve c1 con una longitud total n que se obtiene añadiendo a la izquierda c2 (que por omisión es 
un espacio, ’ ’). 

LTRIM (c1[,c2]) 

Devuelve c1 suprimiendo por la izquierda c2 (por omisión, ’ ’). 

NLS_INITCAP (c,’param’) 

Idéntica a INITCAP teniendo en cuenta param (código del país). 

NLS_LOWER (c,’param’) 

Idéntica a LOWER teniendo en cuenta param (código del país). 

NLSSORT (c) 

Secuencia de bytes para ordenar la cadena c. 

NLS_UPPER (c,’param’) 

Idéntica a UPPER teniendo en cuenta param (código del país). 

© Éditions ENI – Todos los derechos reservados - 5-


REPLACE (c1,c2,c3) 

Reemplaza en c1 todas las apariciones de c2 por c3 (c3 puede ser una cadena nula). 

RPAD (c1,n[,c2]) 

Devuelve c1 con una longitud total n que se obtiene añadiendo a la derecha c2 (que por omisión es 
un espacio, ’ ’). 

RTRIM (c1[,c2]) 

Devuelve c1 suprimiendo por la derecha c2 (por omisión, ’ ’). 

SOUNDEX (c) 

Representación fonética de c. 

SUBSTR (c,n1[,n2]) 

Devuelve una cadena formada por n2 caracteres de c a partir de la posición n1. 

SUBSTRB (c,n1[,n2]) 

Idéntica a SUBSTR con n1 y n2 en bytes. 

TRANSLATE (c1,c2,c3) 

Reemplaza en c1 todas las apariciones de c2 por c3 (c3 no puede ser una cadena de caracteres 
nula). 

TRIM ({{LEADING |TRAILING|BOTH c1} | {c1}} FROM c2 ) 

El carácter c1 se suprime de la cadena c2 bien a partir del principio de la cadena (LEADING), bien del 
final de la cadena (TRAILING), o de ambas posiciones (BOTH, o ninguna palabra clave). 

UNISTR (c) 

La cadena de caracteres que se pasa como parámetro se convierte a formato Unicode. 

UPPER(c) 

Devuelve c en mayúsculas. 

Funciones escalares para fechas 

ADD_MONTHS (d,n) 

Suma n meses a la fecha d (n puede ser negativo). 

CURRENT_DATE 

- 6- © Éditions ENI – Todos los derechos reservados


Proporciona la fecha y la hora actuales teniendo en cuenta la configuración de zona horaria 
(TIME_ZONE) de la sesión. 

CURRENT_TIMESTAMP 

Proporciona la fecha y la hora respecto de la zona horaria de la sesión. Esta función devuelve un 
valor de tipo TIMESTAMP WITH TIME ZONE. 

DBTIMEZONE 

Permite conocer la zona horaria en vigor en la base de datos. 

EXTRACT (formato FROM d) 

Extrae un elemento (día, mes, año, hora, minutos, segundos...) de un elemento de tipo fecha o de un 
intervalo de tiempo calculado con la ayuda de las funciones NUMTODSINTERVAL o NUMTOYMINTERVAL. 

FROM_TZ (t, zona_horaria) 

Convierte un valor de tipo TIMESTAMP en un valor de tipo TIMESTAMP WITH TIME ZONE. 

LAST_DAY (d) 

Fecha del último día del mes indicado por la fecha d. 

LOCALTIMESTAMP 

Permite conocer la fecha y la hora actuales con respecto a la zona horaria de la sesión. Esta función 
devuelve un valor de tipo TIMESTAMP. 

MONTHS_BETWEEN (d1,d2) 

Proporciona la diferencia en meses entre dos fechas. 

NEW_TIME (d,z1,z2) 

La fecha d de la zona z1 se convierte en la fecha correspondiente en la zona z2. 

NEXT_DAY (d,j) 

Proporciona la fecha del siguiente día j que es posterior a la fecha d. 

NUMTODSINTERVAL (n,formato) 

Convierte el número n que se pasa como parámetro a formato de fecha. El segundo argumento 
representa la unidad en la que se expresa n. Los posibles valores son: ’DATE’, ’HOUR’, ’MINUTE’ y 
’SECOND’. 

NUMTOYMINTERVAL (n, formato) 

Convierte el número n pasado como argumento a formato de mes, año. El formato especificado por el 

© Éditions ENI – Todos los derechos reservados - 7-


segundo parámetro permite precisar si el primer parámetro representa meses (’MONTH’) o años 
(’YEAR’). 

ROUND (d, formato) 

Redondea la fecha d a la unidad especificada por formato (Año, Mes, Día, Hora...). 

SESSIONTIMEZONE 

Permite conocer la zona horaria activa en la sesión actual. 

SYSDATE 

Fecha del sistema. 

SYS_EXTRACT_UTC (d) 

Convierte una fecha y hora de una zona horaria determinada en una fecha y hora en formato UTC 
(Universal Time Coordinate), es decir, la hora de Greenwich. 

SYSTIMESTAMP 

Permite conocer la fecha y la hora, incluyendo las fracciones de segundo, basándose en la zona 
horaria configurada en el servidor de base de datos. 

TRUNC (d, formato) 

Trunca la fecha d comenzando por el elemento especificado en formato (Año, Mes, Día, Hora...). 

TZ_OFFSET (zona|formato) 

Permite conocer la zona horaria correspondiente a la zona que se pasa como parámetro. 

Las funciones de conversión (TO_CHAR, TO_DATE) y las funciones que manipulan fechas (TRUNC, ROUND) utilizan 
los  formatos  de  fecha.  En  la  siguiente  tabla  se  resumen  los  principales  indicadores  de  formato  de  fecha  que 
pueden emplearse. 

­ / ’ . ;:’texto’  Elementos de separación presentes en el resultado. 

D  Número  de  día  de  la  semana  (1  a  7).  Este  indicador  se  usa  únicamente  con  la  función 
TO_DATE. 

DAY  Nombre del día de la semana. 

DD  Número de día del mes (1 a 31). 

DDD  Número de día del año (1 a 366). 

DY  Nombre abreviado del día de la semana. 

HH, HH12  Hora del día (1 a 12). 

HH24  Hora del día (0 a 23). 

IW  Número de la semana del año (1 a 53) según la norma ISO. 

MI  Minutos (0 a 59). 

MM  Número del mes usando 2 caracteres (1 a 12). 

- 8- © Éditions ENI – Todos los derechos reservados


MON  Nombre abreviado del mes. 

MONTH  Nombre del mes. 

Q  Número de trimestre (1 a 4). 

RM  Número de mes en números romanos (I a XII). 

SS  Segundos (0 a 59). 

SSSS  Número de segundos desde medianoche (0 a 86399). 

WW  Número  de  la  semana  del  año.  La  semana  número  1  comienza  el  primer  día  del  año  y 
dura siete días. 

W  Número  de  la  semana  en  el  mes  (1  a  5).  La  primera  semana  del  mes  comienza  el 
primer día del mes y dura siete días. 

YYYY  Año utilizando 4, 3, 2 o 1 cifras. 
YYY 
YY 

Funciones escalares de conversión 

BIN_TO_NUM (expr[, ...]) 

Convierte un conjunto de números binarios en su equivalente decimal. 

CHARTOROWID (char) 

Convierte una cadena de caracteres con la forma ’numbloque.numfila.numarch’ en el tipo de datos 
ROWID. Esta pseudo­columna representa la dirección física de la fila en la base de datos Oracle. 

CONVERT (char,dest[,source]) 

Conversión del juego de caracteres. 

source o dest 

US7ASCII (ASCII 7­bit American), WE8ISO8859P1 (ISO 8859­1 8­bit West European), WE8ISO8859P9 
(ISO 8859­9 8­bit West European & Turkish), WE8ISO8859P15 (ISO 8859­15 8­bit West European), 
WE8MSWIN1252 (MS Windows Code Page 1252 8­bit West European), WE8PC850 (IBM­PC Code 
Page 850 8­bit West European), AL32UTF8 (Unicode 6.2 UTF­8 Universal character set), UTF8 
(Unicode 3.0 UTF­8 Universal character set, CESU­8 compliant), AL16UTF16 (Unicode 6.2 UTF­16 
Universal character set), UTFE (EBCDIC form of Unicode 3.0 UTF­8 Universal character set). 

HEXTORAW (char) 

Convierte un valor hexadecimal contenido en una cadena de caracteres en una expresión binaria de 
tipo RAW. 

RAWTOHEX (raw), RAWTONHEX (raw) 

Es la función inversa de la anterior. 

ROWIDTOCHAR (rowid), ROWIDTONCHAR (rowid) 

© Éditions ENI – Todos los derechos reservados - 9-


Función inversa de CHARTOROWID. 

TO_CHAR (carácter) 

Convierte una cadena de caracteres al formato NCHAR, NVARCHAR2, CLOB o NCLOB de la tabla de 
caracteres utilizada en la base de datos. 

TO_CHAR (n,[formato[,’param’]]) 

Convierte datos numéricos en caracteres. 

formato: cadena de caracteres que representa el formato numérico (los posibles elementos de esta 
cadena de caracteres se encuentran en la tabla de formatos de fecha vista anteriormente). 

param: opciones nacionales. 

TO_CHAR (d, formato) 

Convierte una fecha en una cadena de caracteres. 

TO_CLOB (cadena) 

Convierte una cadena de caracteres o de tipo LOB al formato CLOB. 

TO_DATE (char, formato) 

Es la función inversa de TO_CHAR (conversión de cadenas de caracteres en fecha). 

TO_DSINTERVAL (cadena) 

Convierte una cadena de caracteres en datos de tipo INTERVAL TO DAY SECOND (intervalo 
día/segundo). 

TO_NCHAR (c) 

Convierte una cadena de caracteres en el juego de caracteres nacional (segundo juego de 
caracteres de la base de datos). 

TO_NCHAR (d,formato) 

Convierte una fecha en cadena en el juego de caracteres nacional. 

TO_NCHAR (n) 

Convierte un número en una cadena en el juego de caracteres nacional. 

TO_NCLOB (c) 

Convierte una cadena de caracteres en elementos de tipo NCLOB. 

TO_NUMBER (char) 

- 10 - © Éditions ENI – Todos los derechos reservados


Convierte una cadena de caracteres en un tipo de dato numérico. 

TO_TIMESTAMP (c[,formato]) 

Convierte una cadena de caracteres en un elemento de tipo TIMESTAMP basándose en el formato de 
fecha indicado por el segundo parámetro. 

TO_TIMESTAMP_TZ (c[,formato]) 

Convierte una cadena de caracteres en un elemento de tipo TIMESTAMP WITH TIME ZONE basándose 
en el formato de fecha indicado por el segundo parámetro. 

TO_YMINTERVAL (cadena) 

Convierte una cadena de caracteres en datos de tipo INTERVAL YEAR TO MONTH (intervalo mes/año). 

Ejemplo de uso de las funciones de conversión 

En  el  siguiente  ejemplo,  la  función  SYSDATE  permite  conocer  la  fecha  y  hora  actuales  y,  a  continuación,  estos  datos  se 
muestran adecuadamente en pantalla con ayuda de la función de conversión TO_CHAR. Para convertir la fecha en una cadena 
de caracteres se emplea un formato de conversión cuyos argumentos se proporcionan en la tabla anterior. 

SQL> select to_char(sysdate,’DAY DD MONTH YYYY HH24:MI:SS’) from dual;

TO_CHAR(SYSDATE,’DAYDDMONTHYYYYHH24:M
-------------------------------------
JUEVES 19 DICIEMBRE 2002 14:27:14

SQL>

Funciones de comparación 

NULLIF (expr1, expr2) 

Compara la expr1 con la expr2. Si ambas expresiones son iguales, entonces devuelve el valor NULL, 
en caso contrario devuelve la expr1. No se puede especificar el valor NULL para expr1. 

Funciones escalares diversas 

BITAND (arg1, arg2) 

Efectúa una operación AND entre los dos argumentos, bit a bit. 

COALESCE (expr,[,...]) 

Devuelve la primera expresión no nula que se pasa como parámetro. 

DECODE (columna, valor1, resul1 [,valor2, resul2...],[predeterminado]) 

Si columna tiene el valor especificado por valor1, el resultado será resul1. 

© Éditions ENI – Todos los derechos reservados - 11 -


DUMP (exp[,formato[,inicial[longitud]]]) 

Los posibles formatos son: 

8 (el resultado se expresa en octal), 

10 (el resultado se expresa en decimal), 

16 (el resultado se expresa en hexadecimal), 

17 (el resultado se expresa en forma de caracteres). 

Los argumentos inicial y longitud permiten especificar la parte de la cadena que hay que tratar. 

GREATEST (exp[,exp...]) 

Devuelve la expresión más grande. 

LEAST (exp[,exp......]) 

Devuelve la expresión más pequeña. 

NVL (exp1, exp2) 

Si exp1 es NULL, devuelve exp2. 

NVL2 (exp1, exp2, exp3) 

Si exp1 es NULL, entonces la función NVL2 devuelve la exp2; en caso contrario, devuelve exp3. Las 
expresiones 2 y 3 pueden ser cualquier tipo de datos, excepto el tipo LONG. 

UID 

Número identificador del usuario. 

USER 

Nombre del usuario. 

USERENV (opción) 

Devuelve características del entorno. 

opción: CLIENT_INFO ; ENTRYID ; ISDBA ; LANG ; LANGUAGE ; SESSIONID ; SID; TERMINAL. 

VSIZE (exp) 

Número de bytes almacenados para exp. 

WIDTH_BUCKET (expr, min, max, n) 

Crea n intervalos equivalentes en el rango comprendido entre min y max e indica en qué intervalo se 
encuentra cada expresión. 

- 12 - © Éditions ENI – Todos los derechos reservados


2. Creación de filas

La adición de una fila a una tabla se lleva a cabo si se cumplen las restricciones. Si no se especifican los nombres de 
las columnas a los que debe asignarse un valor, debe proporcionarse una expresión para cada columna en el orden 
en  que  se  han  definido  las  columnas  durante  la  creación  de  la  tabla.  No  se  puede  omitir  ninguna  columna,  a 
excepción de las columnas invisibles. 

Sintaxis 

INSERT INTO tabla [(columna ,...)] VALUES (expresión ,...);

Ejemplos 

Creación de un cliente (las columnas omitidas tienen valor NULL o son iguales a su valor por defecto): 

SQL> insert into CLIENTES (NUMCLI,NOMCLI)


2 values (37, ’Fco. LACALLE’);

1 fila creada.

SQL>

Asignación de valores a todas las columnas de un artículo: 

SQL> insert into ARTICULOS


2 values (’AB03’, ’Alfombras’, 150, 2, ’IMPORT’, 80);

1 fila creada.

SQL>

Asignación de valores a una fila de un pedido, con introducción de una variable mediante SQL*Plus (primera columna, consulte 
el capítulo dedicado a SQL*Plus) y una expresión para el cálculo de la cantidad (última columna): 

SQL> insert into LINPED


2 values (&NumPed, 1, ’AB10’, 2+6);
Introduzca un valor para numped: 1
antiguo 2: values (&NumPed, 1, ’AB10’, 2+6)
nuevo 2: values (1, 1, ’AB10’, 2+6)

1 fila creada.

SQL>

Para insertar un valor NULL en una columna es necesario completar todas las columnas para las que se dispone de 
un valor, usando la sintaxis indicada en los ejemplos anteriores (las restantes columnas tendrán el valor NULL). 

© Éditions ENI – Todos los derechos reservados - 13 -


Para utilizar el valor predeterminado de una columna en una inserción, es posible utilizar la palabra clave DEFAULT. 

SQL> insert into clientes (numcli, nomcli, dircli, cod_postal, pobl)


2 values (601,’Alberto’,’calle Pirineos’,DEFAULT, DEFAULT);

1 row created.

SQL>

La instrucción INSERT permite agregar una o más filas en la tabla de destino. 

Si bien la inserción de una fila de datos es el funcionamiento más frecuente, también es posible agregar varias filas 
en la tabla. Estas filas insertadas de forma masiva se extraen de la base de datos mediante una consulta de tipo 
SELECT. 

Este proceso facilita la transferencia de datos de una tabla a otra. 

Sintaxis 

INSERT INTO tabla[(columna), ...)] SELECT columna, ...


FROM tabla ...;

Ejemplo 

Extracción de la lista de clientes que habitan en Barcelona a una nueva tabla: 

SQL> create table cli4(


2 numcli number(6));

Table created.
SQL> insert into cli4 select numcli
2 from clientes where pobl=’BARCELONA’;

0 rows created.

SQL>

3. Eliminación de filas

Instrucción DELETE 

La  instrucción  DELETE  borra  todas  las  filas  de  una  tabla.  Si  se  emplea  la  cláusula  WHERE,  solo  se  borran  las  filas 
para las que la condición sea verdadera. 

Sintaxis 

DELETE FROM tabla [WHERE condición];

- 14 - © Éditions ENI – Todos los derechos reservados


Ejemplos  

Eliminación de un artículo: 

SQL> delete from ARTICULOS where REFART = ’ZZZZ’;

1 fila suprimida.

La  siguiente  instrucción  intenta  eliminar  los  artículos  que  cuestan  entre  1250  y  1750  euros.  Algunos  de  estos  artículos  están 
referenciados en otras tablas, lo que produce un error: 

SQL> delete from ARTICULOS


2 where PRECIO >1250 and PRECIO <1750;
delete from ARTICULOS
*
ERROR en línea 1:
ORA-02292: restricción de integridad (SCOTT.FK_LINPED_ARTICULOS)
violada - registro secundario encontrado

SQL>

Eliminación de las filas que hacen referencia a los artículos: 

SQL> delete from LINPED;

1 fila suprimida.

SQL>

La siguiente instrucción elimina los artículos que cuestan entre 1250 y 1750 euros (AB10, AB22): 

SQL> delete from ARTICULOS


2 where PRECIO between 1250 and 1750;

2 filas suprimidas.

SQL>

La siguiente instrucción elimina los artículos cuya descripción comienza por "Lo" (ZZ01): 

SQL> delete from ARTICULOS where DESCRIPCION like ’Lo%’;


1 fila suprimida.

La siguiente instrucción elimina los artículos cuya cantidad en almacén no tiene asignado un valor: 

SQL> delete from ARTICULOS where CANTALM is null;

© Éditions ENI – Todos los derechos reservados - 15 -


2 filas suprimidas.

Instrucción TRUNCATE 

La instrucción TRUNCATE permite eliminar todas las filas de una tabla y reactivar las condiciones de almacenamiento 
adoptadas al crear la tabla. 

Sintaxis 

TRUNCATE TABLE tabla

Ejemplo 

Eliminación de artículos: 

SQL> truncate table ARTICULOS;

Tabla truncada.

SQL>

4. Modificación de filas

En una tabla, la instrucción UPDATE permite reemplazar por expresiones el valor de las columnas especificadas. Si 
no  se  especifica  ninguna  cláusula  WHERE,  la  actualización  se  lleva  a  cabo  en  todas  las  filas  de  la  tabla.  En  caso 
contrario, solo se actualizarán aquellas filas que cumplan la condición especificada en la cláusula WHERE. 

Sintaxis 

UPDATE tabla SET columna = expresión, ... [WHERE condición];

Ejemplos 

Actualización de la cantidad disponible en almacén del artículo AB10, fijándola en 15: 

SQL>update ARTICULOS set CANTALM=15 where REFART=’AB10’;

1 fila actualizada.

Incremento de un 10% del precio de los artículos cuya referencia comienza por AB: 

SQL> update ARTICULOS


2 set PRECIO=PRECIO*1.1
3 where REFART like ’AB%’;

- 16 - © Éditions ENI – Todos los derechos reservados


4 filas actualizadas.

El siguiente ejemplo convierte a mayúsculas la descripción y elimina los espacios que haya al final de la referencia de todos los 
artículos: 

SQL>update ARTICULOS set DESCRIPCION=UPPER(DESCRIPCION),


2 REFART=rtrim(REFART);

8 filas actualizadas.

5. Extracción de datos

La instrucción SELECT permite presentar los datos de una tabla, vista o sinónimo. 

Sintaxis 

SELECT {* | expresión, ...} FROM tabla [WHERE condición];

* especifica que se muestren todas las columnas.

Ejemplo 

Visualización de la tabla ARTICULOS completa: 

SQL> select * from ARTICULOS;

Tabla inicial: 

SQL> select * from ARTICULOS;

REFA DESCRIPCION PRECIO CODIVA CATEGORIA CANTALM


---- ------------------------- --------- -------- ---------- --------
AB03 Alfombras 150 2 IMPORT 116
AB10 Alfombra china 1250,1 2 IMPORT 10
ZZ01 Lote alfombras 500 2 VARIOS 0
AA00 Regalo 0 VARIOS 8
CD50 Cadena HIFI 735,4 2 IMPORT 7
ZZZZ Cantimplora VARIOS 25
AB22 Alfombra persa 1500 2 IMPORT 5
AB Alfombra 2 REBAJ 2
8 filas seleccionadas.
SQL>

Referencias que tienen menos de 20 unidades en almacén: 

SQL> select REFART from ARTICULOS where CANTALM < 20;

© Éditions ENI – Todos los derechos reservados - 17 -


REFA
----
AB10
ZZ01
AA00
CD50
AB22
AB
6 filas seleccionadas.
SQL>

6. Control de transacciones

Una  transacción  es  un  conjunto  de  instrucciones  DML  (INSERT,  UPDATE,  DELETE)  que  se  ejecutan  entre  dos 
comandos CONNECT, COMMIT y ROLLBACK. 

La transacción permite asegurar que el conjunto de instrucciones incluidas en ella se ejecutará en su totalidad o no 
se ejecutará. 

En  un  instante  determinado  solo  estará  activa  una  transacción.  La  transacción  termina  cuando  se  ejecuta  una 
instrucción COMMIT o ROLLBACK. La primera instrucción DML que siga será el comienzo de una nueva transacción. 

Cada transacción también permite asegurar la coherencia de los datos vistos por cada usuario conectado al sistema 
de  gestión  de  bases  de  datos  (RDBMS).  Todas  las  modificaciones  realizadas  sobre  los  datos  durante  una 
transacción se efectúan respecto al estado de dichos datos al principio de la misma. Las modificaciones efectuadas 
sobre los datos por un usuario durante la transacción no serán visibles para los demás usuarios hasta después de 
llevar a cabo la validación (COMMIT) de esta transacción. 

a. Validación de transacciones

Las modificaciones de filas después de la última instrucción COMMIT o CONNECT se convierten en definitivas.

También es posible poner fin a una transacción con éxito ejecutando simplemente una instrucción del DDL, como
por ejemplo un comando CREATE, ALTER o DROP. En efecto, las instrucciones del DDL no pueden participar de la
transacción. La transacción en curso termina, por tanto, con éxito y, a continuación, se ejecuta la instrucción DDL y
empieza  una  nueva  transacción.  Esta  nueva  transacción  afectará  a  las  instrucciones  DML  siguientes.  Esta
validación  de  transacción  se  hace  de  forma  implícita  y  puede  ser  origen  de  errores  en  la  comprensión  del
mecanismo de las transacciones.

Sintaxis

COMMIT;

b. Anulación de modificaciones

Las modificaciones de filas realizadas después de la última instrucción COMMIT, CONNECT o SAVEPOINT se anulan.

Si la instrucción ROLLBACK especifica un punto de salvaguarda (SAVEPOINT), la transacción en curso sigue estando
activa después de la ejecución de la instrucción.

Sintaxis

- 18 - © Éditions ENI – Todos los derechos reservados


ROLLBACK [TO punto_grabación];

c. Declaración de un punto de control

Un punto de control permite memorizar el estado de los datos durante la transacción. La inclusión de un punto de
grabación  (SAVEPOINT)  permite  deshacer  las  modificaciones  realizadas  después  del  punto  de  grabación
establecido.

La transacción en curso seguirá estando activa después de establecer el punto de salvaguarda (SAVEPOINT).

Sintaxis

SAVEPOINT punto_grabación;

Ejemplo 

SQL> savepoint s1;

Punto de grabación creado.

SQL> select numcli, rtrim(nomcli), ciudad from clientes;

NUMCLI RTRIM(NOMCLI) CIUDAD


---------- ------------------------------ -----------------------------
138 Martín Juan MADRID
15 Gómez S.A. ORENSE
20 M. García TOLEDO
128 Martín P. ORENSE
152 LACALLE PONTEVEDRA
100 PLAZA S.A. PONTEVEDRA
35 Martín Juan ORENSE
36 Del Pino S.A. TOLEDO

8 filas seleccionadas.

SQL> delete from clientes where numcli>35;

5 filas suprimidas.

SQL> select numcli, rtrim(nomcli), ciudad from clientes;

NUMCLI RTRIM(NOMCLI) CIUDAD


---------- ------------------------------ -----------------------------
15 Gómez S.A. ORENSE
20 M. García TOLEDO
35 Martín Juan ORENSE

SQL> savepoint s2;

Punto de grabación creado.

SQL> insert into clientes (numcli, nomcli, ciudad)

© Éditions ENI – Todos los derechos reservados - 19 -


2 values (111, ’GASCÓN’, ’BARCELONA’);

1 fila creada.

SQL> select numcli, rtrim(nomcli), ciudad from clientes;

NUMCLI RTRIM(NOMCLI) CIUDAD


---------- ------------------------------ -----------------------------
15 Gómez S.A. ORENSE
20 M. García TOLEDO
35 Martín Juan ORENSE
111 GASCÓN BARCELONA

SQL> rollback to s2;

Rollback terminado.

SQL> select numcli, rtrim(nomcli), ciudad from clientes;

NUMCLI RTRIM(NOMCLI) CIUDAD


---------- ------------------------------ -----------------------------
15 Gómez S.A. ORENSE
20 M. García TOLEDO
35 Martín Juan ORENSE

SQL> rollback to s1;

Rollback terminado.

SQL> select numcli, rtrim (nomcli), ciudad from clientes;

NUMCLI RTRIM(NOMCLI) CIUDAD


---------- ------------------------------ -----------------------------
138 Martín Juan MADRID
15 Gómez S.A. ORENSE
20 M. García TOLEDO
128 Martín P. ORENSE
152 LACALLE PONTEVEDRA
100 PLAZA S.A. PONTEVEDRA
35 Martín Juan ORENSE
36 Del Pino S.A. TOLEDO

8 filas seleccionadas.

SQL> commit;

Validación terminada.

SQL>

d. Acceso simultáneo a los datos

Cuando varias transacciones acceden a los mismos datos (tablas), Oracle garantiza la coherencia de los datos de
la transacción respecto de los valores iniciales existentes al comienzo de la misma. Mientras una transacción no se

- 20 - © Éditions ENI – Todos los derechos reservados


valide  mediante  una  instrucción  COMMIT,  las  modificaciones  realizadas  en  los  datos  no  serán  visibles  para  los 
demás usuarios. 

Ejemplo 

Se  abren  dos  sesiones  (sesión  1  y  sesión  2)  con  el  mismo  nombre  de  usuario.  Sesión  1:  inserción  de  una  fila  en  la  tabla 
PEDIDOS. La fila insertada se ve en la transacción. 

SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC

SQL> insert into PEDIDOS (NUMPED, NUMCLI, FECHAPED, ESTADOPED)


2 values (2000, 35, SYSDATE, ’EC’);

1 fila creada.

SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC
2000 35 23/12/02 EC

SQL>

Sesión 2: en la sesión 1 no se ejecuta una instrucción COMMIT después de la operación de inserción. La fila insertada no es 
visible en la sesión 2. Se inserta una fila en la tabla PEDIDOS. 

SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC

SQL> insert into PEDIDOS (NUMPED, NUMCLI, FECHAPED, ESTADOPED)


2 values (2001, 15, SYSDATE, ’EC’);

1 fila creada.

SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

© Éditions ENI – Todos los derechos reservados - 21 -


NUMPED NUMCLI FECHAPED ES
---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC
2001 15 23/12/02 EC

SQL>

Sesión 1: COMMIT 

SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC
2000 35 23/12/02 EC

SQL> commit;

Validación terminada.
SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC
2000 35 23/12/02 EC

SQL>

Sesión 2: la fila insertada en la primera etapa de la transacción ahora es visible en la sesión 2. 

SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC
2000 35 23/12/02 EC
2001 15 23/12/02 EC

6 filas seleccionadas.

- 22 - © Éditions ENI – Todos los derechos reservados


SQL> commit;

Validación terminada.
SQL> select NUMPED, NUMCLI, FECHAPED, ESTADOPED from PEDIDOS;
NUMPED NUMCLI FECHAPED ES
---------- ---------- -------- -
1210 15 12/11/02 SE
1301 15 20/11/02 EC
1250 35 14/11/02 EC
1230 35 14/11/02 EC
2000 35 23/12/02 EC
2001 15 23/12/02 EC

6 filas seleccionadas.
SQL>

e. Verificación de las restricciones al final de la transacción

En ciertos casos puede ser necesario verificar las restricciones de integridad al final de la transacción. Para poder 
aprovechar esta funcionalidad es necesario precisar, al implementar la restricción de integridad, si su verificación 
se difiere hasta finalizar la transacción (INITIALLY DEFERRED) o bien si, por el contrario, es posible pedir en ciertos 
casos  la  validación  de  la  restricción  al  finalizar  la  transacción  (DEFERRABLE).  De  modo  predeterminado,  las 
restricciones  de  integridad  se  verifican  tras  la  inserción  de  los  valores  en  las  tablas  y  no  es  posible  mover  esta 
validación al final de la transacción. 

La sintaxis exacta de implementación de estos estados de restricción se explica en la sección Creación de una tabla 
­ Opciones de las restricciones de este capítulo. 

De este modo, en el ejemplo que se presenta a continuación, es necesario contar con una suscripción para poder 
ser miembro y cada suscripción debe estar en posesión de un único miembro. 

La  implementación  de  esta  relación  1­1  entre  las  2  tablas  se  efectuará  implementando  una  restricción  de 
referencia  entre  las  2  tablas.  Cada  caso  de  suscripción  referencia  un  único  caso  de  miembro  y  cada  caso  de 
miembro se refiere a un único caso de suscripción. 

Para este ejemplo es necesario agregar, en el transcurso de la misma transacción, un miembro y su suscripción y 
luego pedir la verificación de las restricciones de referencia al validar la transacción. 

Creación de tablas con las restricciones de clave primaria: 

SQL> create table suscripciones(


2 numero number(5),
3 miembro number(5),
4 constraint pk_suscripciones primary key(numero)
5 );

Table created.

SQL> create table miembros(


2 numero number(5),
3 apellido varchar2(40),
4 nombre varchar2(40),

© Éditions ENI – Todos los derechos reservados - 23 -


5 suscripcion number(5),
6 constraint pk_miembros primary key(numero)
7 );

Table created.

SQL>

Implementación de las restricciones de clave externa: 

SQL> alter table suscripciones


2 add constraint fk_suscripciones_miembros
3 foreign key(miembro)
4 references miembros(numero)
5 initially deferred;

Table altered;

SQL> alter table miembros


2 add constraint fk_miembros_suscripciones
3 foreign key(suscripcion)
4 references suscripciones(numero)
5 initially deferred;

Table altered.

SQL>

Inserción de datos: 

SQL> insert into suscripciones(numero, miembro)


2 values(1,100);

1 row created.

SQL> insert into miembros(numero, apellido, nombre, suscripcion)


2 values(100,’CASAS’,’Antonio’,1);

1 row created.

SQL> commit;

Commit complete.

SQL>

- 24 - © Éditions ENI – Todos los derechos reservados


Traducción del álgebra relacional

El método del álgebra relacional permite resolver extracciones de datos creando tablas intermedias mediante el uso 
de  operadores  (unión,  restricción,  combinación,  etc.).  Este  método  puede  traducirse  a  SQL  mediante  la  instrucción 
SELECT,  que  permite  llevar  a  cabo  todas  las  operaciones  mediante  sus  diferentes  cláusulas  (WHERE,  GROUP  BY, 
UNION, etc.), y mediante las instrucciones CREATE e INSERT, que permiten la gestión de las tablas intermedias. 

1. Operaciones

a. Restricción

La restricción permite extraer solo aquellas filas que cumplan una condición.

La operación   s (condición) se traduce de la siguiente manera:

SELECT * FROM S WHERE condición;

Ejemplo

Restricción sobre el número de pedido en la tabla PED =   PEDIDOS (NUMPED = 100):

SQL> select * from PEDIDOS where NUMPED=100;

NUMPED NUMCLI FECHAPED ES


---------- ---------- -------- -
100 15 18/11/02 EC

SQL>

b. Campos calculados elementales

Los campos calculados elementales permiten obtener columnas calculadas para cada fila. La operación  S (col, 
..., nvcol = exp) se traduce como:

SELECT col, ..., expresión FROM S;

Ejemplo 

Cálculo del valor del almacén   ARTICULOS(REFART, DESCRIPCION, VALALM = (PRECIOSINIVA * CANTALM))

SQL> select REFART, DESCRIPCION, (PRECIO * CANTALM) from ARTICULOS;

REFA DESCRIPCION (PRECIO*CANTALM)


---- ------------------------------ ---------------
ZZZZ CANTIMPLORA
ZZ01 LOTE ALFOMBRAS 0
AA00 REGALO 0
CD50 CADENA HIFI 5147,8
AB ALFOMBRA
AB10 Alfombra china 12501

© Éditions ENI – Todos los derechos reservados - 1-


AB03 Alfombras 17400
AB22 ALFOMBRA PERSA 7500

8 filas seleccionadas.

SQL>

c. Proyección

La  proyección  tiene  por  objetivo  eliminar  las  columnas  inútiles.  En  SQL,  esto  se  hace  enumerando  solo  aquellas
columnas deseadas en la instrucción SELECT.

Ejemplo

Simplificación de la tabla CLI =   CLIENTES (NUMCLI, NOMCLI):

SQL> SELECT NUMCLI, NOMCLI from CLIENTES;

Las proyecciones de agrupación se pueden efectuar con la ayuda de dos posibles sintaxis: 

SELECT DISTINCT {* | lista de columnas} FROM tabla;

SELECT lista de columnas FROM tabla GROUP BY lista de columnas;

La  primera  sintaxis  (DISTINCT)  permite  mostrar  solo  una  fila  en  el  caso  en  que  la  consulta  devuelva  varias  filas 
idénticas.  La  segunda  sintaxis  (GROUP  BY)  se  emplea  cuando  se  desea  realizar  una  proyección  de  grupo, 
calculando valores agregados sobre las filas agrupadas. 

La  palabra  clave  DISTINCT  solo  permite  mostrar  valores  diferentes,  mientras  que  la  palabra  clave  GROUP  BY 
efectúa  primero  una  agrupación.  Esta  operación  de  agrupación  hace  posible  calcular  valores  agregados  pero, 
lógicamente, precisa de más tiempo de procesador del servidor. 

Ejemplos 

Presentación de una fila por cada nombre de cliente: 

SQL> select NOMCLI from CLIENTES;

NOMCLI
------------------------------
Martín Juan
Gómez S.A.
M. García
Martín P.
LACALLE
PLAZA S.A.
Martín Juan

7 filas seleccionadas.

- 2- © Éditions ENI – Todos los derechos reservados


SQL> select distinct NOMCLI from CLIENTES;

NOMCLI
------------------------------
Gómez S.A.
LACALLE
M. García
Martín Juan
Martín P.
PLAZA S.A.
SQL> select NOMCLI from CLIENTES group by NOMCLI;

NOMCLI
------------------------------
Gómez S.A.
LACALLE
M. García
Martín Juan
Martín P.
PLAZA S.A.

SQL>

Agrupación por NOMCLI y CIUDAD: 

SQL> select NOMCLI, CIUDAD from CLIENTES group by NOMCLI, CIUDAD;

NOMCLI CIUDAD
------------------------------ ------------------------------
LACALLE PONTEVEDRA
M. García TOLEDO
Martín P. ORENSE
Gómez S.A. ORENSE
PLAZA S.A. PONTEVEDRA
Martín Juan MADRID
Martín Juan ORENSE

7 filas seleccionadas.

SQL>

d. Cálculo de valores agregados

Las proyecciones del cálculo de valores agregados permiten realizar cálculos estadísticos sobre las agrupaciones
especificadas mediante GROUP BY.

La operación   S (col, ..., nvcol = cálculo estadístico) se traduce de la siguiente manera:

SELECT lista de columnas, función de grupo FROM S GROUP BY


lista de columnas;

© Éditions ENI – Todos los derechos reservados - 3-


La  lista  de  columnas  proyectadas  (las  que  siguen  a  la  instrucción  SELECT)  tiene  que  ser  idéntica  a  la  lista  de 
columnas de agrupación (las que siguen a la cláusula GROUP BY). Los nombres de las columnas pueden aparecer 
en campos calculados elementales; en tal caso, la agrupación debe hacerse sobre las mismas expresiones. 

e. Funciones de grupo

coln

Columna numérica. 

col 

Columna de cualquier tipo. 

AVG (coln) 

Media de los valores de columna. 

COUNT ([DISTINCT] (columna) 

Para cada agrupación, número de filas agrupadas en las que la columna no tiene el valor NULL. Si la 
palabra DISTINCT no está presente, cuenta el número de valores distintos no NULL en la columna. 

APPROX_COUNT_DISTINCT (columna) 

Para cada agrupación, número aproximado de filas agrupadas que contienen valores distintos no 
NULL de columna. Esta funcionalidad apareció en la versión 12. 

COUNT (*) 

Para cada agrupación, número de filas agrupadas. 

MAX (columna) 

Valor máximo de columna para cada agrupación. 

MIN (columna) 

Valor mínimo de columna para cada agrupación. 

STDDEV (coln) 

Desviación típica de los valores de columna para cada agrupación. 

SUM (coln) 

Suma de los valores de columna para cada agrupación. 

VARIANCE (coln) 

Varianza de los valores de columna para cada agrupación. 

- 4- © Éditions ENI – Todos los derechos reservados


CORR (col1, col2) 

Coeficiente de correlación entre las dos columnas. 

COVAR_POP (col1, col2) 

Covarianza de una población. 

COVAR_SAMP (col1, col2) 

Covarianza de una muestra. 

CUME_DIST (col, porcentaje) 

Distribución acumulativa. 

DENSE_RANK (col) 

Número de orden de una fila en un conjunto ordenado de filas. 

FIRST (col) LAST (col) 

Devuelve la primera (última) fila, ordenada con respecto a un criterio elegido (por ejemplo, 
DENSE_RANK). 

GROUP_ID 

Diferencia los grupos duplicados que aparecen después de aplicar la cláusula GROUP BY. 

GROUPING (expr) 

Permite identificar las filas de acumulación cuando se ejecutan las instrucciones ROLLUP o CUBE. 

GROUPING_ID (expr) 

Al igual que la función GROUPING, permite identificar si la fila está contenida o no en el resultado de 
un comando ROLLUP o CUBE. 

PERCENTILE_CONT (n) WITHIN GROUP (ORDER BY expr [ASC|DESC]) 

Distribución inversa continua, con n comprendido entre 0 y 1. 

PERCENTILE_DISC (n) WITHIN GROUP (ORDER BY expr [ASC|DESC]) 

Distribución inversa discreta, estando n comprendido entre 0 y 1. 

MEDIAN (expr) 

Mediana. Equivalente a PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY expr). 

PERCENT_RANK (expr) 

© Éditions ENI – Todos los derechos reservados - 5-


Similar a CUME_DIST. 

RANK (expr) 

Calcula el rango de un valor dentro de un grupo de valores. 

REGR_(expr) 

Calcula la regresión lineal. 

STDDEV_POP (expr) 

Desviación típica de una población. 

STDDEV_SAMP (expr) 

Desviación típica de una muestra. 

VAR_POP (expr) 

Varianza de una población. 

VAR_SAMP (expr) 

Varianza de una muestra. 

LISTAGG (expr[,delimitador]) WITHIN GROUP (cláusula de ordenación) 

Para cada agrupación, concatena una expresión con un delimitador. 

Cuando  el  cálculo  de  valores  agregados  se  realiza  sobre  una  columna  determinada,  los  valores  NULL  de  dicha 
columna no se tienen en cuenta en los cálculos. 

Oracle  dispone  de  algunas  otras  funciones  para  calcular  valores  agregados  específicas  para  el  cálculo 
estadístico. 

Ejemplos 

Número  de  clientes  por  ciudad.  El  atributo  ciudad  se  ha  definido  como  un  tipo  de  dato  CHAR(30);  es  necesario  eliminar  los 
posibles  espacios  incluidos  a  la  derecha  de  los  nombres  de  ciudades,  con  el  fin  de  que  la  agrupación  se  realice  sobre  los 
caracteres significativos del valor de la columna. 

SQL> select rtrim (CIUDAD), count(*) from CLIENTES group by rtrim(CIUDAD);

RTRIM(CIUDAD) COUNT(*)
------------------------------ ----------
MADRID 1
ORENSE 3
PONTEVEDRA 2
TOLEDO 1

SQL>

- 6- © Éditions ENI – Todos los derechos reservados


Precios  más  elevado  y  medio  de  las  cantidades  disponibles  en  el  almacén  para  cada  familia  de  artículos  (los  dos  primeros 
caracteres de la referencia): 

SQL> select * from articulos;

REFA DESCRIPCIÓN PRECIO CODIVA CATEGORIA CANTALM


---- ------------------------------ ------- ------ ---------- -------
ZZZZ CANTIMPLORA VARIOS 25
ZZ01 LOTE ALFOMBRAS 500 2 VARIOS 0
AA00 REGALO 0 0 VARIOS 8
CD50 CADENA HIFI 735,4 2 IMPORT 7
AB ALFOMBRA 2 REBAJ 2
AB10 Alfombra china 1375,11 2 IMPORT 10
AB03 Alfombras 165 2 IMPORT 116
AB22 ALFOMBRA PERSA 1650 2 IMPORT 5
CD21 Pletina láser 500 2 IMPORT 20

9 filas seleccionadas.

SQL> select substr(refart,1,2), max(precio), avg(cantalm)


2 from articulos
3 group by substr(refart,1,2);

SU MAX(PRECIO) AVG(CANTALM)
-- ------------- -------------
AA 0 8
AB 1650 33,25
CD 735,4 13,5
ZZ 500 12,5

SQL>

f. Funciones analíticas

Las  funciones  analíticas  permiten  extraer  resultados  a  partir  de  una  agrupación  de  filas  realizada  mediante  la
instrucción GROUP BY.

Estas  funciones  se  diferencian  de  las  funciones  de  agregación  en  que,  en  lugar  de  devolver  un  único  valor  por
cada  grupo  de  valores,  devuelven  varias  filas  de  resultados  por  cada  grupo.  Estas  filas  de  resultados  se
denominan  ventanas  (windows).  Se  define  una  ventana  desplazable  por  cada  fila  analizada.  El  tamaño  de  la
ventana determina el número de filas que hay que tener en cuenta para el cálculo de la fila actual.

AVG

Media. 

CORR 

Coeficiente de correlación. 

COVAR_POP 

© Éditions ENI – Todos los derechos reservados - 7-


Covarianza de una población. 

COVAR_SAMP 

Covarianza de una muestra. 

COUNT 

Contador. 

CUME_DIST 

Distribución acumulativa. 

DENSE_RANK 

Calcula el rango de una fila en un grupo ordenado de filas. 

FIRST 

Permite obtener la primera fila de un conjunto de resultados seleccionado. 

LAST 

Permite obtener la última fila de un conjunto de resultados seleccionado. 

FIRST_VALUE 

Proporciona el primer valor de un conjunto de resultados seleccionado. 

LAST_VALUE 

Proporciona el último valor de un conjunto de resultados seleccionado. 

LAG 

Permite acceder a más de una fila simultáneamente. 

LEAD 

Función similar a LAG. 

LISTAGG 

Concatenación. 

MAX 

El elemento más grande. 

MIN 

- 8- © Éditions ENI – Todos los derechos reservados


El elemento más pequeño. 

NTH_VALUE 

Valor de una expresión en la enésima fila de una ventana. 

NTILE 

Permite dividir una fila de resultados en pequeños grupos perfectamente identificados por su número 
de orden. 

PERCENT_RANK 

Distribución acumulativa. 

PERCENTILE_CONT 

Distribución inversa continua. 

PERCENTILE_DISC 

Distribución inversa discreta. 

RANK 

Rango de un valor en el seno de un grupo. 

RATIO_TO_REPORT 

Calcula la relación entre un valor y la suma de un conjunto de valores. 

REGR 

Regresión lineal. 

ROW_NUMBER 

Permite generar un número exclusivo para cada fila. 

STDDEV 

Desviación típica. 

STDDEV_POP 

Desviación típica de una población. 

STDDEV_SAMP 

Desviación típica de una muestra. 

© Éditions ENI – Todos los derechos reservados - 9-


SUM 

Suma. 

VAR_POP 

Varianza de una población. 

VAR_SAMP 

Varianza de una muestra. 

VARIANCE 

Varianza. 

En el ejemplo siguiente, la consulta permite enumerar todos los artículos cuya referencia comienza por AB y mostrar junto a 
cada uno de ellos la referencia del artículo más barato. 

SQL> select refart, precio,


2 FIRST_VALUE(refart)
3 OVER(order by precio asc rows unbounded preceding) as mas_barato
4 from articulos
5 where upper(substr(refart,1,2))=’AB’;

REFA PRECIO MAS_


---- ------------- -----
AB03 165 AB03
AB10 1375,11 AB03
AB22 1650 AB03
AB AB03

SQL>

g. Restricciones sobre valores agregados

Cuando  se  desea  limitar  el  número  de  filas  devueltas  por  una  consulta  que conlleva  un  cálculo  de  valores
agregados, se puede usar la cláusula HAVING. La sintaxis es la siguiente:

SELECT lista de columnas, función de grupo FROM S GROUP


BY lista de columnas HAVING condición;

La condición puede contener una función estadística. Las expresiones usadas en la cláusula HAVING pueden hacer
referencia a criterios de agrupación o a cálculos de valores agregados.

Ejemplo

Presentación de datos estadísticos de las familias de artículos cuyo precio mínimo es mayor de 300 euros:

SQL> select substr(refart,1,2), max(PRECIO), min(PRECIO)

- 10 - © Éditions ENI – Todos los derechos reservados


2 from ARTICULOS group by substr(REFART,1,2)
3 having min(PRECIO)>300;

SU MAX(PRECIO) MIN(PRECIO)
-- ------------- -----------
CD 735,4 735,4
ZZ 500 500

SQL>

h. Producto cartesiano

El producto cartesiano permite asociar cada fila de una tabla con cada fila de otras tablas.

La operación S X T se expresa de la siguiente manera:

SELECT lista de columnas FROM S, T;

Si las columnas tienen el mismo nombre en ambas tablas, el nombre de la columna va precedido por el nombre de
la tabla.

Por tanto, el nombre completo de la columna es:

nombretabla.nombrecolumna.

Ejemplo

Creación y asignación de valores a la tabla DEPOSITOS. Simulación de la asignación de cada artículo a un depósito:

SQL> create table DEPOSITOS (CODE char(2) primary key, DIRECCION


varchar(60));
Tabla creada.
SQL> insert into DEPOSITOS values (’OR’, ’Paseo de los Olmos 12 32003 ORENSE’);
1 fila creada.
SQL> insert into DEPOSITOS values (’PO’, ’PONTEVEDRA’);
1 fila creada.
SQL> insert into DEPOSITOS values (’MA’, ’MADRID’);
1 fila creada.
SQL> commit;

Validación terminada.

SQL> select CODIGO,REFART from DEPOSITOS,ARTICULOS;

CO REFA
-- ----
OR ZZZZ
PO ZZZZ
MA ZZZZ
OR ZZ01
PO ZZ01
MA ZZ01

© Éditions ENI – Todos los derechos reservados - 11 -


OR AA00
PO AA00
MA AA00
OR CD50
PO CD50
MA CD50
OR AB
PO AB
MA AB
OR AB10
PO AB10
MA AB10
OR AB03
PO AB03
MA AB03
OR AB22
PO AB22
MA AB22
OR CD21
PO CD21
MA CD21
27 filas seleccionadas.

i. Combinaciones

La combinación es una restricción sobre el producto cartesiano que vincula cada fila de una tabla con filas de otra
tabla, de acuerdo con una condición dada.

La operación S JOIN (condición) T se expresa de la siguiente manera:

SELECT lista de columnas FROM S, T WHERE condición;

Ejemplo

Combinación natural entre PEDIDOS y CLIENTES:

SQL> select NUMPED, PEDIDOS.NUMCLI, NOMCLI


2 from CLIENTES, PEDIDOS
3 where CLIENTES.NUMCLI = PEDIDOS.NUMCLI;

NUMPED NUMCLI NOMCLI


---------- ---------- ------------------------------
1210 15 Gómez S.A.
1301 15 Gómez S.A.
1250 35 Martín Juan
1230 35 Martín Juan

SQL>

A partir de la versión 9i, Oracle admite el uso de combinaciones expresadas usando una sintaxis compatible con el 
estándar ANSI. 

- 12 - © Éditions ENI – Todos los derechos reservados


SELECT lista de columnas
FROM tabla [NATURAL] INNER JOIN tabla ON
{condición_combinación|USING (columna)}
WHERE condiciones;

SQL> select numped, pedidos.numcli, nomcli


2 from clientes inner join pedidos on
3 clientes.numcli=pedidos.numcli;

NUMPED NUMCLI NOMCLI


---------- ---------- ------------------------------
100 15 Gómez S.A.
1210 15 Gómez S.A.
1301 15 Gómez S.A.
1250 35 Martín Juan
1230 35 Martín Juan

SQL>

La palabra clave INNER es opcional. 

La ventaja de la sintaxis normalizada es, por el contrario, muy clara a la hora de definir combinaciones naturales 
entre las tablas, ya que solo es necesario especificar la condición de combinación. 

SQL> select numped, numcli, nomcli


2 from clientes natural inner join pedidos;

NUMPED NUMCLI NOMCLI


---------- ---------- ------------------------------
100 15 Gómez S.A.
1210 15 Gómez S.A.
1301 15 Gómez S.A.
1250 35 Martín Juan
1230 35 Martín Juan

SQL>

j. Combinaciones externas

La combinación externa (outer join) es una extensión de la combinación que permite obtener, además de las filas
que cumplen la condición, las filas de una de las tablas que no la cumplen. Basta con añadir el operador (+) a la
condición después de la columna de la tabla cuyas filas pueden no aparecer en el resultado.

Ejemplo

Lista de los clientes con sus pedidos, en el caso de que tengan alguno:

SQL> select NUMPED, PEDIDOS.NUMCLI, NOMCLI


2 from CLIENTES, PEDIDOS
3 where CLIENTES.NUMCLI=PEDIDOS.NUMCLI (+);

© Éditions ENI – Todos los derechos reservados - 13 -


NUMPED NUMCLI NOMCLI
---------- ---------- ------------------------------
1210 15 Gómez S.A.
1301 15 Gómez S.A.
M. García
1250 35 Martín Juan
1230 35 Martín Juan
PLAZA S.A.
Martín Juan
LACALLE

8 filas seleccionadas.
SQL>

La sintaxis ANSI para una unión externa es la siguiente: 

SELECT lista de columnas


FROM tabla [NATURAL] {LEFT | RIGHT | FULL} OUTER JOIN tabla ON
{condición_unión |USING (columna)}
WHERE condiciones;

SQL> select NUMPED, PEDIDOS.NUMCLI, NOMCLI


2 from CLIENTES LEFT OUTER JOIN PEDIDOS
3 on CLIENTES.NUMCLI = PEDIDOS.NUMCLI;
NUMPED NUMCLI NOMCLI
---------- ------ ------------------------------
1301 15 Gómez S.A.
M. García
1250 35 Martín Juan
1230 35 Martín Juan
PLAZA S.A.
Martín Juan
LACALLE

7 filas seleccionadas.

SQL>

La palabra clave OUTER es opcional. 

t1  LEFT  OUTER  JOIN  t2:  conserva  todas  las  filas  de  la  tabla  1  (tabla  de  la  izquierda)  incluso  si  no  hay 
correspondencia en la tabla 2.  

t1  RIGHT  OUTER  JOIN  t2:  conserva  todas  las  filas  de  la  tabla  2  (tabla  de  la  derecha)  incluso  si  no  hay 
correspondencia en la tabla 1. 

t1 FULL OUTER JOIN t2: conserva todas las filas de las tablas 1 y 2 incluso si no hay correspondencia con la otra 
tabla (LEFT y RIGHT). 

k. Unión, intersección, diferencia

- 14 - © Éditions ENI – Todos los derechos reservados


Estos operadores permiten obtener en una consulta filas procedentes de consultas diferentes pero que usan el 
mismo formato (mismo nombre de columnas, mismo tipo y en el mismo orden). 

Las operaciones S { / /­} T se expresan de la siguiente manera:

SELECT lista de columnas FROM S {UNION/UNION ALL/INTERSECT/


MINUS} SELECT lista de columnas FROM T;

El operador UNION ALL permite extraer todas las filas procedentes de las consultas, sin eliminar las duplicadas. 

Es posible realizar las operaciones de unión, intersección o diferencia entre datos procedentes de varias consultas 
SELECT,  pero  todas  las  columnas  deben  tener  la  misma  lista  de  columnas  (tipo  y  longitud)  y  dichas  columnas 
siempre deben definirse en el mismo orden. 

Ejemplo 

Agrupación de las filas de CLIENTES y CLIVARIOS: 

SQL> select NUMCLI, NOMCLI from CLIENTES


2 UNION
3 select NUMCLI, NOMCLI from CLIVARIOS;

NUMCLI NOMCLI
---------- ------------------------------
15 Gómez S.A.
20 M. García
35 Martín Juan
100 PLAZA S.A.
128 Martín P.
138 Martín Juan
152 LACALLE
556 Martín Juan
567 STUDIO 4

9 filas seleccionadas.

SQL>
SQL> select NOMCLI from CLIENTES
2 UNION
3 select NOMCLI from CLIVARIOS;

NOMCLI
------------------------------
Gómez S.A.
LACALLE
M. García
Martín Juan
Martín P.
PLAZA S.A.
STUDIO 4

7 filas seleccionadas.

SQL>

© Éditions ENI – Todos los derechos reservados - 15 -


2. Tratamiento del resultado

El resultado de las consultas anteriores puede emplearse para distintas finalidades: 

l presentar la información ordenada o no,

l asignar valores a una tabla intermedia,

l crear un archivo externo a la base de datos.

a. Clasificación

Para obtener un resultado ordenado se emplea la cláusula ORDER BY al final del comando SELECT.

Por  omisión,  la  clasificación  se  realiza  en  orden  creciente  y  este  orden  viene  determinado  por  los  parámetros
nacionales del entorno del usuario (parámetro NLS_SORT). La clasificación en orden decreciente se obtiene con la
opción  DESC  de  la  cláusula  ORDER  BY.  Si  el  usuario  posee  el  privilegio  necesario,  puede  modificar  el  parámetro
NLS_SORT durante la sesión.

El  orden  de  clasificación  se  puede  especificar  también  indicando  en  la  cláusula  ORDER  BY  el  número  de  orden
correspondiente, dentro de la cláusula SELECT, de la columna que se va utilizar para realizar la clasificación.

Sintaxis

SELECT ..... ORDER BY exp [Desc][, ...] ;

Ejemplo 

Presentación de los artículos clasificados por familia y en orden decreciente de precio: 

SQL> select REFART, PRECIO from ARTICULOS


2 ORDER BY substr(REFART,1,2), PRECIO desc;

REFA PRECIO
---- ----------
AA00 0
AB
AB10 1500
AB22 1250,1
AB03 150
CD50 735,4
ZZZZ
ZZ01 500

8 filas seleccionadas.

SQL> select PRECIO, substr(REFART,1,2) from ARTICULOS


2 ORDER BY 2,1 desc;

PRECIO SU
---------- --

- 16 - © Éditions ENI – Todos los derechos reservados


0 AA
AB
1500 AB
1250,1 AB
150 AB
735,4 CD
ZZ
500 ZZ

8 filas seleccionadas.
SQL>

b. Guardado

Mediante SQL

Es posible guardar el resultado de una consulta en una tabla, con el fin de poder utilizarlo en otra consulta.

Se pueden emplear dos métodos:

l crear en primer lugar la tabla y luego insertar en ella las filas resultantes de la consulta,

l crear la tabla a partir de la consulta.

Primer método 

Sintaxis 

CREATE TABLE nombre (columna tipo [DEFAULT expr]


[restricción], ...) ;
INSERT INTO nombre [(columna, columna,...)] SELECT ...;

Este método permite seleccionar los tipos de columnas, los valores predeterminados y definir controles empleando 
restricciones. 

Ejemplo 

Creación de una tabla simplificada a partir de la tabla CLIENTES: 

SQL> create table CLI (NUMCLI char(4), NOMCLI char(10));

Tabla creada.

SQL>
SQL> insert into CLI
2 select to_char(NUMCLI, ’009’), substr(NOMCLI, 1, 10)
3 from CLIENTES where CIUDAD like ’MADRID%’;

1 fila creada.

SQL> select * from CLI;

© Éditions ENI – Todos los derechos reservados - 17 -


NUMC NOMCLI
---- ----------
138 Martín Jua

SQL> drop table CLI;

Tabla borrada.

SQL>

Segundo método 

Sintaxis 

CREATE TABLE nombre [(columna, columna, ....)] AS SELECT ...;

Este método es más rápido, ya que los nombres y los tipos de las columnas de la nueva tabla se derivan de los de 
las columnas proyectadas en la instrucción SELECT. 

Ejemplo 

Guardado de la restricción "Clientes de Orense" en la tabla CLIORENSE: 

SQL> create table CLIORENSE as


2 select NUMCLI, NOMCLI from CLIENTES
3 where COD_POSTAL between 32000 and 32999;

Tabla creada.

SQL> select * from CLIORENSE;

NUMCLI NOMCLI
---------- ------------------------------
15 Gómez S.A.
128 Martín P.
35 Martín Juan
SQL> desc CLIORENSE
Name Null? Type
------------------------- -------- --------------
NUMCLI NUMBER(4)
NOMCLI NOT NULL VARCHAR2(30)

SQL> drop table CLIORENSE;


Tabla borrada.

SQL>

Mediante SQLPLUS 

Guardar el resultado de la consulta en un archivo ASCII. 

- 18 - © Éditions ENI – Todos los derechos reservados


Sintaxis 

SPOOL nombre_archivo

Ejemplo 

Creación de un archivo secuencial ASCII archivo.lst que contenga los datos de la tabla CLIENTES: 

SQL> SET HEADING OFF


SQL> SPOOL archivo
SQL> select * from CLIENTES;
SQL> SPOOL OFF

Tablas temporales 

Además de las tablas permanentes, Oracle ofrece la posibilidad de crear tablas temporales para almacenar datos 
durante la sesión o durante una transacción. Los datos almacenados en una tabla temporal creada mediante la 
instrucción  CREATE  GLOBAL  TEMPORARY  TABLE  son  accesibles  únicamente  desde  la  sesión  que  ha  creado  los 
datos. De hecho, cada sesión no ve más que sus propios datos y una instrucción TRUNCATE TABLE aplicada a una 
tabla temporal permite eliminar de forma sencilla todos los datos utilizados en la sesión que ejecuta la instrucción 
TRUNCATE.  

La  especificidad  de  esta  tabla  temporal  reside  en  el  hecho  de  que  los  datos  insertados  en  esta  tabla  solo  se 
mantienen durante el tiempo de la transacción. Por su parte, la tabla se mantiene en su sitio y es posible utilizarla 
en  las  demás  transacciones.  Si  se  quiere  que  los  datos  insertados  en  esta  tabla  se  guarden  de  forma  más 
persistente,  hay  que  utilizar  la  cláusula  ON  COMMIT  PRESERVE  ROWS  al  crear  la  tabla  temporal  global. De  este 
modo, los datos insertados en esta tabla serán visibles a través de todas las transacciones durante el tiempo de 
la sesión del usuario de Oracle que ha insertado los datos en la tabla. 

Sintaxis 

CREATE GLOBAL TEMPORARY TABLE tabla (nombre_columna tipo,...)


[ON COMMIT PRESERVE ROWS];

Ejemplo 

Creación de una tabla temporal global para almacenar el número y el nombre de determinados clientes: 

SQL> create global temporary table TCLI(


2 NUMCLI number(4),
3 NOMCLI varchar2(30));

Tabla creada.

SQL>

A continuación, se añaden datos a la tabla temporal. Estos datos son el resultado de ejecutar una instrucción de tipo SELECT 
que permite conocer el número y el nombre de los clientes correspondientes a cada uno de los pedidos. 

SQL> insert into tcli

© Éditions ENI – Todos los derechos reservados - 19 -


2 select cli.numcli, nomcli
3 from clientes cli, pedidos ped
4 where cli.numcli=ped.numcli;

3 filas creadas.

SQL>

En la misma sesión, se consulta la tabla temporal para conocer su contenido: 

SQL> select * from tcli;

NUMCLI NOMCLI
---------- ------------------------------
1 Alberto
1 Alberto
2 Casimiro

SQL>

En otra sesión, se consulta la misma tabla temporal para conocer su contenido: 

SQL> select * from tcli;

ninguna fila seleccionada

SQL>

La creación de la misma tabla con la opción ON COMMIT PRESERVE ROWS: 

SQL> create global temporary table TCLI(


2 NUMCLI number(4),
3 NOMCLI varchar2(30))
4 ON COMMIT PRESERVE ROWS;

Table created.

SQL> insert into tcli


2 select cli.numcli, numcli
3 from clientes cli, pedidos ped
4 where cli.numcli=ped.numcli;

5 rows created.

SQL> commit;

Commit complete.

SQL> select count(*) from tcli;

- 20 - © Éditions ENI – Todos los derechos reservados


COUNT(*)
---------------
5

SQL>

c. Enumeración de todas las posibilidades de un cálculo de valores agregados

Los cálculos de valores agregados siempre se realizan sobre la agrupación especificada por la cláusula GROUP BY.
A  veces,  es  necesario  efectuar  una  agrupación  más  grande  con  el  fin  de  conocer  otros  valores.  Por  ejemplo,  se
desea conocer el importe de cada pedido y el importe de todos los pedidos pasados por un cliente. Para llevar a
cabo correctamente estos cálculos en un solo paso, hay que utilizar las palabras claves ROLLUP y CUBE.

ROLLUP  permite realizar agrupaciones con niveles crecientes de generalidad. 

CUBE  permite realizar el cálculo solicitado sobre todas las agrupaciones posibles. 

Sintaxis 

SELECT lista_columnas, cálculo_agregado FROM tabla GROUP BY


{ROLLUP|CUBE} (lista_columnas)

El funcionamiento de estas dos palabras clave se explica mediante los ejemplos siguientes. 

Ejemplo 

En el siguiente ejemplo, ROLLUP permite calcular el total para cada cliente, así como el importe total de los pedidos de todos 
los clientes: 

SQL> select nomcli, p.numped, sum(cantped*precio) as total


2 from clientes cli, pedidos p, lineasped l, articulos a
3 where p.numcli=cli.numcli and p.numped=l.numped and l.refart=a.refart
4 group by rollup (nomcli, p.numped);

NOMCLI NUMPED TOTAL


------------------------------ ---------- ------------
Alberto 1 3000
Alberto 2 1250,1
Alberto 4250,1
Casimiro 3 300
Casimiro 300
4550,1

SQL>

Utilizando la expresión DECODE, se puede obtener una presentación más cuidad. 

SQL> select decode (grouping(nomcli),1,’Total clientes’, nomcli) as NOMBRE,


2 substr(decode(grouping(p.numped),1,’Total pedidos’, p.numped),1,20)
3 as numped, sum(cantped*precio) as total

© Éditions ENI – Todos los derechos reservados - 21 -


4 from clientes cli, pedidos p, lineasped l, articulos a
5 where p.numcli=cli.numcli and p.numped=l.numped and l.refart=a.refart
6 group by rollup (nomcli, p.numped);

NOMBRE NUMPED TOTAL


------------------------------ -------------------- ------------
Alberto 1 3000
Alberto 2 1250,1
Alberto Total pedidos 4250,1
Casimiro 3 300
Casimiro Total pedidos 300
Total clientes Total pedidos 4550,1
6 filas seleccionadas.
SQL>

La instrucción CUBE permite explorar todas las combinaciones posibles: 

SQL> select decode (grouping(nomcli),1,’Total clientes’, nomcli) as NOMBRE,


2 substr(decode(grouping(p.numped),1,’Total pedidos’, p.numped),1,20)
3 as numped, sum(cantped*precio) as total
4 from clientes cli, pedidos p, lineasped l, articulos a
5 where p.numcli=cli.numcli and p.numped=l.numped and l.refart=a.refart
6 group by cube (nomcli, p.numped);

NOMBRE NUMPED TOTAL


--------------------------- -------------------- ------------
Alberto 1 3000
Alberto 2 1250,1
Alberto Total pedidos 4250,1
Casimiro 3 300
Casimiro Total pedidos 300
Total clientes 1 3000
Total clientes 2 1250,1
Total clientes 3 300
Total clientes Total pedidos 4550,1
9 filas seleccionadas.
SQL>

3. La instrucción MERGE

Esta instrucción permite fusionar, en una única consulta, una operación de actualización (INSERT, UPDATE, DELETE) 
en una tabla. 

Los datos que sirven de base para la ejecución de la orden DML pueden provenir de una o más tablas. 

Sin embargo, la misma fila de datos no puede participar como origen y destino de la instrucción MERGE. 

Esta función resulta muy interesante cuando se quiere actualizar los datos de una tabla de forma condicional. Por 
ejemplo,  en  la  tabla  de  empleados  se  quiere  actualizar  el  salario  (+4%)  de  los  empleados  de  más  de  40  años  y 
borrar los de más de 65 años (jubilados). 

El contenido de la tabla EMPLEADOS es el siguiente: 

- 22 - © Éditions ENI – Todos los derechos reservados


SQL> select * from empleados;

NUMERO NOMBRE EDAD SALARIO


----------- --------------- ------------ --------------
1 María 53 3500
2 Pablo 28 1200
4 Juan 35 2300
7 Lucas 41 1800
5 Ana 25 1100
SQL>

Al  no  poder  ser  una  misma  fila  a  la  vez  origen  y  destino  del  comando  MERGE,  la  primera  etapa  consistirá  en  crear  una  tabla 
temporal que contendrá los números de empleado y su edad. 

SQL> Create table tinfo as


2 select numero, edad from empleados
3 /

Table created.

SQL>

Finalmente los datos de la tabla de empleados se actualizan: 

SQL> merge into empleados e


2 using (select numero, edad from tinfo) t
3 on (t.numero=e.numero)
4 WHEN MATCHED THEN UPDATE SET salario=salario*1.04
5 WHERE (t.edad>40)
6 DELETE WHERE (t.edad>65);

2 rows merged.

SQL>

El nuevo contenido de la tabla de empleados es ahora: 

SQL> select * from empleados;

NUMERO NOMBRE EDAD SALARIO


------------ --------------------------- ----------------- ----------
1 María 53 3640
2 Pablo 28 1200
4 Juan 35 2300
7 Lucas 41 1872
5 Ana 25 1100
SQL>

© Éditions ENI – Todos los derechos reservados - 23 -


El uso de esta instrucción permite evitar la ejecución de muchas consultas como INSERT, UPDATE o DELETE. 

No es posible actualizar varias veces una misma fila en el transcurso de una sola instrucción MERGE. 

Sintaxis 

MERGE INTO nombreTabla USING origen


ON (condition)
[WHEN MATCHED THEN UPDATE SET nombreColumna=valor
[WHERE condición] [DELETE WHERE condición] ]
[WHEN NOT MATCHED THEN INSERT (nombreColumna,...)
VALUES (valor, ...) [WHERE condición] ];

INTO 

permite especificar la tabla de destino de la instrucción MERGE y por tanto de las operaciones INSERT, 
UPDATE y DELETE. 

USING 

permite especificar cómo se seleccionan los datos que participan en esta instrucción; se trata de una 
consulta de tipo SELECT o bien del nombre de una tabla o vista. 

ON 

permite hacer una unión entre los datos ya presentes en la tabla de destino y los procedentes del 
origen. En función de esta unión, la acción será una actualización (WHEN MATCHED) o bien una 
inserción (WHEN NOT MATCHED). 

WHEN MATCHED 

permite definir la acción de actualización o bien de borrado a efectuar. 

WHEN NOT MATCHED 

permite definir una inserción a realizar en la tabla de destino. 

- 24 - © Éditions ENI – Todos los derechos reservados


SQL avanzado
El  lenguaje  SQL  permite  emplear  otros  objetos,  además  de  las  tablas  y  los  índices,  para  gestionar  los  datos  o 
manipular las consultas. 

Por otro lado, la potencia de la instrucción SELECT permite combinar las diferentes cláusulas en un único comando, así 
como anidar consultas. 

Por último, en un entorno multiusuario, SQL permite bloquear las tablas para preservar la integridad de los datos. 

1. Los objetos

a. Objetos View (vista)

Las vistas son tablas virtuales que presentan el resultado de una instrucción SELECT.

Una de las principales ventajas de utilizar vistas procede del hecho de que la vista no almacena los datos, sino
que hace referencia a una o varias tablas de origen mediante una consulta SELECT, consulta que se ejecuta cada
vez que se hace referencia a la vista. De este modo, cualquier modificación que se realice sobre los datos de las
tablas de origen es inmediatamente visible en la vista, cuando ésta vuelve a ejecutarse.

Los casos en que se emplean las vistas son diversos:

l Para  ocultar  a  los  usuarios  determinadas  columnas  o  filas,  poniendo  a  su  disposición  vistas  de  proyección  o  de 
restricción. Esto permite proporcionar un nivel de seguridad adicional.

l Para simplificar el uso de tablas que incluyan muchas columnas, muchas filas o nombres complejos, creando vistas 
con estructuras más sencillas y nombres más explícitos.

l Para "salvaguardar" las consultas utilizadas con mayor frecuencia, empleando un nombre para designarlas.

l Para  simplificar  la  introducción  de  instrucciones  SQL  por  parte  de  los  usuarios,  enmascarando  las  combinaciones 
utilizadas con mayor frecuencia.

Una  vez  creadas,  las  vistas  se  emplean  como  las  tablas  en  las  instrucciones  DML,  INSERT,  SELECT,  UPDATE, 
DELETE. Sin embargo, no es posible realizar actualizaciones si la vista contiene: 

l instrucciones para operaciones de conjuntos (UNION, INTERSECT, MINUS),

l funciones de grupo,

l cláusulas GROUP BY, CONNECT BY, START WITH.

Una vista definida mediante una combinación soporta las instrucciones INSERT, UPDATE, DELETE, si hace referencia 
en su definición a una tabla cuya(s) columna(s) de clave primaria aparecen en la lista de las columnas proyectadas 
de la combinación y si las instrucciones INSERT, UPDATE, DELETE se aplican sobre dicha tabla. 

Creación 

Sintaxis 

CREATE [OR REPLACE] [FORCE | NO FORCE] VIEW nombre


[(columnas [VISIBLE | INVISIBLE], .....)] AS SELECT .....
[WITH CHECK OPTION | WITH READ ONLY];

© Éditions ENI – Todos los derechos reservados - 1-


OR REPLACE 

Si la vista ya existe, permite reemplazar la descripción por la nueva consulta. En la práctica, la 
definición de una vista no se puede modificar parcialmente. 

FORCE | NO FORCE 

Permite forzar o impedir la creación de la vista si alguno de los elementos subyacentes (tabla o vista) 
no está definido. 

columnas 

Nombres asignados a las columnas de la vista. Si esta cláusula se omite, los nombres de las 
columnas de la vista se convierten en nombres de columnas o alias de columnas usadas en la 
sentencia de definición de la vista. 

[VISIBLE | INVISIBLE] 

Indica si la columna es visible (es el caso por defecto) o invisible. El funcionamiento es el mismo que 
para las columnas de las tablas. Esta funcionalidad apareció en la versión 12. 

WITH READ ONLY 

Prohíbe cualquier inserción, modificación o eliminación de datos a través de la vista. 

WITH CHECK OPTION 

Durante la inserción o modificación de filas en la vista, verifica que las filas insertadas o modificadas 
puedan visualizarse en dicha vista. 

Compilación 

Sintaxis 

ALTER VIEW nombre COMPILE;

La  compilación  de  la  vista  permite  validar  la  consulta  asociada  y  detectar  cuanto  antes  posibles  referencias 
incorrectas que pueda contener. Esto es especialmente útil después de modificar la estructura de alguna de las 
tablas subyacentes de la vista. Si la compilación de la vista da lugar a un error, los restantes objetos de la base de 
datos dependientes de esta vista dejarán de ser válidos. 

Ejemplo 

Vista  que  devuelve  los  clientes  de  ORENSE.  La  opción  WITH  CHECK  OPTION  impide  cualquier  inserción  de  cliente  que  no 
pertenezca a esta provincia: 

SQL> create or replace view V_CLIORENSE as


2 select NUMCLI, NOMCLI, COD_POSTAL, CIUDAD from CLIENTES
3 where COD_POSTAL between 32000 and 32999
4 with check option;

- 2- © Éditions ENI – Todos los derechos reservados


Vista creada.

SQL> select NUMCLI, substr(NOMCLI, 1, 12), COD_POSTAL,


2 substr(CIUDAD,1,12) from V_CLIORENSE;

NUMCLI SUBSTR(NOMCL COD_POSTAL SUBSTR(CIUDAD


---------- ------------ ---------- ------------
15 Gómez S.A. 32225 ORENSE
35 Martín Juan 32001 ORENSE
128 Martín P. 32255 ORENSE

SQL> insert into V_CLIORENSE values


2 (255, ’UMBERTO S.A.’, 27001, ’LUGO’);
insert into V_CLIORENSE values (255, ’UMBERTO S.A.’, 27001, ’LUGO’)
*
ERROR en línea 1:
ORA-01402: violación de la cláusula WHERE en la vista WITH CHECK OPTION

SQL> insert into V_CLIORENSE values (176, ’García e Hijo’, 32005, ’AMOEIRO’);

1 fila creada.

SQL> select NUMCLI, substr(NOMCLI, 1, 12), COD_POSTAL,


2 substr(CIUDAD,1,12) from V_CLIORENSE;

NUMCLI SUBSTR(NOMCL COD_POSTAL SUBSTR(CIUDAD


---------- ------------ ---------- ------------
15 Gómez S.A. 32225 ORENSE
35 Martín Juan 32001 ORENSE
128 Martín P. 32255 ORENSE
176 García e Hijo 32005 AMOEIRO

SQL> select NUMCLI, substr(NOMCLI, 1, 12), COD_POSTAL,


2 substr(CIUDAD,1,12) from CLIENTES;

NUMCLI SUBSTR(NOMCL COD_POSTAL SUBSTR(CIUDAD


---------- ------------ ---------- ------------
15 Gómez S.A. 32225 ORENSE
20 M. García 40040 TOLEDO
35 Martín Juan 32001 ORENSE
36 PLAZA S.A. 27001 LUGO
128 Martín P. 32255 ORENSE
138 Martín Juan 28020 MADRID
152 LACALLE 27001 LUGO
176 García e Hijo 32005 AMOEIRO

8 filas seleccionadas.

SQL>

La vista V_CLIPED salvaguarda la combinación CLIENTES/PEDIDOS. La vista V_CLIPED32 permite aplicar una restricción sobre 
los clientes de la provincia de Orense (código postal 32). La vista V_CLIPED se convierte en una vista no válida después de la 
eliminación  de  una  tabla  referenciada  en  la  cláusula  SELECT.  La  vista  V_CLIPED32  queda  entonces  automáticamente 
invalidada. 

© Éditions ENI – Todos los derechos reservados - 3-


SQL> create or replace view V_CLIPED (NUMCLIENTE, NOMBRE, PEDIDO,
2 CP) as select CLIENTES.NUMCLI, NOMCLI, NUMPED,
3 COD_POSTAL from CLIENTES, PEDIDOS
4 where CLIENTES.NUMCLI = PEDIDOS.NUMCLI;

Vista creada.

SQL> select * from V_CLIPED order by NUMCLI;

NUMCLIENTE NOMBRE PEDIDO CP


---------- ---------------------------------- ------- -----
15 Gómez S.A. 1210 32225
15 Gómez S.A. 1301 32225
35 Martín Juan 1250 32001
35 Martín Juan 1230 32001

SQL> create or replace view V_CLIPED32 as


2 select * from V_CLIPED
3 where CP between 32000 and 32999;

Vista creada.

SQL> select * from V_CLIPED32 order by NUMCLI;

NUMCLIENTE NOMBRE PEDIDO CP


---------- ---------------------------------- ------- -----
15 Gómez S.A. 1210 32225
15 Gómez S.A. 1301 32225
35 Martín Juan 1250 32001
35 Martín Juan 1230 32001

SQL> drop table PEDIDOS cascade constraints;

Tabla borrada.

SQL> alter view V_CLIPED compile;

Advertencia: Vista modificada con errores de compilación.

SQL> select * from V_CLIPED32 order by NUMCLI;


select * from V_CLIPED32 order by NUMCLI
*
ERROR en línea 1:
ORA-04063: view "SCOTT.V_CLIPED32" tiene errores

SQL>

Inserción en una vista basada en una combinación: 

SQL> create or replace view V_PEDCLI (NUMPED, FECHAPED, NUMCLI,


2 NOMCLI) as select NUMPED, FECHAPED, PEDIDOS.NUMCLI,
3 NOMCLI from CLIENTES, PEDIDOS

- 4- © Éditions ENI – Todos los derechos reservados


4 where CLIENTES.NUMCLI=PEDIDOS.NUMCLI;

Vista creada.

SQL> select * from V_PEDCLI order by NUMCLIENTE;

ninguna fila seleccionada

SQL> insert into V_PEDCLI (NUMPED, FECHAPED, NUMCLI)


2 values (1501, SYSDATE, 176);

1 fila creada.

SQL> select * from V_PEDCLI order by NUMCLI;

NUMPED FECHAPED NUMCLIENTE NOMCLI


---------- -------- ---------- --------------
1501 23/12/02 176 García e Hijo

SQL>

Eliminación 

Sintaxis 

DROP VIEW nombre;

Los objetos que hacen referencia a una vista eliminada se convierten en objetos no válidos. 

Vistas interactivas 

Se puede definir una vista directamente en una consulta sin ser necesario utilizar un comando CREATE VIEW. Esta 
posibilidad es interesante, ya que permite definir de forma simple una vista cuyo uso sea limitado. 

Ejemplo 

La  vista  interactiva  permite  conocer  el  importe  de  cada  pedido.  En  la  consulta  se  hace  referencia  a  dicha  vista  mediante  el 
alias de tabla LPED. La consulta muestra los datos relativos a cada cliente. 

SQL> select nomcli, importe


2 from clientes cli, (select numped, sum(cantped*precio) as importe
3 from lineasped l, articulos a
4 where l.refart=a.refart
5 group by numped) lped,
6 pedidos ped
7 where cli.numcli=ped.numcli
8 and lped.numped=ped.numped;

NOMCLI IMPORTE
------------------------------ ----------
Alberto 3000
Alberto 500

© Éditions ENI – Todos los derechos reservados - 5-


Casimiro 300

SQL>

b. Objetos schema (esquema)

Un esquema es un conjunto de tablas, vistas y privilegios agrupados bajo un mismo nombre (el del usuario).

El  uso  explícito  de  un  esquema  mediante  la  instrucción CREATE  SCHEMA  AUTHORIZATION  permite  comprender  el
concepto de transacción aplicado a las instrucciones DDL para la creación de tablas y vistas y a la asignación de
privilegios mediante GRANT.

Si  alguna  de  las  instrucciones  DDL  especificadas  en  la  instrucción  CREATE  SCHEMA  AUTHORIZATION  no  funciona
correctamente, el conjunto entero de instrucciones se anula.

El nombre de esquema utilizado en la instrucción es el nombre asociado al usuario (USER) que ha abierto la sesión
actual.

Sintaxis

CREATE SCHEMA AUTHORIZATION nombre


{CREATE {TABLE/VIEW}..../GRANT... }...;

Ejemplo 

Instrucción  CREATE  SCHEMA  AUTHORIZATION  ejecutada  sin  errores.  Todas  las  instrucciones  DDL  especificadas  han  sido 
ejecutadas. 

SQL> drop view v_pedcli;

Vista borrada.

SQL> drop table linped;

Tabla borrada.

SQL> drop table pedidos;

Tabla borrada.

SQL> drop table clientes;

Tabla borrada.

SQL> drop table articulos;

Tabla borrada.

SQL> create schema authorization scott


2 create table clientes(
3 numcli number(4)
4 constraint pk_clientes primary key

- 6- © Éditions ENI – Todos los derechos reservados


5 constraint ck_clientes_numcli check (numcli>0),
6 nomcli varchar2(30)
7 constraint nn_clientes_nomcli not null,
8 direccli varchar2(80),
9 cod_postal number(5)
10 constraint ck_clientes_codpostal check(cod_postal between 1000 and 95999),
11 ciudad char(30)
12 )
13 create table articulos(
14 refart char(4) primary key,
15 descripcion varchar2(30),
16 precio number(8,2),
17 codiva number(1),
18 categoria char(10),
19 cantalm number(5)
20 )
21 create table pedidos(
22 numped number(9),
23 numcli number(4),
24 fechaped date,
25 estadoped char(2),
26 constraint pk_pedidos primary key (numped),
27 constraint fk_pedidos_clientes foreign key(numcli) references
clientes(numcli),
28 constraint ck_pedidos_estado check (estadoped in (’EC’,’SU’,’SE’))
29 )
30 create table linped (
31 numped number(6)
32 constraint fk_linped_pedidos references pedidos (numped),
33 numlin number(2)
34 constraint ck_linped_numlin check (numlin>0),
35 refart char(4)
36 constraint fk_linped_articulos references articulos(refart),
37 cantped number(5),
38 constraint pk_linped primary key(numped,numlin)
39 )
40 create view v_pedcli (numped, fechaped, numcli, nomcli) as
41 select numped, fechaped, pedidos.numcli, nomcli
42 from pedidos, clientes
43 where pedidos.numcli=clientes.numcli
44 grant select on articulos to public
45 ;

Esquema creado.

SQL> desc pedidos;


Nombre Nulo? Tipo
----------------------------------------- -------- ----------------------------
NUMPED NOT NULL NUMBER(9)
NUMCLI NUMBER(4)
FECHAPED DATE
ESTADOPED CHAR(2)

SQL> desc clientes;


Nombre Nulo? Tipo

© Éditions ENI – Todos los derechos reservados - 7-


----------------------------------------- -------- ----------------------------
NUMCLI NOT NULL NUMBER(4)
NOMCLI NOT NULL VARCHAR2(30)
DIRECCLI VARCHAR2(80)
CODPOSTAL NUMBER(5)
CIUDAD CHAR(30)

SQL> desc articulos;


Nombre Nulo? Tipo
----------------------------------------- -------- ----------------------------
REFART NOT NULL CHAR(4)
DESCRIPCION VARCHAR2(30)
PRECIO NUMBER(8,2)
CODIVA NUMBER(1)
CATEGORIA CHAR(10)
CANTALM NUMBER(5)

SQL> desc linped;


Nombre Nulo? Tipo
----------------------------------------- -------- ----------------------------
NUMPED NOT NULL NUMBER(6)
NUMLIN NOT NULL NUMBER(2)
REFART CHAR(4)
CANTPED NUMBER(5)

SQL>

Una de las instrucciones DDL especificadas (CREATE VIEW) contiene un error (nombre de columna incorrecto en la línea 18) y 
no se ha podido terminar la ejecución. La otra instrucción (CREATE TABLE) especificada en CREATE SCHEMA AUTHORIZATION 
ha sido anulada. 

SQL> drop table LINPED;

Tabla borrada.

SQL> drop view V_CLIPEDLIN

Vista borrada.

SQL> create schema authorization JUAN


2 create table LINPED(
3 NUMPED number(6)
4 constraint LINPED_NUMPED_RF
5 references PEDIDOS(NUMPED),
6 NUMLIN number(2)
7 constraint LINPED_NUMLIN_CK check(NUMLIN>0),
8 REFART char(4)
9 constraint LINPED_refart_RF
10 references ARTICULOS(REFART),
11 CANTPED number(5),
12 constraint LINPED_PK primary key (NUMPED, NUMLIN))
13 create view V_CLIPEDLIN (NUMCLIENTE, NOMCLI, NUMPED, FECHAPED,

- 8- © Éditions ENI – Todos los derechos reservados


14 NUMLIN, REFART, CANTPED) as
15 select NUMCLIENTE, NOMCLI, LINPED.NUMPED, FECHAPED, NUMLIN,
16 REFART, CANTPED
17 from V_PEDCLI, LINPEDIDOS
18 where V_PEDCLI.NUMPED = LINPEDIDOS.NUMPE;
create schema authorization JUAN
*
ERROR en línea 1:
ORA-02427: fallo al crear la vista

SQL>
SQL> select * from LINPED;
select * from LINPED
*
ERROR en línea 1:
ORA-00942: la tabla o vista no existe

SQL>

c. Objetos Synonym (sinónimo)

Un  sinónimo  es  un  nombre  alternativo  que  se  asigna  a  un  objeto  de  tipo  TABLE,  VIEW,  SEQUENCE,  SNAPSHOT,
PROCEDURE, FUNCTION o PACKAGE.

Los sinónimos proporcionan una mayor flexibilidad en la gestión de los nombres de objetos:

l poniendo a disposición de los usuarios objetos con el mismo nombre,

l ocultando el nombre del esquema al que pertenece el objeto,

l proporcionando la posibilidad de hacer referencia varias veces a un objeto dentro de una consulta,

l simplificando la escritura de las consultas.

Creación 

Sintaxis 

CREATE [PUBLIC] SYNONYM nombre FOR objeto;

PUBLIC incluye el sinónimo en el esquema PUBLIC, haciendo de este modo que sea visible para cualquier usuario 
definido  en  la  base  de  datos  (sin  hacer  referencia  a  un  esquema).  En  caso  contrario,  el  sinónimo  es  local  al 
esquema del usuario propietario. 

Los sinónimos ofrecen la posibilidad de atribuir varios nombres a un mismo objeto, lo que permite la simplificación 
de  la  escritura  de  consultas,  sobre  todo  cuando  debe  emplearse  la  misma  tabla  varias  veces  en  la  misma 
instrucción SELECT. 

Los sinónimos públicos (PUBLIC) resultan muy útiles, ya que ofrecen a una aplicación la posibilidad de trabajar con 
tablas  sin  tener  en  cuenta  el  esquema  en  el  que  se  han  creado  los  objetos.  Con  este  tipo  de  elemento,  la 
aplicación  cliente  es  totalmente  independiente  de  la  estructura  de  la  base  de  datos  y  del  propietario  de  los 
elementos. 

© Éditions ENI – Todos los derechos reservados - 9-


Eliminación 

Sintaxis 

DROP [PUBLIC] SYNONYM nombre;

Ejemplo 

Combinación de la tabla NOMENCLATURA consigo misma para visualizar los artículos compuestos: 

SQL> select * from NOMENCLATURA;

REFART DESCRIPCION COMPONENTE NUM


------ ------------------------------ ------------ ----------
XX55 BICICLETA 0
x133 Ruedas XX55 2
x520 Cuadro XX55 1
x456 Manillar XX55 1
QD24 Lote de alfombras 0
AB03 Alfombrillas QD24 10

6 filas seleccionadas.

SQL> create synonym COMPOSICION for NOMENCLATURA;

Sinónimo creado.
SQL> select COMPOSICION.REFART,COMPOSICION.DESCRIPCION,
2 NOMENCLATURA.NUM,
3 NOMENCLATURA.DESCRIPCION
4 from NOMENCLATURA, COMPOSICION
5 where NOMENCLATURA.COMPONENTE=COMPOSICION.REFART
6 order by COMPOSICION.REFART;

REFART DESCRIPCION NUM DESCRIPCION


------ ------------------------------ ---------- ------------
QD24 Lote de alfombras 10 Alfombrillas
XX55 BICICLETA 2 Ruedas
XX55 BICICLETA 1 Cuadro
XX55 BICICLETA 1 Manillar

SQL>

d. Objetos Sequence (secuencia)

La creación de un objeto SEQUENCE pone a disposición del usuario un generador de números.

Las  secuencias  se  emplean  para  generar  numeraciones  de  forma  automática,  en  concreto  para  la  creación  de
valores de clave primaria.

El  uso  de  un  objeto  secuencia  es  más  flexible  y  proporciona  mejores  resultados  que  la  gestión  manual  de
contadores por medio de una tabla.

- 10 - © Éditions ENI – Todos los derechos reservados


No  obstante,  utilizar  una  secuencia  no  garantiza  la  ausencia  de  "huecos"  en  la  numeración.  La  secuencia  es  un 
sencillo generador de números y todos los números que facilita son diferentes, pero, si se solicitan números a una 
secuencia y no se utilizan a continuación, entonces dichos números se pierden. La secuencia es, en la práctica, un 
objeto en sí mismo y puede ser utilizado por varias tablas. 

Cada valor de la secuencia se expresa utilizando un máximo de 28 cifras significativas. 

Sintaxis 

CREATE SEQUENCE nombre [parámetros];


ALTER SEQUENCE nombre parámetros;
DROP SEQUENCE nombre;

Parámetros 

START WITH n 

Valor inicial. 

INCREMENT BY n 

Establece el valor del incremento. Puede ser positivo o negativo. 

MINVALUE n/NOMINVALUE 

Establece un valor límite mínimo o que no existe dicho valor mínimo. 

MAXVALUE n/NOMAXVALUE 

Establece un valor límite máximo o que no existe dicho valor máximo. 

CYCLE/NOCYCLE 

CYCLE fuerza a la secuencia a volver al valor MINVALUE cuando se ha alcanzado MAXVALUE 
(secuencia creciente) o al valor MAXVALUE cuando se ha alcanzado el valor MINVALUE (secuencia 
decreciente). 

CACHE n/NOCACHE 

Fuerza la anticipación del proceso de generación de los valores siguientes de la secuencia, 
almacenándolos en memoria, con el fin de mejorar los tiempos de respuesta de la secuencia. 

ORDER/NOORDER 

Garantiza un orden de asignación de números según el orden de las solicitudes. Esta opción no tiene 
mayor interés salvo en el caso de usar la opción PARALLEL OPTION en modo PARALLEL en el nivel de 
la instancia de Oracle. 

GLOBAL/SESSION 

Permite definir una secuencia global (por defecto) o a nivel sesión. Esta funcionalidad apareció en la 
versión 12 y una secuencia global corresponde a la secuencia tradicional de las versiones anteriores. 

© Éditions ENI – Todos los derechos reservados - 11 -


Con una secuencia de nivel sesión, los valores generados son únicos para cada sesión, y no se 
comparten entre sesiones. Además, cuando la sesión termina, el estado actual de la secuencia se 
pierde. Esta funcionalidad es particularmente útil con las tablas temporales que tienen una visibilidad 
a nivel de sesión. 

Las secuencias se usan mediante pseudo­columnas en las instrucciones de manipulación de datos. 

pseudo­columnas 

nomseq.CURRVAL 

Proporciona el valor actual de la secuencia. Esta pseudo­columna no tiene asignado ningún valor 
cuando se crea la secuencia ni cuando se abre una nueva sesión. 

nomseq.NEXTVAL 

Incrementa el valor de la secuencia y devuelve el nuevo valor de la misma. Esta pseudo­columna 
debe ser la primera a la que se haga referencia después de crear la secuencia o de abrir una sesión. 

Si se hace referencia a la misma secuencia desde varias sesiones, el valor de la pseudo­columna CURRVAL en una 
sesión no se modifica mientras que el usuario correspondiente no haga referencia a la pseudo­columna NEXTVAL; 
y esto es así incluso aunque otros usuarios hagan referencia a NEXTVAL en su sesión. 

Ejemplo 

SQL> create sequence C_NUMCLI start with 1000 maxvalue 9999 nocycle;

Secuencia creada.

SQL> insert INTO CLIENTES (NUMCLI, NOMCLI, CIUDAD)


2 values (C_NUMCLI.nextval, ’GARCÍA y GARCÍA’, ’CADIZ’);

1 fila creada.

SQL> insert INTO CLIENTES (NUMCLI, NOMCLI, CIUDAD)


2 values (C_NUMCLI.nextval, ’GÓMEZ y GÓMEZ’, ’JAEN’);

1 fila creada.

SQL> select NUMCLI, NOMCLI, CIUDAD from CLIENTES order by NUMCLI;


NUMCLI NOMCLI CIUDAD
---------- ------------------------------ -------------------------
15 Gómez S.A. ORENSE
20 M. García TOLEDO
35 Martín Juan ORENSE
36 DEL PINO S.A. TOLEDO
138 Martín Juan MADRID
152 LACALLE CACERES
1000 GARCÍA y GARCÍA CADIZ
1001 GÓMEZ y GÓMEZ JAEN
8 filas seleccionadas.
SQL>

- 12 - © Éditions ENI – Todos los derechos reservados


2. Consultas complejas

a. Elementos de la sintaxis

Alias

Nombre alternativo dado a una columna o a una tabla en una consulta. 

Los alias de columna permiten: 

l Cambiar el nombre de la columna en la presentación o en la tabla resultante.

l Proporcionar un nombre que use caracteres especiales (el espacio, por ejemplo).

Los  alias  de  tabla  definidos  en  las  cláusulas  FROM  de  las  instrucciones  SELECT  se  corresponden  con  sinónimos 
internos  de  la  consulta.  Permiten  agilizar  la  escritura  de  la  instrucción  y  referirse  a  la  misma  tabla  en  contextos 
diferentes dentro de una instrucción DML compleja (con subconsulta). 

Sintaxis 

SELECT columna [AS] alias_columna,...


FROM tabla alias_tabla,...

Ejemplos 

Presentación de un nombre de columna que contiene espacios: 

SQL> select NUMCLI, NOMCLI as "Nombre del cliente" from CLIENTES;


NUMCLI Nombre del cliente
---------- ------------------------------
1000 GARCÍA y GARCÍA
1001 GÓMEZ y GÓMEZ
15 Gómez S.A.
20 M. García
35 Martín Juan
152 LACALLE
138 Martín Juan
36 DEL PINO S.A.
8 filas seleccionadas.

SQL>

Utilización de la tabla de origen en una subconsulta. Establece la correspondencia de la cantidad en almacén de cada artículo 
con el valor máximo de la cantidad en almacén para la familia de artículos (dos primeros caracteres de la referencia). 

SQL> update articulos a


2 set cantalm=(select max(cantalm) from articulos b
3 where substr(a.refart,1,2)=substr(b.refart,1,2));

© Éditions ENI – Todos los derechos reservados - 13 -


9 filas actualizadas.

SQL> select refart, descripcion, precio, cantalm from articulos;

REFA DESCRIPCION PRECIO CANTALM


---- ------------------------------ ---------- ----------
AB22 Alfombra persa 1250,1 116
CD50 Cadena HIFI 735,4 20
ZZZZ Cantimplora 25
AA00 Regalo 0 8
AB03 Alfombra 150 116
CD21 Pletina láser 500 20
AB Alfombra 116
ZZ01 Lote alfombras 500 25
AB10 Alfombra china 1500 116

9 filas seleccionadas.

SQL>

Any

Compara,  teniendo  en  cuenta  el  operador  especificado  (= ,<>,<,<= ,>,  >= ),  los  valores  de  las  columnas 
especificadas con cada uno de los valores de la lista. La expresión es verdadera si al menos una comparación es 
verdadera.  La  lista  de  valores  puede  ser  una  lista  de  constantes  literales  o  los  valores  devueltos  por  una 
subconsulta. 

Sintaxis 

SELECT ...... WHERE [(columna, columna,...)] operador ANY


({SELECT ...../expresión,...});

La subconsulta o la lista de valores debe proporcionar los valores con los que hay que comparar. 

Ejemplo 

Presentación de los artículos que tienen el mismo precio que el artículo ZZ01: 

SQL> select refart, descripcion, precio, cantalm from articulos


2 where precio=ANY(select precio from articulos
3 where refart=’ZZ01’);

REFA DESCRIPCION PRECIO CANTALM


---- ------------------------------ ---------- ----------
CD21 Pletina láser 500 20
ZZ01 Lote alfombras 500 25

SQL>

All

- 14 - © Éditions ENI – Todos los derechos reservados


Compara,  teniendo  en  cuenta  el  operador  especificado  (= ,<>,<,<= ,>,  >= ),  los  valores  de  las  columnas 
especificadas  con  cada  uno  de  los  valores  contenidos  en  la  lista.  La  expresión  es  verdadera  si  todas  las 
comparaciones  son  verdaderas.  La  lista  de  valores  puede  ser  una  lista  de  constantes  literales  o  de  valores 
devueltos por una subconsulta. 

Sintaxis 

SELECT ...... WHERE [(columna, columna,..)] operador ALL


(SELECT...../expresión,...);

Exists

La condición es verdadera si la subconsulta devuelve al menos una fila. 

Sintaxis 

SELECT ...... WHERE [(]columna [, columna, ..)] EXISTS


(SELECT ...../expresión,...);

Ejemplo 

La lista de clientes sólo se muestra si hay al menos un pedido en la tabla PEDIDOS:

SQL> select NUMCLI, NOMCLI from CLIENTES


2 where exists (select ’x’ from PEDIDOS);

NUMCLI NOMCLI
---------- ------------------------------
1000 GARCÍA y GARCÍA
1001 GÓMEZ y GÓMEZ
15 Gómez S.A.
20 M. García
35 Martín Juan
152 LACALLE
138 Martín Juan
36 DEL PINO S.A.
8 filas seleccionadas.

SQL> delete from PEDIDOS;

4 filas suprimidas.

SQL> select NUMCLI, NOMCLI from CLIENTES


2 where exists (select ’x’ from PEDIDOS);

ninguna fila seleccionada

SQL>

b. Subconsultas

Al escribir una consulta compleja, hay que diferenciar entre la consulta externa y la consulta interna, es decir, la

© Éditions ENI – Todos los derechos reservados - 15 -


subconsulta. 

Las subconsultas pueden clasificarse en dos categorías: subconsultas anidadas y subconsultas correlacionadas. 

Subconsultas anidadas 

En una subconsulta anidada, no existe ningún vínculo explícito entre la consulta interna y la consulta externa. La 
consulta interna se ejecuta una sola vez para construir la lista de valores, antes de ejecutar la consulta externa 
(independientemente del número de filas devueltas por aquélla). 

Ejemplo 

Lista de los clientes que viven en la misma ciudad que el cliente "Martín Juan". 

SQL> select NUMCLI, NOMCLI, CIUDAD from CLIENTES


2 where CIUDAD in (select CIUDAD from CLIENTES
3 where NOMCLI like ’Martín Juan%’);

NUMCLI NOMCLI CIUDAD


---------- ------------------------------ ---------
138 Martín Juan MADRID
15 Gómez S.A. ORENSE
35 Martín Juan ORENSE

SQL>

Subconsultas correlacionadas 

En  una  subconsulta  correlacionada,  la  condición  especificada  en  la  cláusula  WHERE  de  la  consulta  interna  hace 
referencia a una o varias columnas de la consulta externa. La consulta interna se ejecuta, por tanto, para cada fila 
devuelta por la consulta externa. 

Ejemplo 

Lista de los clientes que no tienen pedidos asociados: 

SQL> select numcli, nomcli


2 from clientes cl
3 where not exists (select numcli
4 from pedidos pe
5 where cl.numcli=pe.numcli);

NUMCLI NOMCLI
---------- ------------------------------
15 Gómez S.A.
20 M. García
35 Martín Juan
36 DEL PINO S.A.
37 E. LACALLE
152 LACALLE
138 Martín Juan

- 16 - © Éditions ENI – Todos los derechos reservados


7 filas seleccionadas.

SQL>

Diferencia entre los dos tipos de subconsultas 

Al escribir subconsultas, es posible elegir la escritura de subconsultas anidadas, que favorece el uso de la cláusula 
IN, o la escritura de subconsultas correlacionadas, que favorece el uso de la cláusula EXISTS. Para saber cuál es la 
mejor  solución  en  función  de  los  datos  a  extraer,  hay  que  profundizar  un  poco  en  el  funcionamiento  de  las 
cláusulas IN y EXISTS. 

En el marco del uso de la cláusula IN (subconsulta anidada) es posible concebir que la subconsulta se evalúa como 
una vista en línea y que se hace una unión sobre la tabla de la consulta principal con los datos procedentes de 
esta subconsulta. 

El ejemplo que presenta la subconsulta anidada se evalúa de la forma siguiente: 

Select numcli, nomcli, ciudad


from clientes cli1, (select ciudad from clientes where nomcli
like ’GARCIA%’) cli2
where cli1.ciudad=cli2.ciudad

En el caso del uso de la cláusula EXISTS, la subconsulta correlacionada se ejecuta por cada fila procedente de la 
consulta externa. Esta solución será pues mejor si la tabla de la consulta externa es relativamente pequeña y si 
cuenta con buenos índices sobre la tabla de la subconsulta sobre las columnas que participan de la unión. 

El ejemplo que ilustra la subconsulta correlacionada es interesante respecto a una subconsulta anidada si: 

l el número de clientes es pequeño en relación a los pedidos;

l la  extracción  de  los  diferentes  números  de  cliente  a  partir  de  la  tabla  de  pedidos  representa  una  pesada  carga  de 
trabajo.

Se implementa un índice sobre la columna NUMCLI de la tabla de pedidos para acelerar los tiempos de unión. 

c. Consultas jerárquicas

En  ocasiones,  es  necesario  solicitar  datos  que  siguen  un  orden  jerárquico  preciso.  Para  ello,  Oracle  dispone  de
comandos o instrucciones que permiten extraer datos en un determinado orden. Estos comandos son CONNECT BY
PRIOR y START WITH. Durante la ejecución de una consulta de este tipo, Oracle procede de la siguiente forma:

l Oracle selecciona como raíz del árbol las filas que satisfacen la condición especificada en la cláusula START WITH.

l Oracle  selecciona  los  objetos  hijo  de  cada  objeto  padre.  Todos  deben  satisfacer  la  condición  especificada  en  la 
cláusula CONNECT BY.

l Todos los elementos descendientes se seleccionan uno tras otro.

l Si la consulta contiene una cláusula WHERE, Oracle elimina de la jerarquía todas las filas que no cumplen la cláusula 
WHERE.

Para  saber  en  qué  nivel  de  la  jerarquía  se  encuentra,  Oracle  pone  a  disposición  del  usuario  la  pseudo­columna 
LEVEL. 

© Éditions ENI – Todos los derechos reservados - 17 -


Ejemplo 

Creación de la tabla EMPLEADOS. Cada empleado puede depender de un jefe cuyo número se conoce. El jefe de un empleado 
también es un empleado. Se desea conocer el organigrama de la empresa. 

SQL> create table empleados(


2 numemp number(5)
3 constraint pk_empleados primary key,
4 nombre char(30),
5 puesto char(15),
6 numjefe number(5));

Tabla creada.

SQL>

La consulta SQL permite conocer la jerarquía de organización de la empresa: 

SQL> select substr(lpad(’ ’,2*(level-1))||nombre,1,30) as nombre,


2 numemp, numjefe, puesto
3 from empleados
4 start with puesto=’dg’
5 connect by prior numemp=numjefe;

NOMBRE NUMEMP NUMJEFE PUESTO


------------------------------ ---------- ---------- ------------
Evaristo 5 dg
Barrios 2 5 drh
Alcalá 1 2 contable
Castillo 3 2 secretaria
Hernández 8 2 empleado
Hernández 6 5 experto
Diego 4 6 secretaria
García 7 6 empleado

8 filas seleccionadas.

SQL>

La función SYS_CONNECT_BY_PATH, que solo puede utilizarse en las consultas jerárquicas, permite conocer la ruta 
completa desde la raíz del árbol. Esta función solo se puede aplicar a las columnas de tipo carácter. 

El siguiente ejemplo muestra el uso de esta función en una consulta jerárquica. 

SQL> select lpad(’ ’,2*(level-1))||SYS_connect_by_path(rtrim(nombre),’/’)


as nombre
2 from empleados
3 start with puesto=’dg’
4 connect by prior numemp=numjefe;

- 18 - © Éditions ENI – Todos los derechos reservados


NOMBRE
------------------------------------------------------------------------
Evaristo
/Evaristo/Barrios
/Evaristo/Barrios/Alcalá
/Evaristo/Barrios/Castillo
/Evaristo/Barrios/Hernández
/Evaristo/Hernández
/Evaristo/Hernández/Diego
/Evaristo/Hernández/García

8 filas seleccionadas.

SQL>

La función CONNECT_BY_ROOT permite conocer, a partir de un elemento extraido de una consulta jerárquica, los 
datos sobre la cima de la jerarquía. Es necesario anteceder el nombre de las columnas de las que se quiere esta 
información con CONNECT_BY_ROOT. 

Esta funcionalidad es especialmente interesante cuando se quiere extraer de una forma jerárquica los datos con 
una restricción sobre ciertos criterios. 

Por  ejemplo,  si  la  tabla  contiene  reglas  de  ensamblado  de  piezas,  es  posible  mediante  CONNECT_BY_ROOT 
conocer los elementos que cuentan con la pieza sobre la que se ha hecho la restricción. 

Ejemplo 

El ejemplo siguiente permite conocer fácilmente al superior de cada empleado. 

SQL> select substr(lpad(’ ’,2*(level-1))||nombre,1,30) as nombre,


2 numemp, numjefe, puesto, CONNECT_BY_ROOT nombre as BigJefe
3 from empleados
4 start with puesto=’dg’
5 connect by prior numemp=numjefe;

NOMBRE NUMEMP NUMJEFE PUESTO BIGJEFE


--------------------- ------ ------- ------ -------
Ernesto 5 dg Ernesto
Bernardo 2 5 drh Ernesto
Alberto 1 2 contable Ernesto
Coronas 3 2 secretaria Ernesto
Hestor 8 2 empleado Ernesto
Fraguas 6 5 experto Ernesto
Damas 4 6 secretaria Ernesto
García 7 6 empleado Ernesto

8 rows selected.

SQL>

La  extracción  de  datos  de  forma  jerárquica  se  hace  a  menudo  etapa  por  etapa.  Para  saber  si  un  elemento  es 
terminal  o  no,  hay  que  efectuar  una  consulta  jerárquica  a  partir  de  dicho  elemento.  Con  la  función 
CONNECT_BY_ISLEAF,  que  devuelve  0  si  el  elemento  no  es  hoja  y  1  en  caso  contrario,  es  posible  identificar  los 

© Éditions ENI – Todos los derechos reservados - 19 -


elementos que poseen un detalle. 

Ejemplo 

En el ejemplo siguiente se puede distinguir entre los empleados que administran un equipo y los que no lo hacen. 

SQL> select numemp, nombre, puesto, connect_by_isleaf as dirigente


2 from empleados
3 start with puesto=’dg’
4 connect by numjefe = PRIOR numemp;

NUMEMP NOMBRE PUESTO DIRIGENTE


----------------------------- ------ - ---------
5 Ernesto dg 0
2 Bernardo drh 0
1 Alberto contable 1
3 Coronas secretaria 1
8 Hestor empleado 1
6 Fraguas experto 0
4 Damas secretaria 1
7 García empleado 1

8 rows selected.

SQL>

d. Pivotar los datos

A partir de la versión 11 es posible, de una manera muy sencilla, pivotar los datos del resultado de una consulta
para visualizarlos en formato de tabla cruzada.

Como  ejemplo,  supongamos  que  tenemos  una  tabla  que  almacena  las  ventas  detalladas  por  código  de  país,
código de producto y año:

SQL> desc VENTAS;


Nombre NULL ? Tipo
-------------------------------------- --------------- ----------
CODIGOPAIS CHAR(2)
CODIGOPRODUCTO CHAR(4)
AÑO NUMBER(4)
CANTIDAD NUMERO(8)

Podemos  consultar  esta  tabla  para  generar  un  informe  que  permita  visualizar  las  ventas  acumuladas  por  país  y 
año: 

SQL> select AÑO, CODIGOPAIS, sum (CANTIDAD)


2 from VENTAS
3 group by AÑO, CODIGOPAIS
4 order by AÑO, CODIGOPAIS;

- 20 - © Éditions ENI – Todos los derechos reservados


AÑO CODIGOPAIS SUM(CANTIDAD)
------- ------------ -------------
2006 FR 1254878
2006 IT 8548778
2006 ES 45785
2007 ES 1254741
2007 FR 4528745
2007 IT 369858
2008 IT 5658747
2008 FR 4587854
2008 ES 1254774

8 filas seleccionadas.

Para  visualizar  el  resultado  en  formato  de  tabla  cruzada,  es  necesario  modificar  la  codificación  de  la  consulta  y 
utilizar la cláusula PIVOT. 

Ejemplo 

SQL> select * from (


2 select AÑO, CODIGOPAIS, CANTIDAD
3 from VENTAS
4 )
5 pivot
6 (
7 sum (CANTIDAD)
8 for CODIGOPAIS in (’FR’, ’ES’, ’IT’)
9 )
10 order by AÑO;

AÑO ’FR’ ’ES’ ’IT’


----- -------------------- ------------ -------------
2006 1254878 45785 8548778
2007 4528745 1254741 369858
2008 4587854 1254774 5658747

Sintaxis simplificada 

FROM tabla | subconsulta


PIVOT ( función_agregación(expresión)
FOR columna IN (valor [[AS] alias], ...)
)

La  cláusula  función_agregación(expresión)  permite  indicar  la  fórmula  de  cálculo  de  los  datos  que  se  van  a 
visualizar en la tabla cruzada; esta fórmula de cálculo debe utilizar una función de agregación (SUM, AVG, COUNT, 
etc.). 

La cláusula FOR permite indicar la columna del resultado de la consulta origen cuyos valores deben visualizarse en 
columnas  y  enumerar  los  valores  que  se  desean  visualizar.  Estos  valores  deben  conocerse  previamente;  no  es 
posible definirlos dinámicamente. En la lista de valores es posible definir alias para modificar el título de la columna 
visualizada. 

© Éditions ENI – Todos los derechos reservados - 21 -


Ejemplo 

SQL> select * from (


2 select AÑO, CODIGOPAIS, CANTIDAD
3 from VENTAS
4 )
5 pivot
6 (
7 sum (CANTIDAD)
8 for CODIGOPAIS in (’FR’ AS FRANCIA, ’ES’ AS ESPAÑA, ’IT’ AS ITALIA)
9 )
10 order by AÑO;

AÑO FRANCIA ESPAÑA ITALIA


-------------- ------------ ----------- -------------
2006 1254878 45785 8548778
2007 4528745 1254741 369858
2008 4587854 1254774 5658747

Existe  una  variante  de  la  sintaxis  que  permite  generar  el  resultado  en  formato  de  documento  XML.  Con  esta 
variante, la lista de valores puede no conocerse inicialmente. 

También existe una cláusula UNPIVOT que permite realizar la operación inversa: transformar una tabla cruzada en 
una tabla plana. 

Supongamos  que  tenemos  una  tabla  de  ventas  que  almacena  los  datos  en  formato  de  tabla  cruzada  (lo  que, 
desde un punto de vista conceptual, resulta extraño): 

SQL> desc VENTAS;


Nombre NULL ? Tipo
-------------------------------------- --------------- --------
AÑO NUMBER(4)
FRANCIA NUMBER
ESPAÑA NUMBER
ITALIA NUMERO

SQL> select * from VENTAS;

AÑO FRANCIA ESPAÑA ITALIA


-------- ---------------- ----------- -------------
2006 1254878 45785 8548778
2007 4528745 1254741 369858
2008 4587854 1254774 5658747

Para visualizar el resultado en formato de tabla, es necesario modificar la codificación de la consulta para utilizar la 
cláusula UNPIVOT. 

Ejemplo: 

SQL> select * from VENTAS

- 22 - © Éditions ENI – Todos los derechos reservados


2 unpivot
3 (
4 CANTIDAD
5 for CODIGOPAIS in (FRANCIA, ESPAÑA, ITALIA)
6 )
7 order by AÑO, CODIGOPAIS;

AÑO CODIGOPAIS SUM(CANTIDAD)


-------- --------------- ----------------------
2006 FR 1254878
2006 IT 8548778
2006 ES 45785
2007 ES 1254741
2007 FR 4528745
2007 IT 369858
2008 IT 5658747
2008 FR 4587854
2008 ES 1254774

9 filas seleccionadas.

Sintaxis simplificada 

FROM tabla | subconsulta


UNPIVOT [{INCLUDE / EXCLUDE} NULLS] (
título_columna_celda
FOR título_columna_pivotada IN (columna, ...)
)

título_columna_celda define el título de la columna que va a mostrar los datos, inicialmente presentes en la 
celda indicada de la tabla cruzada. 

La cláusula FOR permite indicar las columnas de la tabla cruzada de origen que deben convertirse en valores de 
una columna, cuyo título se indica en título_columna_pivotada. 

La cláusula INCLUDE NULLS permite incluir en el resultado las filas con valores nulos; por defecto, estas filas no se 
incluyen. 

Ejemplo de utilización de la cláusula INCLUDE NULLS 

SQL> select * from VENTAS


2 unpivot include nulls
3 (
4 CANTIDAD
5 for CODIGOPAIS in (FRANCIA, ESPAÑA, ITALIA)
6 )
7 order by AÑO, CODIGOPAIS;

AÑO CODIGOPAIS SUM(CANTIDAD)


-------- -------------- -------------
2006 FR 1254878
2006 IT 8548778
2006 ES 45785

© Éditions ENI – Todos los derechos reservados - 23 -


2006 FR
2007 ES 1254741
2007 FR 4528745
2007 IT 369858
2008 IT 5658747
2008 FR 4587854
2008 ES 1254774

10 filas seleccionadas.

e. Limitar el resultado de una consulta

Desde  la  versión  12,  Oracle  soporta  la  sintaxis  ANSI  que  permite  limitar  el  número  de  filas  devueltas  por  una
consulta y especificar la fila de inicio del resultado.

Sintaxis

SELECT ...
FROM ...
[WHERE ...]
[ORDER BY ...]
[cláusula_OFFSET] [cláusula_FETCH]

l cláusula_OFFSET: OFFSET n {ROW | ROWS}


l cláusula_FETCH:  FETCH {FIRST | NEXT} m [PERCENT] {ROW | ROWS} {ONLY | WITH
TIES}

Para  obtener  un  resultado  coherente,  es  necesario  especificar  una  cláusula  ORDER BY  para  asegurar  un  orden 
determinista. 

La cláusula OFFSET permite definir el número de filas (n) que hay que saltar antes de volver al resultado. Si esta 
cláusula  se  omite,  no  se  salta  ninguna  fila  (equivalente  a  OFFSET  0).  Las  palabras  clave  ROW  y  ROWS  son 
equivalentes. 

La  cláusula  FETCH  permite  definir  el  número  de  filas  (m)  o  el  porcentaje  de  filas  (m  PERCENT)  a  devolver.  Si  se 
omite esta cláusula, se devuelven todas las filas desde la fila n+1. Las palabras clave FIRST y NEXT, así como ROW 
y  ROWS,  son  equivalentes.  Con  la  palabra  clave  ONLY,  se  devuelve  el  número  exacto  de  filas  o  el  porcentaje 
exacto del número de filas. Con WITH TIES, las filas iguales desde un punto de vista del criterio de ordenación con 
la última fila seleccionada también se devuelve. 

Ejemplo 

SQL> -- Creación de una tabla (simplificada) de empleados.


SQL> create table EMPLEADOS (
2 numero number(3) generated as identity,
3 nombre varchar2(30));

Table creada.

SQL> insert into EMPLEADOS(nombre) values (’Ángel’);

1 fila creada.

- 24 - © Éditions ENI – Todos los derechos reservados


SQL> insert into EMPLEADOS(nombre) values (’Valeria’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’David’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Tomás’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Ana’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Felipe’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Raquel’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Pablo’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Juan’);

1 fila creada.

SQL> insert into EMPLEADOS(nombre) values (’Lucas’);

1 fila creada.

SQL> commit;

Validación realizada.

SQL> select * from EMPLEADOS;

NUMERO NOMBRE
---------- --------------------
1 Ángel
2 Valeria
3 David
4 Tomás
5 Ana
6 Felipe
7 Raquel
8 Pablo
9 Juan

© Éditions ENI – Todos los derechos reservados - 25 -


10 Lucas

10 filas seleccionadas.

SQL>
SQL> -- Selección de los 5 "primeros" empleados
SQL> -- (clasificación utilizando el número del empleado).
SQL> select * from EMPLEADOS
2 order by NUMERO
3 fetch first 5 rows only;

NUMERO NOMBRE
---------- --------------------
1 Ángel
2 Valeria
3 David
4 Tomás
5 Ana

SQL>
SQL> -- Selección de los 5 empleados siguientes.
SQL> select * from EMPLEADOS
2 order by NUMERO
3 offset 5 rows fetch next 5 rows only;

NUMERO NOMBRE
---------- --------------------
6 Felipe
7 Raquel
8 Pablo
9 Juan
10 Lucas

SQL>
SQL> -- Selección del 20% de los empleados
SQL> -- (clasificación por el nombre del empleado).
SQL> select * from EMPLEADOS
2 order by NOMBRE
3 fetch first 20 percent rows only;

NUMERO NOMBRE
---------- --------------------
5 Ana
3 David

Antes de la versión 12, era posible hacer lo mismo usando la función analítica ROW_NUMBER y una subconsulta: 

SQL> -- Selección de los 5 "primeros" empleados


SQL> -- (clasificación por el número de empleado).
SQL> select
2 NUMERO,
3 NOMBRE
4 from

- 26 - © Éditions ENI – Todos los derechos reservados


5 (
6 select
7 e.*,
8 row_number() over(order by e.NUMERO) r
9 from
10 EMPLEADOS e
11 )
12 where
13 r <= 5;

NUMERO NOMBRE
---------- ---------------
1 Ángel
2 Valeria
3 David
4 Tomás
5 Ana

SQL>
SQL> -- Selección de los 5 empleados siguientes.
SQL> select
2 NUMERO,
3 NOMBRE
4 from
5 (
6 select
7 e.*,
8 row_number() over(order by e.NUMERO) r
9 from
10 EMPLEADOS e
11 )
12 where
13 r <= 10
14 AND r > 5;

NUMERO NOMBRE
---------- ---------------
6 Felipe
7 Raquel
8 Pablo
9 Juan
10 Lucas

3. Bloqueo de tablas

En  las  transacciones  concurrentes  (acceso  a  los  mismos  datos  desde  transacciones  diferentes),  es  necesario 
conservar la coherencia de los datos. 

En  un  determinado  instante,  solo  se  autoriza  a  una  transacción  a  modificar  un  dato  (una  fila).  Las  restantes 
transacciones que deseen modificar la misma fila tienen que esperar (serialización de solicitudes) a que la primera 
transacción se complete. 

Para  permitir  esta  forma  de  operación,  Oracle  gestiona  simultáneamente  un  bloqueo  en  el  nivel  de  cada  fila  que 

© Éditions ENI – Todos los derechos reservados - 27 -


está siendo modificada y un bloqueo en el nivel de tabla. El bloqueo aplicado en el nivel de fila (bloqueo TX: Row 
exclusive) es un bloqueo de tipo exclusivo: si una transacción ha aplicado este bloqueo, ninguna otra podrá hacerlo 
antes de que el bloqueo sea liberado por la primera transacción (COMMIT o ROLLBACK). 

Los bloqueos de tabla pueden ser aplicados automáticamente por Oracle durante la ejecución de las instrucciones 
DML INSERT, UPDATE, DELETE y la instrucción PL/SQL SELECT ... FOR UPDATE o bien explícitamente por los usuarios 
mediante la instrucción LOCK TABLE. 

Tipos de bloqueo 

EXCLUSIVE (X) 

La aplicación de este tipo de bloqueo sobre una tabla impide que cualquier otra transacción aplique 
explícitamente un bloqueo sobre dicha tabla y que acceda a dicha tabla en proceso de modificación. 

SHARE (S) 

La aplicación de este tipo de bloqueo sobre una tabla impide que cualquier otra transacción aplique un 
bloqueo que no sea de tipo SHARE (compartir) sobre la tabla y que acceda a dicha tabla en proceso de 
modificación. 

ROW SHARE (RS) 

La aplicación de este tipo de bloqueo sobre una tabla permite el acceso concurrente a la misma 
(modificación de filas diferentes en cada una de las transacciones) e impide que cualquier otra 
transacción aplique sobre esta tabla un bloqueo de tipo exclusivo. Se trata de un bloqueo tentativo. 

ROW EXCLUSIVE (RX) 

La aplicación de este tipo de bloqueo sobre una tabla indica que hay filas de la misma que han sido 
modificadas por una instrucción DML. Impide la aplicación de un bloqueo exclusivo por parte de otra 
transacción. 

SHARE ROW EXCLUSIVE (SRX) 

La aplicación de este tipo de bloqueo sobre una tabla impide que una transacción aplique un bloqueo 
que no sea un bloqueo tentativo RS. 

Las instrucciones DML INSERT, UPDATE y DELETE aplican automáticamente un bloqueo de tipo RX sobre la tabla que 
se está modificando. Una instrucción SELECT... FROM ... FOR UPDATE en un bloque PL/SQL da lugar a la aplicación de 
un bloqueo de tipo S sobre la tabla. 

Lock

Sintaxis 

LOCK TABLE {tabla / vista} IN{EXCLUSIVE / SHARE / ROW SHARE / ROW EXCLUSIVE /
SHARE ROW EXCLUSIVE} MODE [NOWAIT / WAIT n];

Ejemplo 

Sesión 1: La transacción bloquea la tabla PEDIDOS de forma exclusiva. 

- 28 - © Éditions ENI – Todos los derechos reservados


SQL> lock table PEDIDOS in EXCLUSIVE mode;

Tabla(s) bloqueada(s).

SQL>

Sesión 2: Intento de actualizar una fila de la tabla PEDIDOS. La instrucción espera a que la tabla quede desbloqueada. 

SQL> insert into PEDIDOS (NUMPED, NUMCLI, FECHAPED, ESTADOPED)


2 values (3001, 35, SYSDATE, ’EC’);

Sesión 1: Inserción de una fila y validación de la transacción. 

SQL> insert into PEDIDOS (NUMPED, NUMCLI, FECHAPED, ESTADOPED)


2 values (3001, 35, SYSDATE, ’EC’);

1 fila creada.

SQL> commit;

Validación terminada.

SQL>

Sesión 2: La instrucción de inserción se ejecuta, pero se genera un error, ya que el mismo dato acaba de ser insertado en la 
otra sesión. 

SQL> insert into PEDIDOS (NUMPED, NUMCLI, FECHAPED, ESTADOPED)


2 values (3001, 35, SYSDATE, ’EC’);
insert into PEDIDOS (NUMPED, NUMCLI, FECHAPED, ESTADOPED)
*
ERROR en línea 1:
ORA-00001: restricción única (SCOTT.PEDIDOS_PK) violada

SQL>

4. Comentarios

Con el fin de facilitar las operaciones de actualización de la base de datos, se pueden incluir comentarios acerca de 
las  tablas  y  las  vistas,  así  como  sobre  cada  columna  que  forma  parte  de  dichas  tablas  y  vistas.  La  inclusión  de 
comentarios constituye una etapa indispensable, ya que permite conocer de forma exacta el significado y la función 
de cada elemento de la base de datos. Todos estos comentarios se almacenan en un diccionario de datos y están 
accesibles a través de determinadas vistas del diccionario. 

Para  añadir  un  comentario  sobre  las  columnas  no  es  imprescindible  haber  incluido  anteriormente  un  comentario 
sobre la tabla o la vista. 

© Éditions ENI – Todos los derechos reservados - 29 -


COMMENT

Sintaxis 

COMMENT ON TABLE nombre_tabla_vista IS ’texto’;


COMMENT ON COLUMN nombre_tabla_vista.nombre_columna IS ’texto’;

Ejemplo 

Especificación de un comentario sobre la tabla CLIENTES: 

SQL> comment on table CLIENTES


2 IS ’Clientes de la empresa’;

Comentario creado.

SQL>

A continuación se especifica un comentario sobre la columna direccli, con el fin de explicar qué datos contiene dicha columna: 

SQL> comment on column CLIENTES.DIRECCLI


2 IS ’Dirección del cliente’;

Comentario creado.

SQL>

Para ver los comentarios, hay que consultar el diccionario: 

SQL> select comments


2 from user_tab_comments
3 where table_name=’CLIENTES’;

COMMENTS
--------------------------------------------------------------
Clientes de la empresa

SQL>

Las  vistas  ALL_COL_COMMENTS  y  USER_COL_COMMENTS  contienen  los  comentarios  definidos  en  el  nivel  de 
columna. 

5. Información sobre los objetos del esquema

El  diccionario  de  datos  contiene  muchas  vistas  que  proporcionan  información  detallada  sobre  los  diferentes 
elementos presentes en el esquema. 

- 30 - © Éditions ENI – Todos los derechos reservados


Entre las vistas más utilizadas pueden citarse las siguientes: 

ALL_OBJECTS, USER_OBJECTS 

ALL_CATALOG, USER_CATALOG 

ALL_TABLES, USER_TABLES 

ALL_TAB_COLUMNS, USER_TAB_COLUMNS 

ALL_TAB_COMMENTS, USER_TAB_COMMENTS 

ALL_COL_COMMENTS, USER_COL_COMMENTS 

ALL_VIEWS, USER_VIEWS 

ALL_INDEXES, USER_INDEXES 

ALL_IND_COLUMNS, USER_IND_COLUMNS 

ALL_SEQUENCES, USER_SEQUENCES 

ALL_SYNONYMS, USER_SYNONYMS 

ALL_DEPENDENCIES, USER_DEPENDENCIES 

Todas estas vistas pueden recuperarse realizando una consulta sobre la vista DICT, la cual enumera todas las vistas 
que constituyen el diccionario, junto con un comentario que indica su papel. 

Ejemplo 

La vista USER_TABLES se utiliza para saber cuáles son todas las tablas del usuario actual. 

SQL> select table_name


2 from user_tables;

TABLE_NAME
-------------------------
ARTICULOS
CLIENTES
CLIVARIOS
DEPOSITO
EMPLEADOS
EXCEPTIONS
FACTURA
NOMENCLATURA
PEDIDOS
PRODUCTOS

10 filas seleccionadas.

SQL>

© Éditions ENI – Todos los derechos reservados - 31 -


6. Funcionalidades específicas

NLS

Hay determinadas funciones que responden de forma diferente dependiendo del idioma seleccionado en el servidor 
de Oracle. En Oracle, todos estos criterios vienen determinados por los parámetros NLS (National Language Support). 
Estos parámetros afectan fundamentalmente a la presentación de los datos de tipo fecha (date) y de tipo numérico. 

Todas  las  funciones  SQL  que  dependen  de  NLS  permiten  tener  en  cuenta  un  parámetro  NLS  determinado.  Estas 
funciones son: TO_CHAR, TO_DATE, TO_NUMBER, NLS_UPPER, NLS_LOWER, NLS_INITCAP, NLSSORT. 

El principal interés de establecer el parámetro NLS en el nivel de función es reemplazar la opción definida en el nivel 
de sesión. 

Ejemplo 

Uso de parámetros NLS en una función. Para comparar dos fechas, el siguiente ejemplo convierte la fecha de referencia, que se 
proporciona como cadena de caracteres, en un dato de tipo fecha (Date). Para llevar a cabo esta conversión se utiliza la función 
TO_DATE. Además de la cadena de caracteres que contiene la fecha, esta función recibe otros dos parámetros: el formato de 
fecha y el parámetro de tipo NLS que indica el idioma en el que se expresa la fecha. 

SQL> select numped


2 FROM pedidos
3 WHERE fechaped>TO_DATE(’25-APR-2001’,’DD-MON-YYYY’,
4 ’NLS_DATE_LANGUAGE=AMERICAN’);

NUMPED
----------
3
8
10
11

SQL>

Lista de los diferentes parámetros NLS disponibles para las funciones SQL: 

Funciones SQL  Parámetros NLS 

TO_DATE  NLS_DATE_LANGUAGE 
NLS_CALENDAR 

TO_NUMBER  NLS_NUMERIC_CHARACTERS 
NLS_CURRENCY  
NLS_DUAL_CURRENCY  
NLS_ISO_CURRENCY 

TO_CHAR  NLS_DATE_LANGUAGE 
NLS_NUMERIC_CHARACTERS 
NLS_CURRENCY  
NLS_DUAL_CURRENCY  
NLS_ISO_CURRENCY  
NLS_CALENDAR 

- 32 - © Éditions ENI – Todos los derechos reservados


NLS_UPPER  NLS_SORT 

NLS_LOWER  NLS_SORT 

NLS_INITCAP  NLS_SORT 

En el siguiente listado se ilustran diferentes ejemplos de uso de los parámetros NLS: 

TO_CHAR(fechaped,’DD/MON/YYYY’,’NLS_DATE_LANGUAGE=FRENCH’)
TO_NUMBER(’15.999,80’,’9G999D99’,’NLS_NUMERIC_CHARACTERS=’’,.’’’)
TO_CHAR(precio,’9G999D99F’,’NLS_NUMERIC_CHARACTERS=’’,.’’
NLS_ISO_CURRENCY=Japan’)
NLS_UPPER(nomcli, ’NLS_SORT=SWISS’)
NLSSORT(nomcli,’NLS_SORT=GERMAN’)

Case

La  instrucción  CASE  permite  especificar  una  condición  de  una  instrucción  condicional  directamente  en  la  consulta 
SELECT, sin tener que llamar a un bloque de instrucciones procedimentales. 

El principal interés de esta instrucción es facilitar la presentación y dar formato a los resultados directamente en las 
consultas  SELECT.  La  instrucción  CASE  también  permite  limitar  el  número  de  veces  que  es  necesario  llamar  a  un 
bloque PL/SQL para resolver el problema. 

La  instrucción  CASE  tiene  un  límite  de  128  opciones.  Para  poder  sobrepasar  este  límite,  es  necesario  anidar  las 
instrucciones. 

Sintaxis 

CASE expresión
WHEN expresión_comparación1 THEN expresión_devuelta1
WHEN expresión_comparación2 THEN expresión_devuelta2
....
[ELSE expresión_devuelta]
END

CASE
WHEN condición1 THEN expresión_devuelta1
WHEN condición2 THEN expresión_devuelta2
....
[ELSE expresión_devuelta]
END

La instrucción ELSE es opcional y, en el caso de que esta condición no se especifique, el valor devuelto es NULL si no 
se ha ejecutado ninguna instrucción WHEN ... THEN. 

Ejemplo 

El siguiente ejemplo permite saber el nombre de la región de los clientes a partir del código postal: 

SQL> select numcli, nomcli, case to_number(substr(cod_postal,1,2))


2 when 32 then ’Galicia’

© Éditions ENI – Todos los derechos reservados - 33 -


3 when 28 then ’Madrid’
4 else ’Otro’ END as region
5 from clientes;

NUMCLI NOMCLI REGION


----------- ------------------------------ -------
15 Gómez S.A. Galicia
20 M. García Otro
35 Martín Juan Galicia
36 DEL PINO S.A. Otro
152 LACALLE Madrid
138 Martín Juan Otro
37 E. LACALLE Otro

7 filas seleccionadas.

SQL>

En este otro ejemplo, se realiza la conversión del código postal dentro de la cláusula WHEN: 

SQL> select numcli, nomcli, case


2 when to_number(substr(cod_postal,1,2)) in (32,27)
3 then ’Galicia’
4 else ’Otro’ END as region
5 from clientes;

NUMCLI NOMCLI REGION


---------- ------------------------------ -------
15 Gómez S.A. Galicia
20 M. García Otro
35 Martín Juan Galicia
36 DEL PINO S.A. Otro
152 LACALLE Otro
138 Martín Juan Otro
37 E. LACALLE Galicia

7 filas seleccionadas.

SQL>

7. Las expresiones regulares

Las expresiones regulares representan una potente herramienta para trabajar con las cadenas de caracteres. Esta 
funcionalidad está ya presente en muchos lenguajes de programación y en Unix. 

Las consultas de extracción de datos con criterios muy precisos de selección sobre los datos de tipo carácter podrán 
escribirse más fácilmente. 

Para poder trabajar con las expresiones regulares, Oracle propone un operador REGEXP_LIKE y cuatro funciones: 
REGEXP_INSTR, REGEXP_SUBSTR, REGEXP_REPLACE y REGEXP_COUNT. 

- 34 - © Éditions ENI – Todos los derechos reservados


Las  expresiones  regulares  describirán  mediante  metacaracteres  la  estructura  que  debe  poseer  la  cadena  de 
caracteres con la que se quiere trabajar. 

Aunque los diferentes metacaracteres se presentan a continuación, es preferible trabajar con algunos ejemplos de 
expresiones regulares para comprender bien cómo funcionan. 

Las anclas 

ˆ  marca el principio de línea 

$  marca el fin de línea 

Los cuantificadores 

*  corresponde a 0 o más caracteres. 

?  corresponde a 0 o 1 carácter. 

+  corresponde a 1 o más caracteres. 

{m} corresponde a m caracteres exactamente.

{m,}  corresponde al menos a m caracteres.

{m, n}  corresponde al menos a m caracteres, pero menos de n caracteres.

Hay que prestar atención a la manipulación de estos metacaracteres porque no poseen necesariamente el mismo 
sentido que los utilizados con el operador LIKE. 

El carácter . permite señalar la existencia de cualquier carácter en la cadena. 

Por ejemplo, la expresión regular a.l puede corresponder a las cadenas de caracteres apl, agl... pero también tabla, 
estable,  allí.  En  efecto,  en  la  expresión  regular  solo  se  estipula  que  las  letras  a  y  l  deben  ir  separadas  por  un 
carácter exactamente. En ningún caso se dice que la cadena de caracteres deba empezar por la letra a y terminar 
por la letra l. Si se quiere este escenario, hay que utilizar las anclas para precisar el carácter que marca el principio 
de  la  cadena.  La  expresión  regular  ˆa.l  precisa  que  la  cadena  de  caracteres  buscada  debe  empezar 
obligatoriamente por la letra a, como por ejemplo apl, agl, allí... 

De modo predeterminado, los caracteres presentes en la expresión regular solo deben estar presentes una vez en 
la cadena de caracteres. Así, la expresión regular ˆa.*e$ significa que se busca una cadena que empieza por la letra 
a y termina por la letra e. Entre el primer y el último carácter es posible tener entre 0 y n caracteres. Las cadenas 
ae, ane, anime... responden a esta expresión. 

Para  permitir  la  construcción  de  expresiones  aún  más  complejas,  Oracle  soporta  las  clases  de  caracteres  POSIX 
(Portable Operating System Interface). Gracias a esta clase de caracteres será posible escribir expresiones regulares 
extremadamente precisas para encontrar solo la información deseada. 

Las clases de caracteres POSIX se enumeran en la siguiente tabla: 

[:alpha:]  carácter alfabético 

[:lower:]  carácter alfabético en minúsculas 

[:upper:]  carácter alfabético en mayúsculas 

[:digit:]  número 

[:alnum:]  carácter alfanumérico 

[:space:]  espacio 

© Éditions ENI – Todos los derechos reservados - 35 -


[:punct:]  signo de puntuación 

[:cntrl:]  carácter de control no imprimible 

[:print:]  carácter imprimible 

Estas diferentes clases de caracteres permiten cubrir todos los caracteres presentes en la tabla ASCII. 

Para  poder  utilizar  las  clases  de  caracteres  POSIX  en  las  expresiones  regulares,  es  necesario  posicionarlas  entre 
corchetes []. 

Por  ejemplo,  la  expresión  [[:upper:]]  permite  buscar  una  cadena  de  caracteres  escrita  únicamente  en  mayúsculas 
mientras que [[:lower:]]{5} corresponde a palabras de 5 letras en minúsculas. 

Para afinar las búsquedas, es posible citar una lista de caracteres que se quiere ver aparecer en una ubicación en 
particular. Por ejemplo la expresión ˆpla[tc]a$ permite identificar tanto plata como placa. 

Finalmente, y aquí reside a menudo la dificultad en la escritura de expresiones regulares, ciertos metacaracteres no 
tienen el mismo sentido según su ubicación. Es el caso de los 2 metacaracteres ˆ y ­. 

El carácter ˆ cuando se ubica como primer carácter de una expresión marca el inicio de la expresión, por el contrario 
cuando aparece como primer carácter de una lista de valores marca la negación. 

Por ejemplo, ˆA[[:lower:]] corresponde a las cadenas Ana, Anillo, Arbóreo, Aviso... Por el contrario, la expresión ˆA
[ˆnop][[:lower:]] permite simplemente extraer Arbóreo, Amigo, Aviso... 

El carácter ­ permite simplificar la escritura de rangos de valores citando simplemente el primer y el último caracteres 
separados  por  ­.  Por  ejemplo  en  la  expresión  ˆA[n­p][[:lower:]]  permite  identificar  las  cadenas  siguientes:  Ana, 
Anillo, Apero... 

Por el contrario, si se encuentra como primer carácter de una lista, señala que los caracteres siguientes no pueden 
participar de la cadena final. 

Por tanto, la expresión ˆA[­nop][[:lower:]] permite identificar Aviso, Amigo, Arbóreo... 

REGEXP_LIKE 

Este operador permite el uso de expresiones regulares para la búsqueda en las cláusulas WHERE o bien al construir 
restricciones de integridad. 

Sintaxis simplificada 

REGEXP_LIKE(columna, expresión_regular)

Ejemplo 

En el ejemplo siguiente, se busca los clientes cuyo nombre empiece por B seguido de caracteres en minúsculas: 

SQL> select numcli, nomcli


2 from clientes
3 where regexp_like(nomcli, ’ˆB[[:lower:]]’);

NUMCLI NOMCLI
-------------------------

- 36 - © Éditions ENI – Todos los derechos reservados


36 Bernardo S.A.

SQL>

Pero el operador REGEXP_LIKE puede utilizarse también para definir restricciones de integridad muy precisas. 

Por  ejemplo,  si  se  quiere  que  los  2  primeros  caracteres  de  una  referencia  de  artículo  sean  siempre  caracteres  alfabéticos  en 
mayúsculas, es posible agregar la restricción de integridad siguiente a la tabla de artículos: 

SQL> alter table articulos


2 add constraint ck_refart
3 check(regexp_like(refart, ’ˆ[[:upper:]]{2,}’));

Table altered.

SQL>

REGEXP_REPLACE 

La  función  REPLACE  en  SQL  permite  sustituir  una  cadena  de  caracteres  por  otra.  Pero  el  uso  de  esta  función 
requiere  conocer  exactamente  la  cadena  a  reemplazar,  cosa  que  no  siempre  ocurre.  La  función  REGEXP_REPLACE 
por su parte se sirve simplemente de una descripción de la cadena a reemplazar. 

Sintaxis simplificada 

REGEXP_REPLACE(cadena, expresión_regular,
cadena_de_reemplazo)

Ejemplo 

Por ejemplo cuando se quiere eliminar los espacios inútiles en una cadena de caracteres, la única certeza que se tiene es que si 
hay más de un espacio (2, 3 o más) entonces es posible eliminar los espacios inútiles: 

SQL> select regexp_replace(nomcli,’( ){2,}’,’ ’) as nomcli


2 from clientes;

NOMCLI
----------------------------------------------------------
GOMEZ S.A.
M. GARCIA
MARTÍN Juan
Bernardo S.A.
PLAZA S.A.
MARTÍN Juan
LACALLE

7 rows selected.

SQL>

© Éditions ENI – Todos los derechos reservados - 37 -


En el ejemplo anterior, los espacios inútiles se suprimen del nombre del cliente. 

REGEXP_INSTR 

Esta  función,  cuyo  objetivo  es  el  mismo  que  INSTR,  permite  localizar  la  ubicación  de  partida  de  una  subcadena 
dentro de una cadena. La ventaja reside en el hecho de que no es necesario citar la subcadena, sino que basta con 
describirla mediante una expresión regular para localizarla. 

Sintaxis simplificada 

REGEXP_INSTR(cadena, expresión_regular)

Ejemplo 

En el ejemplo siguiente se quiere conocer la posición de la subcadena S.A. en el nombre de los clientes: 

SQL> select nomcli, regexp_instr(nomcli, ’S.A.$’) as posicion


2 from clientes;

NOMCLI POSICION
-------------------------- ---------------
GOMEZ S.A. 7
M. GARCIA 0
MARTÍN Juan 0
Bernardo S.A. 10
PLAZA S.A. 7
MARTÍN Juan 0
LACALLE 0

7 rows selected.

SQL>

REGEXP_SUBSTR 

Como para la función SUBSTR, el objetivo de REGEXP_SUBSTR es extraer una subcadena a partir de una cadena de 
caracteres,  pero  describiendo  la  subcadena  extraída  mediante  una  expresión  regular.  Esto  permite  extraer  la 
subcadena sin conocer su posición exacta, ni siquiera su longitud. 

Sintaxis simplificada 

REGEXP_SUBSTR(cadena, expresión_regular)

Ejemplo: 

En el ejemplo siguiente, se extraen los apellidos de clientes que empiezan por LA: 

SQL> select nomcli, regexp_substr(nomcli, ’LA.*’)


2 from clientes

- 38 - © Éditions ENI – Todos los derechos reservados


3 ;

NOMCLI REGEXP_SUBSTR(NOMCLI,’LA.*’)
---------------------- ---------------------------------------
GOMEZ S.A.
M. GARCIA
MARTÍN Juan
Bernardo S.A.
LA PLAZA LA PLAZA
MARTÍN Juan
LACALLE LACALLE

7 rows selected.

SQL>

REGEXP_COUNT 

REGEXP_COUNT indica el número de veces que se encuentra una expresión regular en una cadena. Si la expresión 
regular no se encuentra en la cadena, entonces la función devuelve 0. 

Sintaxis simplificada 

REGEXP_COUNT(cadena, expresión_regular)

Ejemplo: 

Contar el número de palabras de una frase: 

SQL> select
2 regexp_count(’érase una vez’,’[[:alnum]]+’) numero_palabras
3 from dual;

NUMERO_PALABRAS
-------------------
3

© Éditions ENI – Todos los derechos reservados - 39 -

También podría gustarte