Está en la página 1de 331

PEDRO SALGUEIRO GMEZ

2011
Tabla de contenidos

I. NOCIONES SOBRE BASES DE DATOS Y ORACLE 6 6.1. Reunin de una tabla consigo misma. .............................. 78
1. Arquitectura de Oracle Database 11g....................................... 6 6.2. Consultas de unin internas. ............................................ 78
1.1. Fundamentos de bases de datos. ........................................ 6 6.3. Consultas con operaciones de conjuntos........................... 80
1.2. Fundamentos de bases de datos relacionales....................... 8 7. Agrupaciones ....................................................................... 80
1.3. Bases de datos e instancias en Oracle. .............................. 11 7.1. Funciones de agregado. ................................................... 80
1.4. Organizacin de las bases de datos en Oracle. .................. 11 7.2. La clusula Group by. ................................................. 83
1.5. Seleccin de arquitecturas y opciones. ............................. 14 8. Subconsultas ........................................................................ 84
2. Instalar Oracle Database 11g y crear una base de datos .......... 15 8.1. Introduccin. .................................................................. 84
2.1. Descripcin de la licencia y opciones de instalacin. ........ 15 8.2. Recuperacin de datos con subconsulta............................ 84
3. Servidor de Oracle ................................................................ 24 8.3. Subconsultas correlacionadas. ......................................... 85
3.1. Elementos del servidor Oracle ......................................... 24 8.4. Subconsultas con operador de comparacin distinto de
3.2. Conexiones. .................................................................... 24 IN. .................................................................................... 85
3.3. Estructura de las bases de datos Oracle. ........................... 25 8.5. Funciones de agregado en subconsultas. .......................... 86
3.4. Instancia de la base de datos. ........................................... 25 8.6. Subconsultas con EXISTS. .......................................... 86
3.5. Procesamiento de instrucciones SQL. .............................. 26 8.7. Expresiones de columna con subconsultas ....................... 86
3.6. Archivos de inicializacin ............................................... 27 8.8. Subconsultas como origen de registros para FROM. ..... 87
3.7. Arranque y parada de la base de datos.............................. 28 9. Vistas ................................................................................... 87
4. Introduccin a los conceptos del sistema Oracle .................... 29 9.1. Introduccin. .................................................................. 87
4.1. Almacenamiento. ............................................................ 29 9.2. Crear y consultar vistas. .................................................. 88
4.2. Transacciones. ................................................................ 29 9.3. Ejecucin de comandos DML sobre vistas. ...................... 88
4.3. Usuarios. ........................................................................ 29 9.4. Estabilidad de una vista. .................................................. 88
4.4. Prdidas de informacin. ................................................. 30 9.5. Mostrar la lista de vistas. ................................................. 89
4.5. Copias de seguridad. ....................................................... 30 9.6. Borrar vistas. .................................................................. 89
4.6. Bases de datos distribuidas. ............................................. 30 10. Comandos internos en SQL*PLUS e iSQL*Plus .................. 89
4.7. Herramientas de Oracle. .................................................. 30 10.1. Variables de sustitucin................................................. 89
II. LENGUAJE DE CONSULTAS.................................. 32 10.2. Comando SET. .......................................................... 90
1. SQL para Oracle ................................................................... 32 10.3. Encabezado y pie de informe. ........................................ 90
1.1. Introduccin. .................................................................. 32 10.4. Comando COLUMN. ................................................ 91
1.2. Cdigo SQL y normas de escritura. ................................. 32 10.5. Comando BREAK. .................................................... 91
1.3. SQL*Plus. ...................................................................... 32 10.6. Comando COMPUTE. .............................................. 92
1.4. Versin grfica de SQL*Plus. ......................................... 33 10.7. Guardar consultas en ficheros. ....................................... 93
1.5. iSQL*Plus. ..................................................................... 33 10.8. Redirigir la salida de SQL*Plus con SPOOL. ............. 93
2. Estructura del lenguaje SQL.................................................. 34 11. Consultas avanzadas ........................................................... 94
2.1. Tipos de datos................................................................. 34 11.1. Consultas con ROWNUM. ........................................ 94
2.2. Operadores ..................................................................... 35 11.2. Consultas con ROWID. ............................................. 94
2.3. Funciones predefinidas.................................................... 36 11.3. Consultas con RANK. ............................................... 95
3. Trabajando con objetos ......................................................... 52 11.4. Consultas sobre estructuras jerrquicas. ......................... 96
3.1. Introduccin. .................................................................. 52 11.5. Consultas de agrupacin avanzada. ................................ 98
3.2. Diccionario de datos de Oracle. ....................................... 52 III. PL/SQL.................................................................... 101
3.3. Crear y usar bases de datos. ............................................. 53 1. Estructura del lenguaje PL/SQL .......................................... 101
3.4. Crear y usar tablespaces. ................................................. 53 1.1. Fundamentos de PL/SQL. ............................................. 101
3.5. Crear esquemas............................................................... 55 1.2. Estructuras de control en PL/SQL. ................................. 102
3.6. Crear y usar tablas. ......................................................... 56 2. Bloques PL/SQL................................................................. 103
3.7. Restricciones. ................................................................. 59 2.1. Introduccin. ................................................................ 103
3.8. Crear y eliminar ndices. ................................................. 61 2.2. Estructura de un Bloque. ............................................... 103
3.9. Uso de tablas particionadas. ............................................ 64 2.3. Seccin de declaracin de variables. .............................. 104
3.10. Clsteres (o cubos)........................................................ 67 2.4. El paquete DBMS_OUTPUT. .................................... 105
3.11. Secuencias. ................................................................... 68 2.5. Asignacin de variables................................................. 106
3.12. Sinnimos..................................................................... 69 3. Excepciones en PL/SQL. .................................................... 107
3.13. Insercin de registros. ................................................... 69 3.1. Manejo de excepciones. ................................................ 107
3.14. Actualizacin de registros. ............................................ 72 3.2. Excepciones predefinidas. ............................................. 107
3.15. Eliminacin de registros. ............................................... 72 3.3. Excepciones definidas por el usuario. ............................ 108
3.16. Combinar registros con MERGE. .................................. 73 3.4. Uso de SQLCODE y SQLERRM. .......................... 109
4. Consultas de seleccin .......................................................... 73 3.5. Excepciones personalizadas en PL/SQL. ........................ 109
4.1. Consultas bsicas. ........................................................... 74 3.6. Propagacin de excepciones en PL/SQL. ....................... 109
4.2. Alias............................................................................... 74 4. Cursores ............................................................................. 109
4.3. Ordenar los registros. ...................................................... 74 4.1. Cursores implcitos. ...................................................... 110
4.4. Consultas con predicado.................................................. 75 4.2. Cursores explcitos. ....................................................... 110
4.5. Recuperacin de valores calculados. ................................ 75 4.3. Cursores con parmetros. .............................................. 111
4.6. La clusula WHERE. .................................................. 76 4.4. Cursores de actualizacin. ............................................. 111
4.7. Consultas que incluyen nulos .......................................... 76 5. Subprogramas en PL/SQL................................................... 112
5. Criterios de seleccin............................................................ 76 5.1. Permisos requeridos. ..................................................... 112
5.1. Operadores lgicos. ........................................................ 76 5.2. Procedimientos, funciones y paquetes. ........................... 113
5.2. Intervalos de valores. ...................................................... 77 5.3. Procedimientos almacenados. ........................................ 113
5.3. El operador Like. ........................................................ 77 5.4. Funciones en PL/SQL. .................................................. 114
5.4. El operador In. ............................................................ 77 5.5. Subprogramas en bloques procedimentales. ................... 115
6. Consultas sobre ms de una tabla .......................................... 78 5.6. Depurando procedimientos. ........................................... 115
5.7. Paquetes en PL/SQL. .................................................... 115 4.5. Cmo usar grupos de polticas. ...................................... 187
5.8. Viendo el cdigo fuente de objetos procedimentales....... 118 5. Trabajando con espacios de tabla......................................... 187
5.9. Compilando procedimientos, funciones y paquetes......... 118 5.1. Tablespaces y la estructura de las bases de datos. ........... 188
6. Transacciones..................................................................... 119 5.2. Planificando el uso de nuestro tablespace. ...................... 196
6.1. Estado de los datos durante la transaccin. ..................... 119 6. Usar SQL*Loader para cargar datos .................................... 197
6.2. Control de transacciones en PL/SQL. ............................ 119 6.1. El fichero de control...................................................... 197
6.3. Puntos de ruptura. ......................................................... 120 6.2. Comienzo de la carga. ................................................... 199
6.4. Transacciones autnomas .............................................. 120 6.3. Sobre la sintaxis del fichero de control. .......................... 201
7. Triggers ............................................................................. 121 6.4. Administracin de la carga de datos. .............................. 202
7.1. Permisos requeridos. ..................................................... 121 6.5. Ajustar la carga de datos. .............................................. 203
7.2. Tipos de triggers. .......................................................... 121 6.6. Funcionalidades adicionales. ......................................... 205
7.3. Triggers asociados a tablas. ........................................... 122 7. Importar y exportar con Data Pump ................................. 205
7.4. Triggers para eventos DDL. .......................................... 125 7.1. Creando un directorio.................................................... 205
7.5. Triggers para eventos del sistema. ................................. 128 7.2. Opciones de Data Pump Export. ................................ 206
7.6. Triggers de sustitucin. ................................................. 129 7.3. Iniciando una tarea de Data Pump Export. .................. 207
7.7. Activar y desactivar triggers. ......................................... 130 7.4. Opciones para Data Pump Import. ............................. 210
8. Tipos de datos complejos y operaciones masivas. ................ 131 7.5. Iniciando una tarea de Data Pump Import. .................. 211
8.1. Registros (RECORD).................................................... 131 8. Acceso a datos remotos ....................................................... 214
8.2. Arrays asociativos (TABLE). ........................................ 132 8.1. Enlaces de base de datos. .............................................. 214
8.3. Arrays variables (VARRAY)......................................... 133 8.2. Usando sinnimos para transparencia de localizacin. .... 218
8.4. Acceso masivo a los datos (BULK COLLECT). ............ 135 8.3. Usando la pseudo-columna USER en vistas................ 219
8.5. Funciones en lnea. ....................................................... 136 8.4. Enlaces dinmicos: usando el comando de copia de
8.6. Instruccin FORALL. ............................................... 137 SQL*Plus............................................................................ 220
8.7. Objetos grandes (LOB). ................................................ 138 8.5. Conectndose a una base de datos remota. ..................... 221
9. SQL Dinmico ................................................................... 142 9. Vistas materializadas. ......................................................... 222
9.1. Sentencias DML con SQL dinmico. ............................. 143 9.1. Funcionalidad. .............................................................. 222
9.2. Cursores con SQL dinmico. ......................................... 143 9.2. Permisos requeridos. ..................................................... 222
9.3. Un ejemplo de cmo usar y cmo no usar SQL dinmico.146 9.3. Solo-lectura contra actualizable. .................................... 223
10. PL/SQL y Java ................................................................. 146 9.4. Sintaxis de creacin de vistas materializadas. ................. 223
10.1. Creacin de Objetos Java en la base de datos ORACLE.146 9.5. Usando vistas materializadas para modificar rutas de
10.2. Ejecucin de programas Java con PL/SQL ................... 147 ejecucin de consultas. ........................................................ 227
10.3. Correspondencia de tipos entre Java y Oracle. .............. 148 9.6. Usando DBMS_ADVISOR. ...................................... 228
10.4. Paso de cursores Oracle a mtodos de Java. ................. 148 9.7. Refrescando vista materializadas. .................................. 229
10.5. Paso de objetos Oracle a mtodos de Java. ................... 149 9.8. Sintaxis para crear registros de vista materializada. ........ 233
10.6. Paso de arrays desde un programa Java a un 9.9. Modificando vistas materializadas y registros. ............... 234
procedimiento almacenado de Oracle. .................................. 150 9.10. Eliminando vistas materializadas y registros. ............... 234
10.7. Cmo pasar y retornar un array de objetos a travs de un 10. Oracle Text....................................................................... 235
procedimiento almacenado................................................... 151 10.1. Aadiendo texto a la base de datos. .............................. 235
10.8. Paquete DBMS_JAVA. ........................................... 152 10.2. Consultas de texto e ndices de texto. ........................... 235
IV. CARACTERSTICAS DE ORACLE GRID........... 155 10.3. Conjuntos de ndices. .................................................. 243
1. Arquitectura de Rejilla ........................................................ 155 11. Uso de tablas externas....................................................... 244
1.1. Hardware y elementos de configuracin del sistema 11.1. Accediendo a datos externos. ....................................... 244
operativo. ............................................................................ 155 11.2. Creando una tabla externa. .......................................... 245
1.2. Aadiendo servidores a la rejilla. ................................... 157 11.3. Modificacin de tablas externas. .................................. 250
1.3. Compartir datos entre la rejilla. ..................................... 157 11.4. Limitaciones, beneficios y usos potenciales de las tablas
1.4. Administracin de la rejilla. .......................................... 158 externas............................................................................... 251
1.5. Lanzar OEM. ................................................................ 159 12. Consultas flashback .......................................................... 252
2. Oracle Real Application Clusters ........................................ 160 12.1. Ejemplo de consulta flashback basada en el tiempo. ..... 253
2.1. Pasos de preinstalacin. ................................................ 160 12.2. Guardando los datos. ................................................... 254
2.2. Instalacin de RAC. ...................................................... 161 12.3. Ejemplo de consulta flashback basada en SCN. ............ 254
2.3. Inicia y parar instancias RAC. ....................................... 163 12.4. Qu ocurre si falla una consulta flashback? ................ 255
2.4. Transparencia de sobrefallos de aplicacin..................... 164 12.5. Qu SCN est asociado con cada registro? ................. 255
2.5. Aadir nodos e instancias a un clster. ........................... 165 12.6. Consultas de versin flashback. ................................... 256
2.6. Administracin de registro y servicios del clster. .......... 165 12.7. Planificacin de las consultas flashback. ...................... 257
3. Seguridad en Oracle ........................................................... 166 13. Tablas y bases de datos flashback ...................................... 258
3.1. Creacin de usuarios. .................................................... 166 13.1. El comando FLASHBACK TABLE. ........................ 258
3.2. Eliminacin de usuarios. ............................................... 167 13.2. El comando FLASHBACK DATABASE. ................ 260
3.3. Gestin de contraseas. ................................................. 167 V. SOPORTE DE OBJETOS Y XML ........................... 263
3.4. Perfiles de usuario......................................................... 169 1. Modelo objeto-relacional de Oracle ..................................... 263
3.5. Cuentas de base de datos sobre cuentas del sistema 1.1. Tipos abstractos de datos (clases y objetos). ................... 263
operativo. ............................................................................ 170 1.2. Seguridad para tipos de datos abstractos. ....................... 264
3.6. Usuarios globales.......................................................... 170 1.3. Herencia de clases. ........................................................ 266
3.7. Usuarios con permisos especiales: SYSOPER y SYSDBA.171 1.4. Mtodos. ...................................................................... 266
3.8. Roles estndar. ............................................................. 172 1.5. Tablas relacionales de objetos. ...................................... 269
3.9. Permisos del sistema. .................................................... 173 1.6. Tipos referencia (REF). ................................................. 271
3.10. Metadatos sobre permisos y usuarios. .......................... 181 1.7. Tablas anidadas y arrays variables. ................................ 272
4. Bases de datos virtuales privadas. ........................................ 181 1.8. Vistas de objeto. ........................................................... 274
4.1. Cmo implementar VPD a nivel de tabla. ...................... 182 1.9. Trabajando con tipos SQL desde aplicaciones JDBC. ..... 275
4.2. Cmo implementar VPD a nivel de columna. ................. 186 1.10. Crear y usar clases de objetos Java personalizadas para
4.3. Cmo desactivar VPD. .................................................. 186 objetos Oracle. .................................................................... 275
4.4. Contenido del paquete SYS.DBMS_RLS. .................. 186 2. Documentos XML en Oracle............................................... 281
2.1. XMLType. ................................................................ 281 1.7. Enlaces de base de datos y vistas materializadas. ............ 308
2.2. Mapeado de XMLType dado un esquema XML. ........ 281 1.8. Triggers, procedimientos, funciones y paquetes.............. 310
2.3. Crear tablas/columnas XMLType. ............................. 282 1.9. Dimensiones. ................................................................ 311
2.4. Operaciones con columnas XMLType. .......................... 283 1.10. Asignacin y uso de espacio, incluyendo particiones y
2.5. Validar los documentos XML sobre un esquema. ........... 286 subparticiones. .................................................................... 312
2.6. Indexar elementos XMLType. ................................... 287 1.11. Usuarios y permisos. ................................................... 316
2.7. SQLX, generar XML de los datos relacionales. .............. 287 1.12. Roles. ......................................................................... 318
2.8. Vistas XMLType. ..................................................... 291 1.13. Auditora. ................................................................... 318
VI. PROCEDIMIENTOS DE GESTIN DE LA BASE 1.14. Supervisin: las tablas de rendimiento dinmico V$. .... 320
DE DATOS. ................................................................... 294 2. Administracin de la base de datos. ..................................... 325
1. Diccionario de datos de Oracle............................................ 294 2.1. Creacin de una base de datos. ...................................... 325
1.1. Las vistas DICTIONARY (DICT) y 2.2. Iniciacin y parado de la base de datos........................... 326
DICT_COLUMNS. ......................................................... 294 2.3. Tamao y gestin de las reas de memoria. .................... 326
1.2. Cosas que podemos seleccionar de: tablas (y columnas), 2.4. Asignar y gestionar espacio para objetos. ....................... 327
vistas, sinnimos y secuencias. ............................................ 295 3. Auditora de Seguridad ....................................................... 329
1.3. Papelera: USER_RECYCLEBIN y DBA_RECYCLEBIN300 3.1. Auditando conexiones. .................................................. 330
1.4. Restricciones y comentarios. ......................................... 300 3.2. Auditando Acciones ...................................................... 330
1.5. ndices y clsteres. ........................................................ 303 3.3. Auditando objetos. ........................................................ 331
1.6. Tipos de datos abstractos, estructuras ORDBMS y LOB's.306 3.4. Protegiendo los registros de auditora............................. 331
I. NOCIONES SOBRE BASES DE DATOS Y ORACLE

1. Arquitectura de Oracle Database 11g


Oracle Database 11g es una actualizacin significativa de Oracle. Se han aadido nuevas funcionalidades para
los programadores, administradores de base de datos, y los usuarios finales tienen un mayor control sobre el
almacenamiento, procesamiento y recuperacin de los datos.
1.1. Fundamentos de bases de datos.
Todas las bases de datos relacionales manejan una serie de conceptos, los cuales pueden ser implementados
de forma diferente en cada base de datos.
Dato. Es un conjunto de caracteres con algn significado; que pueden ser numricos, alfabticos, o
alfanumricos.
Informacin. Es un conjunto ordenado de datos, los cuales son manejados segn la necesidad del
usuario. Para que un conjunto de datos pueda ser procesado eficientemente y pueda dar lugar a
informacin, primero se deben guardar lgicamente en archivos.
Base de datos (BD).Es un conjunto de informacin relacionada que se organiza y estructura de alguna
manera en archivos. En ese sentido, cualquier conjunto de fichas organizadas y guardadas en un
archivador constituye una base de datos.
En nuestro entorno cotidiano existen muchos ejemplos de bases de datos: registros de bibliotecas (con
informacin sobre libros, lectores, prstamos, etc.), registros de empresas (con informacin sobre
empleados, ocupaciones, productos, etc.), el censo de una poblacin (con la informacin personal de sus
habitantes), etc.
La utilidad y eficacia de una base de datos depende de la forma en que se estructura la informacin que
contiene. Por ejemplo, en un archivador, la informacin se distribuye en un nmero determinado de fichas
que poseen la misma estructura.

Registro. Es cada una de las fichas o filas de que consta una base de datos.
Campos o atributos. Son cada una de las caractersticas diferenciadas que definen un registro. Cada
registro o ficha est constituido por una serie de apartados en los que se introduce una determinada
informacin (Nombre, Apellidos, Fecha, Direccin, Ocupacin, etc.).
Archivo o fichero. Es la unin de todos los registros con la misma estructura.
Sistema Gestor de Base de Datos (SGBD). Es una coleccin de rutinas o programas interrelacionados,
que permiten crear y manipular una base de datos.
El objetivo primordial de un sistema gestor es proporcionar un entorno que sea a la vez conveniente y
eficiente para ser utilizado al extraer, almacenar y manipular informacin de la base de datos. Todas las
peticiones de acceso a la base de datos se manejan centralizadamente por medio del SGBD, por lo que
este paquete funciona como una interfaz entre los usuarios y la base de datos.
Esquema de base de datos. Es la estructura por la que est formada la base de datos. Se especifica por
medio de un conjunto de definiciones que se expresa mediante un lenguaje especial llamado lenguaje de
definicin de datos (DDL).
Administrador de base de datos (DBA). Es la persona o equipo de personas profesionales
responsables del control y manejo del sistema de base de datos, generalmente tiene(n) experiencia en
SGBD, diseo de bases de datos, Sistemas operativos, comunicacin de datos, hardware y programacin.
1.1.1. Objetivos de los sistemas de bases de datos.
Los sistemas de base de datos se disean para manejar grandes cantidades de informacin. La manipulacin
de los datos involucra dos aspectos:

Oracle /6
- la definicin de estructuras para el almacenamiento de la informacin, y
- aportar mecanismos para la manipulacin de la informacin.
Adems, un sistema de base de datos debe de tener implementados mecanismos de seguridad que garanticen
la integridad de la informacin, bien ante cadas del sistema o bien ante intentos de accesos no autorizados.
Por tanto, el objetivo principal de un sistema de base de datos es minimizar los siguientes aspectos:
Redundancia e inconsistencia de datos. Puesto que los archivos que mantienen almacenada la
informacin son creados por diferentes tipos de aplicaciones, existe la posibilidad de que si no se controla
detalladamente el almacenamiento, se pueda originar un duplicado de informacin (que la misma
informacin est en ms de un soporte). Esto aumenta los costes de almacenamiento y acceso a los datos,
adems de que puede originar la inconsistencia de los datos.
Dificultad para tener acceso a los datos. Un sistema de base de datos debe contemplar un entorno de
datos que le facilite al usuario el manejo de los mismos. Supngase un banco, y que uno de los gerentes
necesita averiguar los nombres de todos los clientes que viven en una zona con el cdigo postal 78733. El
gerente pide al departamento de procesamiento de datos que genere la lista correspondiente. Si esta
situacin no fue prevista en el diseo del sistema, obtener tal lista se convertir en una tarea difcil.
Aislamiento de los datos. Puesto que los datos estn repartidos en varios archivos, y stos pueden
tener diferentes formatos, es difcil crear nuevos programas para obtener los datos apropiados.
Anomalas del acceso concurrente. Para mejorar el funcionamiento global del sistema y obtener un
tiempo de respuesta ms rpido, muchos sistemas permiten que mltiples usuarios actualicen los datos
simultneamente. En un entorno as, la interaccin de actualizaciones concurrentes puede dar por
resultado datos inconsistentes. Para prevenir esta posibilidad debe mantenerse alguna forma de
supervisin en el sistema.
Problemas de seguridad. La informacin de toda empresa es importante, aunque unos datos lo son
ms que otros; por tal motivo se debe considerar el control de acceso a los mismos. No todos los usuarios
podrn visualizar determinada informacin; y por tal motivo, para que un sistema de base de datos sea
confiable, debe mantener un grado de seguridad que garantice la autentificacin y proteccin de los datos.
Problemas de integridad. Los valores de datos almacenados en la base de datos deben satisfacer cierto
tipo de restricciones de consistencia. Estas restricciones se hacen cumplir en el sistema aadiendo cdigos
apropiados en los diversos programas.
1.1.2. Abstraccin de la informacin.
Una base de datos es en esencia una coleccin de archivos relacionados entre s, de la cual los usuarios
pueden extraer informacin sin que tengan que conocer la estructura interna de los archivos.
Un objetivo importante de un sistema de base de datos es proporcionar a los usuarios una visin abstracta de
los datos; es decir, el sistema debe esconder ciertos detalles de cmo se almacenan y mantienen los datos. Sin
embargo, para que el sistema sea manejable, los datos se deben extraer eficientemente.
Existen diferentes niveles de abstraccin para simplificar la interaccin de los usuarios con el sistema:
Nivel fsico. Es la representacin del nivel ms bajo de abstraccin; en ste se describe en detalle la
forma en cmo se almacenan los datos en los dispositivos de almacenamiento (por ejemplo, mediante
ndices para el acceso aleatorio a los datos).
Nivel conceptual. El siguiente nivel ms alto de abstraccin describe qu datos son almacenados
realmente en la BD y las relaciones que existen entre los mismos. Describe completamente la base de
datos en trminos de su estructura de diseo.
El nivel conceptual de abstraccin lo usan los administradores de BD, quienes deben decidir qu
informacin se va a guardar en la base de datos. Consta de las siguientes definiciones:
1) Definicin de los datos: se describen el tipo de dato y sus caractersticas.
2) Relaciones entre datos: se definen las relaciones entre datos, para enlazar tipos de registros
relacionados, para su procesamiento posterior.
Nivel de visin. Es el nivel ms alto de abstraccin; es lo que el usuario final puede visualizar del
sistema terminado. Slo describe una parte de la BD segn el usuario acreditado para verla. El sistema
puede proporcionar muchas visiones para la misma BD.
La interrelacin entre estos tres niveles de abstraccin se ilustra en la siguiente figura.

Oracle /7
Nivel de visin

Vista 1 ... Vista n

Nivel conceptual

Nivel fsico

1.2. Fundamentos de bases de datos relacionales.


El modelo relacional de base de datos nace en 1970, cuando Edgar Codd escribe el artculo "A relational model
of data for large strared data tanks". Es a partir de 1980 cuando aparecen los primeros gestores de base de datos
cuyo modelo de datos subyacente es el relacional.
El modelo relacional conecta registros mediante los valores que stos contienen. De hecho, Codd propone
una estructura tabular (correspondiente a tablas) para representar los datos.
Es decir, si queremos representar toda la informacin contenida en los registros de un archivo podemos
utilizar una estructura de tabla. Por ejemplo, la informacin del censo de una poblacin podemos
representarla de la siguiente manera:
DNI Nombre Fecha Ocupacin
23444325 Pedro Salgueiro 20/12/64 Profesor
65335544 Jos Martnez 14/07/72 Carpintero
11143442 Esther Lpez 03/07/72 Carpintero
66442444 Jos Martnez 12/10/65 Ingeniero
Como vemos, los registros se disponen por filas mientras que los campos se disponen por columnas. Esta
forma particular de estructurar y representar la informacin se conoce como base de datos relacionales.
Cada tabla es la representacin fsica de una entidad o una relacin, y se corresponde con un archivo o
fichero de la BD.
Cada fila de la tabla se corresponde con un registro, llamado tambin intensin o tupla.
Cada columna se corresponde con los valores de un campo o atributo, siendo stos una caracterstica
distinguible de una entidad o relacin. Cada atributo tiene asignado un dominio, del cual tomar valores.
1.2.1. Campos clave.
Las BD relacionales se basan en un concepto fundamental: cada registro de la tabla debe ser nico, no
pudiendo haber registros repetidos. Para asegurar esta circunstancia surge el concepto de clave, como aquel
campo de la tabla cuyo valor para cada registro es nico.
En el ejemplo anterior podemos comprobar que existen nombres, apellidos y ocupaciones repetidas en varios
registros; por lo tanto, ninguno de estos tres campos puede ser clave. Vemos que ninguna fecha se repite,
pero nada nos asegura que no podamos insertar dos personas que hayan nacido en la misma fecha. Sin
embargo, el DNI de una persona, por su propia definicin, suele ser un valor nico. Por tanto el campo DNI
s puede ser la clave para esta tabla.
Puede darse el caso de que en una tabla ninguno de los campos sea clave. Entonces podemos probar a unir
varios campos, de forma que el valor conjunto de estos campos sea nico. En el ejemplo anterior podemos
considerar que el valor conjunto de los campos Nombre y Fecha no suele repetirse (es decir, no suele haber
dos personas con el mismo nombre y que han nacido en la misma fecha). En ese caso, los campos (Nombre,
Fecha) constituyen una clave compuesta.
Si en una tabla no existen claves simples ni claves compuestas, debemos inventarnos un nuevo campo que
acte como clave. Este nuevo campo normalmente es un cdigo o identificador numrico que se va
asignando a cada nuevo registro que se introduce en la tabla, de forma que nunca se repita.
1.2.2. Operaciones bsicas sobre registros.
Con los registros de una tabla podemos realizar las siguientes operaciones bsicas:
Aadir un registro. Cuando aadimos un nuevo registro en la tabla debemos comprobar que el valor (o
conjunto de valores) de la clave no est repetido. Si otro registro posee esa clave no podr aadirse el
nuevo registro.

Oracle /8
Borrar un registro. No existen limitaciones para borrar un registro. (Normalmente los registros no se
borran inmediatamente de la tabla, sino que internamente se les pone una marca para indicar que estn
pendientes de borrado.)
Actualizar un registro. Se puede modificar la informacin de un registro en cualquiera de sus campos,
excepto en los campos que pertenezcan a la clave.
1.2.3. Operaciones relacionales sobre tablas.
Podemos realizar las siguientes operaciones sobre una tabla:
La Interseccin ( ). Slo es aplicable sobre tablas con esquemas similares. Produce una nueva tabla
con el mismo esquema, y que contendr los registros comunes en ambas tablas.

La Unin ( U ). Tambin es slo aplicable a tablas con el mismo esquema. Produce una nueva tabla con
el mismo esquema y con todos los registros de ambas tablas (excluyendo los registros repetidos).

Diferencia ( ). Produce una nueva tabla con aquellos registros de la primera tabla que no pertenecen a
la segunda tabla.

1.2.4. Operaciones propias del modelo relacional.


Seleccin ( ). Se aplica sobre una tabla, y produce una nueva tabla con aquellos registros que en algunos
atributos cumplen una condicin determinada.

Proyeccin ( ). Aplicada sobre una tabla, produce una nueva tabla con todos los registros de la original,
pero cuyo esquema contiene slo alguno de los atributos de la tabla original.

Join ( ). Se aplica sobre dos tablas de distinto esquema pero con atributos comunes (o compatibles).
Genera una nueva tabla que es el producto cartesiano de ambas tablas, seleccionando los registros con valores
idnticos en los atributos comunes y eliminando las columnas repetidas.

1.2.5. Relaciones entre tablas.


La gran potencia y eficacia de las bases de datos relacionales se comprueba cuando debemos asociar la
informacin contenida en dos o ms tablas relacionadas.
Consideremos el ejemplo de una concesionaria de automviles, la cual posee una base de datos con
informacin sobre sus clientes y los coches que vende. En este caso, la base de datos se compone de dos
tablas: una con los datos de los clientes, y otra con los datos de coches disponibles.

Oracle /9
TABLA DE CLIENTES TABLA DE COCHES
DNI Nombre Apellidos TipoPago Matrcula Marca Precio
11252111 PEDRO PREZ CONTADO M-2345-AF OPEL 1200000
12323253 JUAN GARCA PLAZOS M-3443-HW CITROEN 2100000
56344323 LUSA GMEZ PLAZOS M-1278-HZ CITROEN 1500000

La clave de la tabla CLIENTES es el campo DNI, y la clave de la tabla COCHES es Matrcula. Aunque estas dos
tablas recogen toda la informacin disponible sobre clientes y coches, no tenemos manera de saber qu
clientes han comprado qu coches. Es necesario relacionar estas dos tablas asociando cada registro de un
cliente al registro del coche que ha comprado.
Para relacionar tablas en una BD relacional surge el concepto de clave fornea. En una de las tablas se aade
un nuevo campo que se corresponda con la clave de la otra tabla, actuando el nuevo campo como clave
fornea.
Existen cuatro tipos de relaciones posibles:
Relacin uno a uno. Slo podemos asociar un registro de la primera tabla con un registro de la segunda
tabla y viceversa. En nuestro ejemplo significa que un cliente slo puede comprar un coche y un coche
slo puede ser comprado por un cliente.
Esta relacin se resuelve introduciendo en una de las tablas, como clave fornea, la clave de la otra tabla.
Tenemos dos soluciones para nuestro ejemplo.
CLIENTES COCHES CLIENTES COCHES
1 1
DNI Matrcula DNI Matrcula
Nombre Marca Nombre Marca
Apellidos Precio Apellidos Precio
1
TipoPago TipoPago DNI
Matrcula 1

Relacin uno a varios. Podemos asociar un registro de la primera tabla con varios registros de la
segunda tabla, y un registro de la segunda tabla con un registro de la primera. En nuestro ejemplo significa
que un cliente puede comprar varios coches, pero un coche slo puede ser comprado por un cliente.
Se resuelve introduciendo en la segunda tabla la clave de la primera.
CLIENTES COCHES
1
DNI Matrcula
Nombre Marca
Apellidos Precio
TipoPago DNI

Relacin varios a uno. Esta relacin es anloga a la anterior. Indica que un cliente slo puede comprar
un coche, pero un coche puede ser comprado por varios clientes.
Se resuelve introduciendo en la primera tabla la clave de la segunda.
CLIENTES COCHES
1
DNI Matrcula
Nombre Marca
Apellidos Precio
TipoPago
Matrcula
Relacin varios a varios. Podemos asociar un registro de la primera tabla con varios registros de la
segunda tabla, y podemos asociar un registro de la segunda tabla con varios de la primera. En nuestro
ejemplo significa que un cliente puede comprar varios coches y un coche puede ser comprado por varios
clientes.
Esta relacin se resuelve creando una nueva tabla cuya estructura hereda los campos claves de las tablas
relacionadas. Para nuestro ejemplo crearemos la tabla COMPRA, con dos campos:
- DNI, clave fornea heredada de la tabla CLIENTES.
- Matrcula, clave fornea heredada de la tabla COCHES.
La clave de esta nueva tabla puede estar formada por ambos campos, y por lo tanto ser compuesta; o bien
podemos aadir una nuevo campo que acte de clave.

Oracle /10
CLIENTES COMPRA COCHES

DNI DNI Matrcula


1 1
Nombre Matrcula Marca
Apellidos Precio
TipoPago
Matrcula

1.2.6. Reglas de integridad.


En las bases de datos relacionales deben cumplirse dos reglas fundamentales:
1 REGLA (Integridad de entidad): dice que ningn campo que forme parte de una clave puede carecer
de valor (o dicho en trminos informticos; no puede tomar el valor nulo).
Esto es as porque si un registro careciese de valor en su clave ya no podra ser identificado de forma
nica.
2 REGLA (Integridad referencial): dice que no se puede introducir en una clave fornea valores que
no pertenezcan a la clave de la tabla referenciada.
No tiene sentido indicar en una tabla referenciada valores que no existen en la tabla principal. En el
ejemplo de la concesionaria, no tiene sentido indicar que un coche ha sido comprado por un cliente del
cual no se tiene ninguna referencia.
La segunda regla puede crear problemas en el caso de que se quieran borrar registros con una clave fornea
referenciada por otra tabla. Para evitar este problema existen tres soluciones:
- Prohibir el borrado. Por ejemplo, no se podrn eliminar clientes que hayan comprado algn coche.
- Borrar en cascada. Por ejemplo, si se elimina un cliente, se eliminarn tambin todos los coches
comprados por ese cliente.
- Nulificar. Por ejemplo, si se elimina un cliente, en los registros de coches vendidos a ese cliente se
pondr un valor nulo en el DNI.
1.2.7. Diseo de una base de datos relacional.
Una vez establecido un problema, para disear una BD relacional debemos seguir los siguientes pasos:
1) Decidir cuntas tablas necesitamos. Normalmente se crear una tabla por cada entidad que
podamos distinguir en nuestro problema.
2) Definir la estructura de cada tabla. De qu campos se componen y cul es la clave.
3) Determinar para cada campo su tipo de dato, su tamao (si es necesario) y los valores posibles que
podemos asignarle (su dominio).
4) Establecer las relaciones entre las tablas. Para ello debemos incluir en cada tabla las claves forneas
que sean necesarias o crear nuevas tablas.
Una vez diseada la base de datos podemos crearla utilizando un gestor de base de datos.
1.3. Bases de datos e instancias en Oracle.
Una base de datos de Oracle es una coleccin de datos en uno o ms archivos. La base de datos de Oracle
contiene estructuras fsicas y lgicas. Durante el desarrollo de una aplicacin podemos crear estructuras como
tablas e ndices para almacenar filas y acelerar su recuperacin. Podemos crear sinnimos para los nombres de
objetos, vistas de objetos en varias bases de datos y podemos restringir el acceso a los objetos. Tambin
podemos usar tablas externas para acceder a ficheros fuera de la base de datos como si las filas en los ficheros
fuesen filas de tablas.
Una instancia de Oracle comprende un rea de memoria llamada rea Global del Sistema (SGA) y los
procesos de fondo que interactan entre el SGA y los ficheros de la base de datos en disco. En una "Real
Application Cluster de Oracle" (RAC) ms de una instancia ser usada sobre la misma base de datos; las
instancias generalmente estarn sobre servidores independientes conectados mediante una interconexin de
alta velocidad.
1.4. Organizacin de las bases de datos en Oracle.
Dentro de una base de datos de Oracle, la estructura bsica en la tabla. Oracle Database 11g soporta muchos
tipos de tablas, incluyendo las siguientes:
Tablas relacionales. Usando los tipos de datos soportados por Oracle, podemos crear tablas para
almacenar las filas insertadas y manipularlas en nuestras aplicaciones. Las tablas tienen definiciones de
columna, y podemos aadir o quitar columnas segn los requerimientos de nuestras aplicaciones.
Tablas objeto-relacionales. Para tomar ventajas de funcionalidades como la herencia de tipo, podemos

Oracle /11
usar las capacidades objeto-relacional de Oracle. Podemos definir nuestros propios tipos de datos y usarlos
como base para la definicin de columnas, tablas de objetos, tablas anidadas, arrays variables y ms.
Tablas organizadas por ndice. Podemos crear una tabla que almacene sus datos como una estructura
de ndice, permitiendo que los datos sean ordenados dentro de la tabla.
Tablas externas. Los datos almacenados en ficheros planos pueden ser tratados como tablas que los
usuarios pueden consultar directamente y relacionar con otras tablas en consultas. Podemos usar tablas
externas para acceder a grandes volmenes de datos sin tener que cargarlos en nuestra base de datos.
Oracle tambin soporta tipos de datos BFILE, un puntero a un fichero binario externo.
Tablas particionadas. Podemos dividir una tabla en varias particiones, lo cual permite controlar
independientemente cada parte de la tabla. Podemos aadir una nueva particin a una tabla, separar
particiones existentes, y administrar una particin a parte de otra particin de la tabla. El particionado
puede simplificar o mejorar el rendimiento de actividades de mantenimiento y de las consultas de usuario.
Podemos particionar tablas segn rangos de valores, segn una lista de valores, segn cdigos de valores
de columna, o segn una combinacin de estas opciones.
Vistas materializadas. Una vista materializada en una rplica de los datos recuperados por una
consulta. Las consultas de usuario pueden ser redireccionadas a las vistas materializadas para evitar tablas
largas durante la ejecucin (el optimizador rescribir las consultas automticamente). Podemos establecer y
controlar tareas de refresco para obtener los datos actualizados en las vistas materializadas segn las
necesidades del negocio.
Tablas temporales. Podemos usar tablas temporales globales para crear una tabla en la cual varios
usuarios puedan insertar registros. Cada usuario slo ver sus filas en la tabla.
Tablas de clster (o cubo).Si dos tablas son normalmente consultadas conjuntamente, podemos
almacenarlas fsicamente juntas a travs de una estructura llamada clster (o cubo).
Tablas eliminadas. Desde Oracle Database 10g, podemos recuperar rpidamente tablas eliminadas
mediante el comando DROP. Podemos recuperar varias tablas de una vez o recuperar toda la base de datos
en un momento concreto. Oracle soporta consultas de deshacer, las cuales retornan versiones anteriores
de filas en una tabla existente.
Como soporte en el acceso a las tablas, podemos usar vistas que realicen combinaciones y agregaciones,
limitar las filas retornadas, o modificar las columnas mostradas. Las vistas pueden ser de slo lectura o
modificables, y pueden referenciar tablas locales y remotas. Las tablas remotas pueden ser accedidas a travs
de enlaces a bases de datos. Podemos usar sinnimos para enmascarar la localizacin fsica de las tablas.
Para controlar los accesos a las tablas, Oracle soporta muchos tipos de ndices, incluyendo los siguientes:
ndices B*-tree. Un ndice B*-tree es el tipo estndar de ndices disponibles en Oracle, y es muy usado
para seleccionar filas por un criterio de equivalencia o una criterio de rango.
ndices Bitmap. Para columnas que tienen pocos valores nicos, un ndice bitmap puede mejorar el
rendimiento de las consultas. Los ndices bitmap deberan usarse slo cuando los datos se cargan por lotes
(como en muchos depsitos de datos o aplicaciones de informes).
ndices de clave inversa. Si hay problemas de contencin de E/S durante la insercin de valores
secuenciales, Oracle puede invertir dinmicamente los valores de ndice antes de almacenarlos.
ndices basados en funciones. En vez de indexar una columna, como Nombre, podemos indexar una
columna basada en una funcin, como UPPER(Nombre). Este tipo de ndice tiene opciones adicionales del
optimizador de Oracle cuando seleccionamos una ruta de ejecucin.
ndices particionados. Podemos particionar ndices para soportar tablas particionadas o para
simplificar la gestin de ndices. Los ndices particionados pueden ser locales para cada particin de la tabla
o pueden aplicarse globalmente a todas las filas de la tabla.
ndices de texto. Podemos indexar valores de texto para soportar capacidades de bsqueda avanzada,
como palabras derivadas o bsqueda de frases. Los ndices de texto son conjuntos de tablas e ndices
mantenidos por Oracle para soportar requerimientos de bsqueda de texto complejos. Oracle Database
11g ofrece facilidades para indexar texto que simplifique su administracin y mantenimiento.
1.4.1. Almacenando los datos.
Toda la estructura lgica de una base de datos debe ser almacenada en algn sitio dentro de la base de datos.
Oracle mantiene una diccionario de datos que registra los metadatos acerca de cada objeto (el propietario del
objeto, una definicin, privilegios relacionados, y cosas as). Para los objetos que requieren un espacio de
almacenamiento fsico de s mismos, Oracle reserva espacio dentro de un tablespace.

Oracle /12
Tablespaces.
Un tablespace consiste de uno o ms ficheros de datos; un fichero de datos puede ser parte de un y solo un
nico tablespace. Oracle Database 11g crea al menos dos tablespaces para cada base de datos (SYSTEM y
SYSAUX) para soportar las necesidades de administracin interna. Podemos usar el Administrador de
Ficheros de Oracle (OMF) para simplificar la creacin y mantenimiento de ficheros de datos.
A partir de Oracle Database 10g, podemos crear un tipo especial de tablespace, llamado "bigfile tablespace",
que puede tener muchos miles de terabytes de tamao. Con OMF, la administracin de bigfiles hace la
gestin de tablespace completamente transparente para el administrador de base de datos (DBA); el DBA
puede administrar los tablespace como una unidad sin preocuparse sobre el tamao y estructura de los
ficheros de datos subyacentes.
Si un tablespace esta designado como un tablespace temporal, el tablespace mismo es permanente; slo los
segmentos guardados en el tablespace son temporales. Oracle usa tablespaces temporales para soportar
operaciones de ordenacin en la creacin de ndices y procesos de combinacin. Los segmentos temporales
no deberan ser almacenados en el mismo tablespace como objetos permanentes.
Los tablespaces pueden ser gestionados en diccionario o gestionados localmente. En una gestin de
diccionario, el espacio gestionado es registrado en el diccionario de datos. En una gestin local (por defecto
en Oracle Database 11g), Oracle mantiene una mapa de cada fichero de datos del tablespace para rastrear la
disponibilidad de espacio. En el diccionario de datos slo se gestionan cuotas, lo cual reduce dramticamente
la contencin de tablas del diccionario de datos.
Gestin automtica de almacenamiento.
La gestin automtica de almacenamiento (ASM), disponible desde Oracle Database 10g, automatiza el
diseo de ficheros de datos y otros ficheros del nivel del sistema operativo usados por la base de datos,
distribuyndolos entre los disco disponibles. Cuando un nuevo disco es aadido a la instancia ASM, los
ficheros de datos son automticamente redistribuidos a travs de todos los discos en los grupos de discos
definidos para optimizar el rendimiento.
Las caractersticas de multiplexin de una instancia ASM minimizan la posibilidad de prdida de datos y es
generalmente ms efectiva que un esquema manual que pone ficheros crticos y ficheros de respaldo en
diferentes unidades fsicas.
Gestin automtica de deshacer.
Para soportar nuestras transacciones, Oracle puede crear y administrar dinmicamente segmento de deshacer,
los cuales ayudan a mantener imgenes prioritarias de los bloques y filas cambiadas. Los usuarios que
consultaron previamente las filas que hemos cambiado todava vern las filas tal como existan cuando las
consultaron. La gestin automtica de deshacer (AUM) permite a Oracle administrar los segmentos de
deshacer directamente sin la intervencin del administrador de base de datos. El uso de AUM tambin
simplifica el uso de consultas de flashback.
Desde Oracle Database 10g, podemos ejecutar consultas de versiones pasadas para ver diferentes versiones
de un fichero tal como ha cambiado durante un intervalo de tiempo especfico.
Datos eliminados.
El concepto de cajn de reciclado introducido con Oracle Database 10g afecta a las exigencias de espacio
requerido para nuestros tablespaces y ficheros de datos. En Oracle Database 11g el comportamiento por
defecto para el borrado de una tabla es que la tabla retenga su espacio asignado; podemos ver este espacio
usando la vista RECYCLEBIN del diccionario de datos. Si creamos y borramos una tabla dos veces, habr dos
copias de la tabla en el cajn de reciclado. Aunque esta arquitectura simplifica enormemente las
recuperaciones de borrados de tablas accidentales, puede incrementar considerablemente el espacio usado por
la base de datos. Se usa el comando PURGE para quitar entradas antiguas del cajn de reciclado.
1.4.2. Guardando los datos.
Podemos controlar completamente el acceso a nuestros datos. Podemos conceder privilegios a otros usuarios
para realizar funciones especficas (como seleccionar, insertar y ms) sobre nuestros objetos. Podemos
adquirir privilegios desde roles, los cuales son entonces concedidos a los usuarios, agrupando as privilegios
dentro de conjuntos manejables.
Oracle soporta un nivel muy detallado de permisos; podemos controlar qu filas son accesibles y, durante
auditora, qu filas desencadenan eventos de auditoria que sean registrados. Cuando se usa la opcin Base de
datos Privada Virtual (VPD), las consultas de usuario sobre tablas son siempre limitadas independientemente
del mtodo a travs del cual se accede a las tablas. Desde Oracle Database 10g, VPD ha ido ms lejos
incluyendo enmascaramiento de columna para columnas que contienen datos sensibles.
Oracle /13
Adems del acceso seguro a los datos, podemos auditar actividades en la base de datos. Los eventos
auditables incluyen acciones privilegiadas (como crear usuarios), cambios en las estructuras de datos y accesos
a filas y tablas especficas.
1.4.3. Soporte para programacin.
Oracle soporta una gran cantidad de mtodos de acceso a programacin. El lenguaje SQL es la clave para
cualquier esfuerzo de programacin de aplicaciones. Otros mtodos de acceso incluyen los siguientes:
PL/SQL.PL/SQL es un componente crtico en la implementacin de muchas aplicaciones. Podemos
usar PL/SQL para crear procedimientos y funciones almacenados, y entonces podemos llamar a las
funciones dentro de consultas. Los procedimientos y funciones pueden ser recolectados dentro de
paquetes. Tambin podemos crear desencadenadores (triggers), los cuales dicen a la base de datos qu
pasos deben seguir con varios eventos que ocurren dentro de la base de datos. Los triggers pueden ocurrir
durante eventos de la base de datos (como el acceso inicial a la base de datos), cambios en la estructura
(como un intento de borrar tablas), o cambios en las filas. En cada caso, se usa PL/SQL para controlar el
comportamiento de la base de datos o aplicaciones en los cuales ocurren los eventos.
SQL Dinmico. Podemos generar SQL en tiempo de ejecucin y pasarlo a procedimientos que lo
ejecuten a travs de SQL Dinmico.
SQL*Plus. SQL*Plus proporciona una interfaz sencilla para las bases de datos de Oracle. SQL*Plus
puede soportar requerimientos de informes rudimentarios, pero es mejor conocerlo para soportar
scripting. Proporciona una interfaz consistente para recuperar datos del diccionario de datos y crear
objetos en la base de datos.
Java y JDBC. Oracle da soporte a Java y JDBC, permitindonos usar Java en lugar de PL/SQL en
muchas operaciones. Podemos todava escribir procedimientos almacenados basados en Java. Las
capacidades del Java de Oracle han sido ampliadas y realzadas con cada nueva versin.
XML. Podemos usar interfaces y tipos XML de Oracle para soportar la insercin y recuperacin de
datos en formato XML.
SQL y PL/SQL orientados a objetos. Podemos usar Oracle para crear y acceder a estructuras
orientadas a objetos, incluyendo tipos de datos definidos por el usuario, mtodos, objetos grandes
(LOB's), tablas de objetos, y tablas anidadas.
Data Pump. Data Pump Import y Data Pump Export, ambos introducidos en Oracle Database
10g, realzan enormemente la manejabilidad y rendimiento de las recientes utilidades de importacin y
exportacin. Podemos usar Data Pump para extraer rpidamente datos y moverlos a diferentes bases de
datos mientras alteramos el esquema y cambiamos las filas.
SQL*Loader. Podemos usar SQL*Loader para cargar rpidamente ficheros planos dentro de tablas de
Oracle. Un nico fichero plano puede ser cargado dentro de varias tablas durante la misma carga, y la
carga puede ser paralela.
Programas y procedimientos externos. Podemos embeber SQL dentro de programas externos, o
podemos crear libreras de procedimientos que ms tarde sean enlazadas a Oracle.
UTL_MAIL. Un paquete introducido en Oracle Database 10g, UTL_MAIL, permite a programadores de
aplicaciones PL/SQL enviar correos electrnicos sin tener que conocer la pila de protocolos SMTP
subyacente.
1.5. Seleccin de arquitecturas y opciones.
Oracle proporciona un completo conjunto de herramientas para programar aplicaciones basadas en Oracle
Database 11g. Podemos usar el servidor de aplicaciones de Oracle como la capa intermedia para aplicaciones
de tres capas que acceden a Oracle Database 11g.
Muchas de las funcionalidades introducidas con Oracle Database 11g estarn disponibles independientemente
de la arquitectura de aplicacin seleccionada. Estas funcionalidades incluyen administracin de base de datos
como gestin automtica de almacenamiento, tuneado automtico, y redimensionado automtico de las reas
de memoria en el SGA.
Oracle proporciona un conjunto de procedimientos que ayudan a gestionar la planificacin de refresco de las
vistas materializadas. Por ejemplo, podemos ejecutar un procedimiento que genere una descripcin de los
problemas con los refrescos y las configuraciones que nos impiden usar las opciones ms rpidas posibles.
Podemos usar otro procedimiento de Oracle para generar recomendaciones para tunear estructuras de vistas
materializadas segn un conjunto de consultas previstas.
Algunas nuevas funcionalidades pueden contener pequeos cambios que pueden tener un gran impacto en

Oracle /14
nuestra aplicacin o nuestro cdigo. Por ejemplo, desde Oracle Database 10g estn disponibles bsquedas
usando expresiones regulares.
2. Instalar Oracle Database 11g y crear una base de datos
El software de instalacin del Oracle se hace ms fcil de usar con cada nueva versin; basta con abrir la caja
de ceds y comenzar la instalacin enseguida. Si queremos experimentar con alguna nueva funcionalidad de
base de datos, se requiere una mayor planificacin para realizar una instalacin sucesiva sin tener que hacer
todo el trabajo de reinstalacin. En este captulo veremos lo bsico de una instalacin de Oracle usando el
Instalador Universal de Oracle (OUI), as como una plantilla bsica para hacer una instalacin manual de la
base de datos usando el comando CREATE.
Las siguientes cosas deben ser resueltas antes de empezar la instalacin:
Decidir un nombre de base de datos local, y en qu dominio ser contenido la base de datos. Estos
nombres sern asignados en los parmetros de inicializacin DB_NAME y DB_DOMAIN.
Para el primer proyecto que usar la base de datos, estimar el nmero de tablas e ndices, as como su
tamao, para planificar el espacio en disco adems del requerido por los tablespace SYSTEM y el software y
herramientas asociadas de Oracle.
Planificar la ubicacin de los ficheros de datos fsicos en el disco del servidor para maximizar el
rendimiento y recuperacin. En general, cuantos ms disco fsicos mejor. Si un RAID o Almacn de red
son usados por los ficheros de datos, podemos usar el Administrador de Ficheros de Oracle para
gestionar la ubicacin de los ficheros de datos. Desde Oracle Database 10g podemos usar almacenamiento
automtico (ASM) para simplificar la gestin de almacenamiento.
Revisar y comprender los parmetros bsicos de inicializacin.
Seleccionar el juego de caracteres de la base de datos, con un juego de caracteres alternativos. Aunque
podemos dejar el juego de caracteres por defecto aplicado durante la instalacin, podemos necesitar
considerar dnde estarn localizados los usuarios de la base de datos y sus requerimientos de idioma. El
juego de caracteres puede ser cambiado despus de la instalacin slo si el nuevo juego de caracteres es un
superjuego del existente.
Decidir el mejor tamao por defecto de los bloques de base de datos. El tamao por defecto definido
por DB_BLOCK_SIZE no puede ser cambiado despus sin reinstalar la base de datos. Oracle puede soportar
varios tamaos de bloques dentro de una nica base de datos.
Planificar el almacenamiento de objetos de usuarios distintos de SYSTEM en tablespaces distintos de
SYSTEM. Hay que asegurarse de que todos los usuarios no administrativos son asignados a un tablespace
distinto de SYSTEM por defecto.
Planificar la implementacin del Administrador Automtico de Deshacer para que sea fcil la
administracin de transacciones que rehagan al informacin.
Planificar una estrategia de copias de seguridad y recuperacin. Decidir cmo la base de datos necesita
ser recuperada, y cunto a menudo. Planificar usar ms de un mtodo para recuperar la base de datos.
2.1. Descripcin de la licencia y opciones de instalacin.
Una instalacin inicial acertada del software es el primer paso. Independientemente de la plataforma de
software y hardware sobre la cual decidamos instalar Oracle, los tipos de instalaciones que podemos realizar
son los mismos. Aunque puede haber cambios en cada versin del producto, normalmente se incluyen los
siguientes tipos de instalacin:
Edicin Empresarial. Es la versin ms extensa, con ms funcionalidades. Incluye funciones como
Flashback Database y permite aadir piezas adicionales de funcionalidades con licencia, como Oracle
Spatial, Oracle OLAP, Oracle Label Security, y Oracle Data Mining.
Edicin Estndar. Esta versin proporciona un buen subconjunto de funcionalidades, incluyendo las
que necesitan la mayora de negocios.
Edicin Personal. Esta versin permite el desarrollo de aplicaciones que se ejecutarn sobre la Edicin
Estndar o Empresarial. Esta edicin no puede ser usada en un entorno de produccin.
Desde Oracle Database 10g, la licencia de Oracle es slo para un nombre de usuario o una CPU, y no hay la
opcin de licenciar a usuarios concurrentes. Por lo tanto, el DBA debera usar el parmetro de inicializacin
LICENSE_MAX_USERS para especificar el nmero mximo de usuarios que pueden ser creados en la base de
datos. Como resultado, los parmetros LICENSE_MAX_SESSIONS y LICENSE_SESSIONS_WARNING estn
obsoletos en Oracle Database 11g.

Oracle /15
Adems, el servidor de Oracle puede ser instalado durante una instalacin del lado servidor o cliente. Sin
embargo, es recomendable que esta instalacin sea realizada despus de que una instalacin bsica sea
completada.
2.1.1. Usando OUI para instalar el software de Oracle.
Usaremos el Instalador Universal de Oracle (OUI) para instalar y administrar todos los componentes de
Oracle tanto en el lado servidor como el lado cliente. Podemos tambin desinstalar cualquier producto de
Oracle desde la pantalla inicial del OUI.
Durante la instalacin del servidor, podemos elegir la versin de Oracle Database 11g: Empresarial, Estndar,
o una de las otras opciones disponibles para nuestra plataforma. Es recomendable crear una base de datos de
arranque cuando nos lo soliciten durante la instalacin. Crear la base de datos de arranque es un buen modo
de asegurarnos de que el entorno servidor se instale correctamente, as como repasar cualquier nueva
funcionalidad de Oracle Database 11g. La base de datos de arranque tambin puede ser un buen candidato
como repositorio tanto del Administrador Empresarial de Oracle (OEM) como del Administrador de
Recuperacin.
El flujo exacto del proceso de instalacin puede cambiar dependiendo de nuestro entorno operativo y la
versin de Oracle.
Nota. En entornos UNIX, necesitamos asignar un valor apropiado a la variable de entorno DISPLAY
y habilitar xhost previamente para empezar el OUI a travs del script runInstaller.
En general, los pasos sern como sigue:
1) En la pantalla de apertura, elegir entre instalar un producto o desinstalar un producto previamente
instalado.
2) Especificar la ubicacin del fichero fuente para el producto que queremos instalar y el directorio inicial
dentro del cual el software de Oracle ser instalado. El instalador debera presentarnos valores por defecto.
En general, los valores por defecto para los archivos fuente de software deberan ser vlidos, mientras que
otros pueden necesitar ser cambiados.
3) Seleccionar un producto a instalar. Nuestras opciones incluirn la base de datos y el cliente. Si
seleccionamos la opcin "database", el OUI instalar un base de datos de arranque preconfigurada,
opciones de producto, herramientas administrativas, servicios de red, utilidades, herramientas de
desarrollo, precompiladores, y software cliente bsico.
Para la primera instalacin, deberamos usar la opcin "database" para crear la base de datos de arranque.
4) Elegir el tipo de instalacin: Edicin Empresarial, Edicin Estndar, o personalizada.
5) Si se ha elegido la opcin "database" en el paso 3, ahora se nos pedir que confirmemos la creacin de
la base de datos de arranque.
6) Se nos pedir que elijamos entre configuraciones de base de datos estndar: propsito general,
procesamiento de transacciones, o depsitos de datos (warehouse).
7) Para la base de datos de arranque, elegir las opciones de configuracin. Estas opciones incluyen el
nombre global de la base de datos, el nombre de la instancia, el juego de caracteres, y si incluimos o no
esquemas de ejemplo.
8) Especificar una nica contrasea que ser usada por todos los esquemas precargados en la base de datos
de arranque, o contraseas independientes para cada cuenta.
9) Especificar la opcin de almacenamiento que se usar. Si estamos usando ficheros del sistema,
especificar los directorios a usar. Otras opciones incluyen administracin automtica de almacenamiento y
dispositivos raw.
10) Nos solicitarn finalizar la seleccin de opciones de administracin y servicios previos para aceptar la
configuracin e inicio de la instalacin.
Durante la instalacin del software, el Asistente de Configuracin de la Base de datos (DBCA) nos solicita
los parmetros necesarios de tamao y configura nuestra base de datos (comenzando en el paso 6). Los pasos
de instalacin en la siguiente sesin asumen que hemos completado la instalacin del software y creado una
base de datos de arranque. Ahora crearemos y configuraremos una segunda base de datos sobre el mismo
servidor con DBCA.
Nota. Desde Oracle 10g, DBCA puede configurar nodos en un entorno de Real Application
Clusters.

Oracle /16
2.1.2. Usando el DBCA para crear una base de datos.
En UNIX, podemos comenzar el Asistente de Configuracin de la Base de datos (DBCA) ejecutando el
fichero dbca ubicado en el directorio $ORACLE_HOME/bin. Debemos configurar la variable de entorno
DISPLAY y asignar xhost antes de empezar el DBCA. En Windows, el DBCA est ubicado en el submen
"Herramienta de configuracin y migracin" del men "Oracle".
En las subsecciones que siguen, se indican pautas y guas para la mayor parte de las pantallas durante la
creacin de la base de datos.
Opciones del DBCA.
Despus de una pantalla de bienvenida inicial, se nos presenta una seleccin de cuatro opciones:
Crear una base de datos. Esta opcin crea una nueva base de datos desde el principio, usando una
plantilla como punto de partida.
Configurar opciones de base de datos en una base de datos . Esta opcin permite cambiar alguno
de los parmetros de sistema para una instalacin de base de datos existente, como cambiar desde un
servidor dedicado a un servidor compartido.
Eliminar una base de datos. Esta opcin elimina todos los ficheros de datos y ficheros de control
asociados con la base de datos. Necesitamos la contrasea del usuario SYS o SYSTEM para ejecutar esta
opcin.
Administrar plantillas. Esta opcin permite aadir, modificar o eliminar plantillas. Durante una sesin
del DBCA, una vez que todos los parmetros de base de datos han sido reunidos, tenemos la opcin de
guardar las asignaciones como una plantilla. En muchos casos, las plantillas predefinidas que Oracle
proporciona no son exactamente perfectas para nuestro entorno, y ahorra tiempo poder guardar nuestras
opciones como una plantilla para una futura sesin del DBCA.
Seleccionando una plantilla de base de datos.
La figura siguiente muestra la lista de plantillas disponibles. Si creamos una plantilla en una sesin previa del
DBCA aparecer en esta pantalla tambin.

Las plantillas a seleccionar son las siguientes:


Base de datos personalizada. Se usa esta opcin si hemos realizado muchas instalaciones y sabemos
de antemano los valores para todas las opciones que necesita la base de datos. Esta opcin es mejor si
creamos una nueva plantilla desde el principio o tenemos exigencias muy especficas para la configuracin
de nuestra base de datos.
Depsito de datos. Esta plantilla es para entornos de base de datos donde los usuarios realizan
numerosas y complejas consultas que renen muchas tablas para informes, pronsticos y analticas.

Oracle /17
Propsito general. Si todava no estamos seguros de para qu se emplear nuestra base de datos, o si
tenemos que soportar a usuarios con requerimientos de procesamiento analtico y transaccional, se
recomienda esta plantilla.
Procesamiento de transacciones. En entornos donde el nmero de usuarios es alto, las transacciones
son pesadas pero cortas, y la mayor parte de la actividad es crear y actualizar, se recomienda esta plantilla.
Para continuar con la instalacin, seleccionaremos la plantilla de propsito general. Esta plantilla combina las
funcionalidades de los depsitos de datos y un entorno OLTP en una nica base de datos.
Identificacin de la base de datos.
En el siguiente paso del DBCA, debemos identificar el nombre de la instancia junto con el nombre de la base
de datos global.
Nota. Si el nombre de la base de datos global necesita ser cambiado en el futuro, debemos usar el
comando ALTER DATABASE para cambiarlo, adems de cambiarlo en el fichero de parmetros de
inicializacin. El nombre de la base de datos global es almacenado en el diccionario de datos cuando
se crea la base de datos.
A menos que tengamos un dominio existente, debemos usar el nombre de dominio por defecto .world.
Deberamos comprobar con el administrador de sistemas si deberamos usar un nombre especfico para la
base de datos global.
Credenciales de la base de datos.
La siguiente figura muestra la pantalla de asignacin de contraseas para las cuentas de usuario SYS y
SYSTEM. Despus de la instalacin, debemos asegurarnos de crear al menos una cuenta con privilegios DBA
para no tener que usar los usuarios SYS o SYSTEM en las tareas administrativas del da a da.

En esta pantalla, podemos tambin indicar que esta instancia sea incluida como un nodo administrativo en un
entorno de Administracin Empresarial de Oracle (OEM) existente, o podemos especificar esta instancia
como un repositorio OEM. Si especificamos esta instancia como un repositorio OEM, es extremadamente
recomendable que este nodo sea usado slo para este propsito.
Opciones de almacenamiento.
Las bases de datos pueden usar una cantidad de mtodos diferentes para almacenar ficheros de datos,
ficheros de control y ficheros de deshacer. La siguiente figura muestra la pantalla donde podemos seleccionar
el mecanismo de almacenamiento.

Oracle /18
Si tenemos la posibilidad de dedicar otra instancia de base de datos para administrar espacio de disco,
debemos elegir la opcin ASM. Si estamos en un entorno Real Application Clusters y no tenemos un
sistema de ficheros de clster disponible (como un OCFS) debemos elegir la opcin "Raw Devices".
Localizacin de ficheros.
En la pantalla mostrada a continuacin es donde podemos seleccionar la localizacin de los archivos de datos,
ficheros de control, ficheros de deshacer, as como las localizaciones de archivado, copias de seguridad y
recuperacin.

Un concepto nuevo desde Oracle Database 10g es el rea de Recuperacin Flash. sta es una localizacin del
disco dedicada, separada de la localizacin de los ficheros operacionales de la base de datos, que contiene

Oracle /19
ficheros de respaldo del Administrador de Respaldo (RMAN). Es altamente recomendado usar el rea de
Recuperacin Flash para que el RMAN pueda administrar ms fcilmente copias de respaldo y operaciones
de recuperacin. Deberemos asegurarnos de que el rea de Recuperacin Flash tenga el espacio necesario
para al menos dos copias de todos los ficheros de datos, copias de respaldo incrementales, ficheros de
control, SPFILE's, y ficheros de deshacer que estn todava en el disco.
Podemos tambin habilitar el modo ARCHIVELOG, para especificar la localizacin o localizaciones de los
ficheros de deshacer. Se recomienda dejar el archivado deshabilitado hasta que la base de datos se instale,
porque habilitarlo incrementa el tiempo de creacin de la base de datos. Los parmetros para el modo
ARCHIVELOG pueden ser modificados fcilmente en el fichero init.ora o el SPFILE inmediatamente despus de
que la base de datos est activa y ejecutndose.
Componentes de la base de datos.
En el siguiente paso de la sesin del DBCA, se nos pregunta acerca de la instalacin de los esquemas de
ejemplo. En bases de datos de no-produccin, es altamente recomendable instalar esquemas de ejemplo;
muchos tutoriales y guas de estudio se apoyan en los esquemas de ejemplo de la base de datos. Son tambin
tiles en esto los ejemplos demostrativos de casi todos los tipos de datos y constructores disponibles en la
base de datos, rangos de mapas de ndices para tablas en clsteres y tipos de objetos.
Parmetros de inicializacin.
La siguiente pantalla mostrada a continuacin permite al DBA ajustar los parmetros clave de inicializacin
para la base de datos.

La figura muestra la ficha de Memoria. Si seleccionamos tpica (Typical) o si seleccionamos personalizada


(Custom) con administracin automtica de la memoria compartida, Oracle har asunciones acerca de la
memoria que podemos usar para el SGA y los procesos de segundo plano. Incluso usando por defecto
muchos de los parmetros en una configuracin tpica, todava podemos especificar qu cantidad de la
memoria fsica del servidor debera usar Oracle, dependiendo de cunta memoria es usada por el sistema
operativo y si cualquier otra aplicacin est siendo ejecutada en este servidor junto con Oracle. El valor para
Java Pool debe ser al menos el tamao de una fraccin de la base de datos, entre 4 MB o 16 MB, pero al
menos se recomiendan 20MB.
Las ltimas pantallas de esta seccin del DBCA permiten especificar el tamao de bloque por defecto de la
base de datos, el nmero total de procesos que sern simultneamente conectados, el modo de conexin
usado, y el juego de caracteres para la base de datos.
Almacenamiento de la base de datos.
En la pantalla de almacenamiento de base de datos del DBCA, podemos ver y revisar la localizacin de los

Oracle /20
ficheros de control, ficheros de datos y ficheros de deshacer, as como multiplexar los ficheros de control y
crear grupos de ficheros de deshacer. Los nombres y localizaciones de los ficheros de control en esta pantalla
determinan el valor de CONTROL_FILES en el fichero de parmetros de inicializacin.
Opciones de creacin.
En la siguiente figura se muestra la pantalla para crear la base de datos. Adems, podemos usar la informacin
proporcionada en las pantallas previas y guardarla en una plantilla. Ante la duda guardar como una plantilla; el
almacenamiento requerido para guardar slo una plantilla es mnimo y puede fcilmente ser suprimido ms
tarde por nueva ejecucin del DBCA.

Antes de que la base de datos sea creada, se presenta un resumen de nuestra plantilla, y tenemos la opcin de
guardar este informe como un archivo HTML para propsitos de documentacin.
Completando la instalacin.
Despus de pulsar el botn "OK" de la pantalla de resumen, el DBCA realiza las tareas necesarias para crear
la base de datos e iniciar la instancia. Se ejecuta un conjunto de scripts estndar cuando la base de datos inicia
por primera vez; esto incluye el script que crea los esquemas de ejemplo, ms cualquier script personalizado
especificado previamente. El conjunto estndar de scripts vara dependiendo de las opciones seleccionadas a
travs del DBCA.
Una vez completados los scripts de inicializacin y creacin, se presenta una pantalla de resumen, mostrando
la localizacin de los ficheros de registro de esta instalacin. Es recomendable revisar estos ficheros de
registro para asegurarnos que no ocurrieron errores durante la instalacin. Deberamos tambin guardar este
fichero de registro con otra documentacin de esta base de datos; esto puede ser til para futuras
instalaciones.
La base de datos de Oracle recin creada es activada y ejecutada. Tenemos la opcin de desbloquear otras
cuentas creadas durante esta instalacin y asignarles contraseas.
2.1.3. Creacin manual de una base de datos.
El DBCA puede soportar requerimientos de instalacin complejos. Por ejemplo, si necesitamos crear la
misma base de datos en varios servidores, podemos usar el DBCA para crear y ejecutar plantillas. Podemos
crear manualmente una base de datos en vez de usar el DBCA. Oracle proporciona un script de ejemplo de
creacin de base de datos que puede ser personalizado para una instalacin manual.
A continuacin se describen los pasos necesarios para crear una base de datos manualmente. Algunos de
estos pasos son dependientes del sistema operativo o de la plataforma. Por ejemplo, bajo Windows
necesitamos ejecutar la utilidad oradim para crear el proceso de fondo de Oracle y para asignar los valores de

Oracle /21
registro relevantes.
1) Decidir una estructura de directorios para la base de datos; se recomienda cumplir con los estndares de
la arquitectura flexible ptima de Oracle cuando pongamos nuestros ficheros en el disco.
2) Seleccionar una SID (identificador de instancia) de Oracle para distinguir esta instancia de otras que se
estn ejecutando en el servidor. Frecuentemente ser el mismo que el nombre de la base de datos
especificado en el parmetro de inicializacin DB_NAME. En la lnea de comandos de Windows escribir lo
siguiente:
SET ORACLE_SID=rjbdb
Bajo UNIX, debemos usar:
EXPORT ORACLE_SID=rjbdb
o bien:
SETENV ORACLE_SID=rjbdb
dependiendo de la consola de comandos por defecto.
3) Establecer un mtodo de autentificacin para conectar los permisos de usuario a la base de datos. Se usa
la utilidad de lnea de comando orapwd para crear un fichero de contraseas si queremos que Oracle
autentifique los permisos de usuario; se debe asignar el parmetro de inicializacin
REMOTE_LOGIN_PASSWORDFILE a EXCLUSIVE. Si estamos usando la autentificacin del sistema operativo,
no es necesario un fichero de contrasea; y por lo tanto debemos asignar REMOTE_LOGIN_PASSWORDFILE
a NONE.
4) Crear un fichero de parmetros de inicializacin y ponerlo en la localizacin por defecto para nuestra
plataforma, al menos inicialmente para la instalacin. Bajo UNIX, el lugar por defecto es
$ORACLE_HOME/dbs; bajo Windows, es $ORACLE_HOME\database. A continuacin se muestra un fichero
de inicializacin de ejemplo:
# Cache and I/O
DB_BLOCK_SIZE=4096
DB_CACHE_SIZE=20971520
# Cursors and Library Cache
CURSOR_SHARING=SIMILAR
OPEN_CURSORS=300
# Diagnostics and Statistics
BACKGROUND_DUMP_DEST=/u01/oracle11g/admin/rjbdb/bdump
CORE_DUMP_DEST=/u01/oracle11g/admin/rjbdb/cdump
TIMED_STATISTICS=TRUE
USER_DUMP_DEST=/u01/oracle11g/admin/rjbdb/udump
# Control File Configuration
CONTROL_FILES=("/u01/oracle11g/prod/rjbdb/control01.ctl",
"/u02/oracle11g/prod/rjbdb/control02.ctl",
"/u03/oracle11g/prod/rjbdb/control03.ctl")
# Archive
LOG_ARCHIVE_DEST_1='LOCATION=/u06/oracle11g/oradata/rjbdb/archive'
# New log archive format. If compatibility 10.0 and up,
# this is enforced.
LOG_ARCHIVE_FORMAT=%t_%s_%r.dbf
# The following parameter is deprecated in 10iR1
# LOG_ARCHIVE_START=TRUE
# Shared Server
# Starts shared server if set > 0.
SHARED_SERVERS=2
# Uncomment and use first DISPATCHERS parameter
# below when your listener is
# configured for SSL
# (listener.ora and sqlnet.ora)
# DISPATCHERS = "(PROTOCOL=TCPS)(SER=MODOSE)",
# "(PROTOCOL=TCPS)(PRE=oracle.aurora.server.SGiopServer)"
DISPATCHERS="(PROTOCOL=TCP)(SER=MODOSE)",

Oracle /22
"(PROTOCOL=TCP)(PRE=oracle.aurora.server.SGiopServer)",
(PROTOCOL=TCP)
# Miscellaneous
COMPATIBLE=10.0.0
DB_NAME=rjbdb
# Distributed, Replication and Snapshot
DB_DOMAIN=rjbdba.com
REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE
# Network Registration
INSTANCE_NAME=rjbdb
# Pools
JAVA_POOL_SIZE=31457280
LARGE_POOL_SIZE=1048576
SHARED_POOL_SIZE=52428800
# Processes and Sessions
PROCESSES=150
# Redo Log and Recovery
FAST_START_MTTR_TARGET=300
# Resource Manager
RESOURCE_MANAGER_PLAN=SYSTEM_PLAN
# Sort, Hash Joins, Bitmap Indexes
SORT_AREA_SIZE=524288
# Automatic Undo Management
UNDO_MANAGEMENT=AUTO
UNDO_TABLESPACE=undotbs
5) Conectar la instancia usando SQL*Plus:
SQLPLUS /NOLOG
CONNECT SYS/contrasea AS SYSDBA
Ntese que aunque la instancia misma ya exista, no hay mucho que podamos hacer puesto que an no
hemos creado la base de datos.
6) Crear un fichero de parmetros de servidor (SPFILE). Si el fichero de inicializacin est en la
localizacin por defecto, el siguiente comando crear el SPFILE:
CREATE spfile FROM pfile;
7) Empezar la instancia usando el siguiente comando:
STARTUP NOMOUNT
Ntese que porque no tenemos una base de datos creada an, sta es la nica opcin que podemos
emplear.
8) Ejecutar el comando CREATE DATABASE. A continuacin hay un ejemplo:
CREATE DATABASE rjbdb
USER SYS IDENTIFIED BY paris703
USER SYSTEM IDENTIFIED BY tyler12
LOGFILE GROUP 1 ('/u02/oracle11g/oradata/rjbdb/redo01.log') SIZE 100M,
GROUP 2 ('/u04/oracle11g/oradata/rjbdb/redo02.log') SIZE 100M,
GROUP 3 ('/u06/oracle11g/oradata/rjbdb/redo03.log') SIZE 100M
MAXLOGFILES 6
MAXLOGMEMBERS 5
MAXLOGHISTORY 1
MAXDATAFILES 100
MAXINSTANCES 1
CHARACTER SET US7ASCII
NATIONAL CHARACTER SET AL16UTF16
DATAFILE '/u01/oracle11g/oradata/rjbdb/system01.dbf' SIZE 325M REUSE
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE '/u01/oracle11g/oradata/rjbdb/sysaux01.dbf'SIZE 325M REUSE

Oracle /23
DEFAULT TABLESPACE tbs_1
DEFAULT TEMPORARY TABLESPACE tempts1
TEMPFILE '/u01/oracle11g/oradata/rjbdb/temp01.dbf'SIZE 20M REUSE
UNDO TABLESPACE undotbs
DATAFILE '/u02/oracle11g/oradata/rjbdb/undotbs01.dbf'
SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
Hay varias cosas a destacar en este ejemplo. Se explicitan las contraseas de SYS y SYSTEM; si no se
especifican aqu, tendrn como valores por defecto "change_on_install" y "manager" respectivamente. Los
grupos de archivos de deshacer tienen slo un miembro cada uno; una vez que nuestra base de datos est
en produccin deberamos multiplexarlos. Ya que especificamos un tablespace de deshacer con el
parmetro UNDO_TABLESPACE en el archivo de parmetros de inicializacin, necesitamos crear este
tablespace aqu; sino, la instancia no se iniciar.
Despus de que se cree la base de datos, es montada y abierta para su uso.
9) Crear tablespaces adicionales para los usuarios, ndices y aplicaciones.
10) Construir las vistas del diccionario de datos con los scripts proporcionados catalog.sql y catproc.sql. El
script catalog.sql crea vistas a partir de las tablas del diccionario de datos, vistas de rendimiento dinmico, y
sinnimos pblicos para muchas de las vistas. A las vistas del grupo PUBLIC se les concede slo acceso de
lectura. El script catproc.sql establece PL/SQL.
11) Crear respaldo de la base de datos usando copias en fro o el Administrador de Respaldo. En el caso
de que la base de datos falle en las etapas iniciales del despliegue, tendremos una base de datos completa y
ejecutndose para restaurar, y ms probablemente no tendremos que recrear la base de datos desde el
principio.
3. Servidor de Oracle
Un servidor Oracle es el software que permite una administracin y desarrollo de bases de datos de Oracle.
Tiene tres posibilidades de ejecucin:
Local o basada en host. El servidor se ejecuta en la misma mquina en la que se conectan los clientes.
La versin personal de Oracle Database produce servidores de este tipo.
Cliente-Servidor. Enfoque ms tpico. El servidor reside en un ordenador distinto respecto al que los
usuarios van a usar para conectarse a la base de datos.
Cliente-Servidor de Aplicaciones-Servidor. Los usuarios acceden a un servidor de aplicaciones
(Oracle Application Server) que, a su vez, accede al servidor Oracle. Los tres elementos (cliente, servidor
de aplicaciones, servidor Oracle) pueden estar en tres mquinas distintas.
3.1. Elementos del servidor Oracle
El servidor Oracle est formado por dos elementos:
La instancia de la base de datos. Consta de datos (llamados estructuras de memoria) y de procesos en
memoria (procesos background) necesarios para dar servicio a los usuarios de la base de datos. Puede haber
ms de una instancia si se distribuye la base de datos en ms de una mquina. Cada instancia abre una y
slo una base de datos.
Ficheros en disco. Representan la base de datos en s. Consta de:
- Estructuras lgicas: Tablespaces, objetos del esquema de usuario.
- Estructuras fsicas: Los ficheros de datos almacenados en disco. Los ficheros de datos (asociados a los
tablespaces), los ficheros deshacer y los ficheros de control.
3.2. Conexiones.
Para establecer una sesin con la base de datos, el usuario necesita conectarse con la instancia de la base de
datos. Normalmente esto significa arrancar una herramienta cliente como SQL*Plus o la Consola de
Administracin de Oracle, o ejecutar una aplicacin de desarrollo de bases de datos (como Oracle Forms);
entonces se ejecuta un proceso de usuario.
Cuando esto ocurre, en el servidor se establece un proceso de servidor. Este proceso es el encargado de
comunicar al usuario con la instancia Oracle en nombre del proceso de usuario. Cada vez que el usuario
ejecuta instrucciones SQL, stas son transmitidas a la instancia Oracle por el proceso servidor. De este modo
una conexin es un camino entre un proceso de usuario y un servidor Oracle.
Cada sesin es una conexin de un usuario con el servidor Oracle. Un usuario puede establecer mltiples
sesiones (si se conecta desde diferentes herramientas y mquinas).

Oracle /24
3.3. Estructura de las bases de datos Oracle.
Desde el punto de vista de Oracle, una base de datos es una coleccin de datos tratados como una nica
unidad. Una base de datos Oracle contiene tres tipos de ficheros:
Archivos de datos (.DBF). Contiene los datos actuales de la base de datos as como el diccionario de
datos.
Archivos rehacer o redo logs (.LOG). Almacenan datos de transacciones recuperables en caso de error
grave.
Archivos de control (.CTL). Necesarios para mantener la integridad de la base de datos.
Adems se utilizan otros archivos de forma auxiliar
Archivos de parmetros (.ora). Que definen algunas caractersticas de una instancia Oracle.
Archivos de contraseas. Que sirven para autentificar a los usuarios.
Copias de archivos rehacer. Utilizadas para la recuperacin de datos.
3.4. Instancia de la base de datos.
La instancia de la base de datos es uno de los dos elementos de cualquier base de datos Oracle. Sirve para
gestionar los datos de la base de datos y proporcionar servicio a los usuarios que acceden a la misma.

Est compuesta de:


Estructuras en memoria.
Procesos en segundo plano (background).
En las estructuras en memoria nos encontramos con:
SGA, la abreviatura de System Global Area o rea Global de Sistema. Est situada al inicio de los datos de
la instancia y contiene los datos e informacin de control de la instancia.
Est formada por las siguientes estructuras:
- Shared pool, o fondo comn compartido. Almacena las ltimas instrucciones SQL y PL/SQL
ejecutadas. Posee dos estructuras internas: la cach de instrucciones (Library cache), que almacena las
ltimas instrucciones SQL y PL/SQL ejecutadas; y la cach del diccionario de datos, que almacena las
ltimas definiciones de la base de datos utilizadas (tablas, ndices, privilegios, usuarios,...).
Cada vez que una instruccin utiliza un nombre de la base de datos (tabla, ndice,...) se comprueba en el
diccionario de datos y se almacena en este cach. De este modo la siguiente vez no hace falta acceder al
diccionario de datos real.
- Cach buffer de la base de datos. Almacena los ltimos bloques de datos accedidos por los usuarios.
- Buffer de archivo deshacer. Almacena los ltimos cambios realizados a los bloques de datos de la
base de datos.
- Large pool. Opcional. Se utiliza como memoria de sesin y para realizar operaciones de backup.
- Java pool. Opcional. Se utiliza como cach de los comandos Java.

Oracle /25
- Otras estructuras
PGA, la abreviatura de Program Global Area o Zona global de los programas. En ella se almacenan los
datos correspondientes a un proceso (slo un proceso puede utilizar esta rea). Incluye:
- reas de ordenacin. Para acelerar las tareas de ordenacin de datos.
- Informacin de sesin. Usuario, privilegios,...
- Estado del cursor. Tareas SQL actualmente en ejecucin.
- Espacio de pila. Variables y otros datos.
En Oracle los procesos pueden ser de estos tipos:
Proceso de usuario. Lanzado por el usuario para pedir interaccin con la base de datos.
Proceso de servidor. Hacen de enlace entre los procesos de usuarios y el servidor Oracle. Se utilizan
como manejadores de los procesos de usuario. Los comandos de usuario se envan a estos procesos que se
encargan de solicitar peticiones a la base de datos mediante el interfaz de programas de Oracle (OPI, Oracle
Program Interface).
Procesos en segundo plano (background). Cada instancia de Oracle arranca una serie de procesos de
fondo. Los procesos obligatorios son:
- DBWR (DataBase WRiter). Proceso encargado de escribir en los ficheros de datos los buffers ms
antiguos de la memoria, para que la base de datos vaya almacenando los cambios.
- LGWR (LoG WRiter). Escribe los datos a los ficheros deshacer (redo) desdela cach de archivos
deshacer.
- CKPT. Actualiza todas las cabeceras de los ficheros de datos para que aparezca la nueva disposicin de
datos. Esto ocurre cuando se genera un punto de comprobacin.
- SMON (System MONitor). Permite recuperar la instancia de la base de datos en caso de cada fatal
(cuando el sistema falla por ejemplo).
- PMON (Process MONitor). Es el encargado de gestionar adecuadamente los procesos que fallan. Ante
cadas de procesos, PMON se encarga de restaurarlos datos adecuadamente.
- SQL *Net Listener. Es el encargado de encaminar por una red solicitudes de un cliente a un servidor
de base de datos Oracle. Este proceso escuchador (listener) est tanto en el cliente como en el servidor.
Puede encaminar solicitudes que se dirigen a varias instancias.
3.5. Procesamiento de instrucciones SQL.
Para poder ejecutar SQL sobre la base de datos, hay que conectarse con la instancia Oracle de la base de
datos, lo cual requiere la comunicacin entre un proceso cliente y el servidor (el proceso cliente puede ser una
instancia de SQL*Plus, por ejemplo). Los componentes utilizados por Oracle para procesar el SQL dependen
del cdigo enviado:
- Las consultas devuelven filas.
- Las instrucciones DML (Lenguaje de Manipulacin de Datos) graban cambios.
- La instruccin COMMIT asegura el proceso de la transaccin.
Pero de manera general los pasos en ese proceso son:
1) El usuario abre la herramienta que permite el envo de peticiones SQL (por ejemplo SQL*Plus).
2) El usuario introduce su nombre de usuario y contrasea.
3) Oracle consulta el diccionario de datos para verificar la existencia del usuario y para validar su permiso
de conexin. Si lo tiene, se produce la conexin.
4) El usuario escribe la instruccin SQL (por ejemplo, una instruccin de modificacin).
5) Oracle traduce la instruccin con el analizador de instrucciones (devolvera un error si la instruccin no
es vlida).
6) Oracle traduce los nombres usados en la instruccin con la ayuda del diccionario de datos.
7) Si es una instruccin de mostrar datos (SELECT), comprueba si otros usuarios han enviado hace poco
esa misma instruccin; eso lo comprueba en el cach de instrucciones de la SGA. Si la instruccin est ah
coge los resultados del bfer cach de la base de datos.
8) Si la instruccin conlleva cambios, el servidor bloquea las filas que se modificarn.
9) La base de datos graba los cambios (si los hubo) y actualiza los archivos de deshacer.
10) La base de datos graba los nuevos valores para los datos.
11) Oracle libera del bloqueo los registros.
12) El usuario recibe un mensaje de xito.

Oracle /26
3.6. Archivos de inicializacin
Adems de estructuras de disco y de memoria, un servidor Oracle necesita ciertos archivos para poder
ejecutarse. Estos archivos se establecen durante la creacin de la base de datos, y se consultarn cada vez que
se arranque la base de datos, por lo que deben estar disponibles.
Esta seccin explica los ficheros de parmetros que utiliza la base de datos Oracle para arrancar: init.ora y
spfile.ora.
3.6.1. Parmetros de inicializacin y configuracin.
Oracle es una base de datos configurable mediante una serie de parmetros, de forma que el administrador
puede optimizar los valores de esta base de datos. Estos parmetros de optimizacin y configuracin de base
de datos se almacenan en un fichero. Este fichero es el primero al que se accede al arrancar la base de datos
Oracle y se denomina init.ora.
En este fichero se escriben los parmetros de configuracin de Oracle; pero si en este archivo alguno de los
parmetros de Oracle configurables no se encuentra, entonces tomar el valor que Oracle tenga por defecto.
Existen tres tipos de parmetros en Oracle:
Parmetros "fijos": Son parmetros que una vez instalada la base de datos no se pueden volver a
modificar/configurar. El juego de caracteres es un claro ejemplo.
Parmetros estticos: Son parmetros que se pueden modificar, pero su modificacin implica cerrar la
base de datos y volverla a abrir para que los lea del fichero y pueda realizar el cambio.
Parmetros dinmicos: Son parmetros cuyo valor se puede cambiar sin necesidad de cerrar la base de
datos, a diferencia de los estticos.
3.6.2. Ubicacin y nomenclatura del fichero init.ora.
El archivo init.ora se encuentra en Windows dentro del directorio ORACLE_HOME\database y en UNIX
dentro del directorio ORACLE_HOME/dbs. El nombre del archivo siempre corresponder a initsid.ora siendo
sid el nombre de la base de datos. (ste es el nombre que Oracle buscar al arrancar la base de datos.)
3.6.3. El fichero spfile.ora.
El fichero init.ora no es el nico archivo de parmetros que podemos encontrar en las base de datos Oracle.
A partir de la versin 9 se puede encontrar el archivo spfile.ora. ste es el primer archivo que va a "buscar"
Oracle en su arranque de base de datos. Si no encuentra este archivo entonces ir a buscar el archivo init.ora.
Este archivo est codificado y las modificaciones en l se realizarn mediante una serie de comandos Oracle
que posteriormente indicaremos. La ubicacin de este archivo es la misma que la de init.ora.
3.6.4. Cambio de los valores de los parmetros.
Si queremos realizar algn cambio en algn parmetro de base de datos tenemos que diferenciar dos cosas:
Si el cambio es en init.ora o spfile.ora.
Tipo de parmetro sobre el que se quiere hacer el cambio.
Vamos a explicar como realizar un cambio en el fichero init.ora, para ello tenemos que tener en cuenta el
tipo de parmetro que vamos a cambiar. Como se ha indicado, existen tres tipos de parmetros; dejando a un
lado los parmetros fijos (aquellos que no se pueden cambiar una vez instalada la base de datos) nos quedan
los parmetros estticos y los dinmicos. Para modificar un parmetro esttico nos basta con editar el fichero
init.ora y modificar o aadir ah el parmetro nuevo reiniciando la base de datos para que coja estos
cambios. En cuando a los parmetros dinmicos podemos cambiarlos en tiempo real sin parar la base de
datos mediante la siguiente sentencia:
ALTER SYSTEM SET parmetro = valor;
Este cambio pasa automticamente a ser efectivo en la base de datos, aunque tenemos que tener en cuenta
que la prxima vez que la base de datos sea iniciada se volver a leer el fichero de parmetros init.ora.
Para realizar cualquier cambio en spfile.ora hay que usar el comando ALTER SYSTEM aadiendo la clusula
SCOPE con una serie de valores que detallaremos a continuacin con un ejemplo.
Para cambiar el parmetro shared_pool_size a 150 Megas:
ALTER SYSTEM SET shared_pool_size= 150 SCOPE=spfile
En este caso hemos cambiado el parmetro y estos cambios se han recogido en el archivo spfile, por lo tanto
permanecer cuando sea reiniciada la base de datos.
ALTER SYSTEM SET shared_pool_size= 150 SCOPE=memory
En este caso se ha cambiado el parmetro y estos cambios se han recogido solamente en memoria, esto
quiere decir que se hacen efectivos al momento (si el tipo de parmetro lo permite) pero este cambio no se
ver reflejado en el archivo de parmetros.
ALTER SYSTEM SET shared_pool_size= 150 SCOPE=both

Oracle /27
En este caso el parmetro se cambia tanto en el spfile como en memoria.
3.7. Arranque y parada de la base de datos.
Durante el arranque y parada de la BD se suceden un conjunto de eventos que llevan a la base de datos por
varios estados.
Para que los usuarios puedan acceder a la base de datos el administrador debe abrirla con el comando
STARTUP OPEN. El siguiente es un ejemplo de apertura de una base de datos llamada Test.
STARTUP OPEN Test
ORACLE instancia iniciada.
Total System Global Area 4512688 bytes.
Fixed Size 39732 bytes.
Variable Size 4055164 bytes.
Database Buffers 409600 bytes.
Redo Bufers 8192 bytes.
Database mounted.
Database opened.
Cuando se ejecuta el comando STARTUP OPEN la base de datos pasa por tres estados ( NOMOUNT, MOUNT y
OPEN) antes de estar disponible. El administrador de base de datos puede arrancar la base de datos hasta uno
de los estados con el comando STARTUP: STARTUP NOMOUNT o STARTUP MOUNT.
A continuacin se describe cada uno de los estados por los que pasa la base de datos en el proceso de
arranque.
Estado nomount.
Se arranca la base de datos en el estado nomount con el siguiente comando:
STARTUP OPEN Test
Oracle lee el fichero init.ora, localiza los ficheros de control, crea e inicializa la SGA, y finalmente arranca
todos los procesos Oracle. En este estado la instancia de base de datos est arrancada.
Se deber llevar la base de datos al estado nomount cuando se est creando la base de datos o cuando se
est restaurando un fichero de control despus de haberlo perdido.
Estado mount.
Se cambia la base de datos al estado mount con el siguiente comando:
ALTER DATABASE MOUNT;
Oracle abre los ficheros de control para localizar los ficheros de datos y los redo log, pero no se realiza
ninguna comprobacin en ellos en este momento. La instancia monta la base de datos y la bloquea,
verificando que ninguna otra instancia ha montado la misma base de datos.
Hay varias razones para querer tener la base de datos en el estado mount. En general, todas las
sentencias SQL del tipo ALTER DATABASE se deben ejecutar en esta etapa. Algunas de las operaciones a
realizar cuando la base de datos est montada son:
Efectuar recuperaciones.
Poner online/offline un fichero de datos.
Recolocar los ficheros de datos y redo log.
Crear un nuevo grupo o miembro redo log, o borrar un grupo o miembro redo log existente.
Estado open.
Se cambia la base de datos al estado open con el siguiente comando:
ALTER DATABASE OPEN;
Durante esta etapa, la instancia abre la base de datos, bloquea los ficheros de datos, y abre todos los
ficheros redo log. Si la instancia abre la base de datos despus de una terminacin anormal, o despus de
una cada, se ejecutar automticamente el proceso de recuperacin utilizando los ficheros redo log. Al
final de esta etapa la base de datos est dispuesta para su uso normal.
Para parar la base de datos se usa el comando SHUTDOWN como se puede ver en el siguiente ejemplo:
SHUTDOWN
Database closed.
Database dismounted.
ORACLE instance shut down.
Este comando admite tres opciones: NORMAL, IMMEDIATE y ABORT.
SHUTDOWN NORMAL

Oracle /28
Impide el acceso a la base de datos, espera a que todos los usuarios completen todas sus peticiones y se
desconecten del servidor. Purga todos los bferes de datos y cachs de redo log, actualizando los ficheros
de datos y de redo log, se eliminan los bloqueos de ficheros, se completan las transacciones en marcha, se
actualizan las cabeceras de ficheros, elimina los hilos, libera los bloqueos de la base de datos por parte de la
instancia, y sincroniza los ficheros de control y de datos.
En resumen, la opcin normal cierra la base de datos, la desmonta y para la instancia con cuidado y es la
opcin recomendada para parar la base de datos.
SHUTDOWN IMMEDIATE
En ciertas ocasiones puede ser necesario parar la base de datos de modo inmediato. Si es as, las sentencias
en proceso son terminadas inmediatamente, cualquier transaccin no confirmada es vuelta atrs y la base
de datos es parada. La nica desventaja de utilizar esta opcin es que Oracle no espera a que los usuarios
se desconecten. Sin embargo, la base de datos ser consistente y no se necesitar recuperacin en el
siguiente arranque.
SHUTDOWN ABORT
En situaciones de emergencia, y cuando todo lo dems falla, se debe realizar una parada de este tipo. Por
ejemplo, cuando un proceso de la instancia muere y la base de datos no puede pararse de modo normal o
inmediato. Cuando se utiliza la opcin ABORT las sentencias SQL son terminadas bruscamente, y las
transacciones no confirmadas no son vueltas atrs. Parar la base de datos con la opcin ABORT requiere
recuperacin en la siguiente vez que arranque la base de datos y esta opcin debe ser utilizada slo cuando
no quede ms remedio.
4. Introduccin a los conceptos del sistema Oracle
4.1. Almacenamiento.
Una base de datos tiene una estructura lgica (que se manipula mediante comandos) y una estructura fsica (la
que realmente se almacena en disco).
La estructura lgica de Oracle est formada por: tablespaces, segmentos, extensiones y bloques de datos.
La estructura fsica est formada por: ficheros de datos y bloques de sistema.
4.2. Transacciones.
Los cambios en la base de datos no son guardados hasta que tras una serie de instrucciones se decide llevar a
cabo esos cambios. Hasta ese momento todo lo realizado se toma como provisional. Un fallo en la mquina
permitira invertir los cambios.
Una transaccin son varias operaciones SQL que forman una unidad de trabajo. Comienza cuando una
persona se conecta y de ah hasta que ejecuta la instruccin COMMIT (ejecutar la transaccin) o ROLLBACK
(anular la transaccin). La anulacin deja la base de datos en el estado anterior al comienzo de la transaccin.
Tras un COMMIT o un ROLLBACK comienza la siguiente transaccin.
En Oracle se admite adems el uso de puntos de ruptura (savepoints) para almacenar valores intermedios y
volver a cualquier de ellos si interesa. Pero esto ralentiza excesivamente el sistema.
4.3. Usuarios.
Los usuarios son las personas que acceden de una forma o de otra a la base de datos. Cada usuario tiene una
vista determinada de la base de datos. Hay varios conceptos sobre los usuarios a tener en cuenta.
Privilegios. Controlan el permiso que posee un usuario de ejecutar una determinada instruccin SQL.
Un usuario que quiera crear una tabla, deber tener el privilegio (o permiso) adecuado para ello.
Adems se pueden colocar privilegios en los objetos; es decir, un usuario propietario de una tabla puede
otorgar privilegios a esa tabla (se tratara de un privilegio a nivel de objeto) para que haya otros usuarios
que la puedan usar.
Rol. Son agrupaciones de privilegios que facilitan la tarea de gestionar a los usuarios. As, cuando una
serie de usuarios van a tener los mismos privilegios, se crea un rol que contenga esos privilegios y a esos
usuarios se les asigna el rol. Oracle proporciona varios roles ya predefinidos, por ejemplo el rol DBA da
privilegio absoluto a un usuario.
Esquemas. Estn asociados a los usuarios. Agrupan los objetos lgicos que pertenecen al usuario. Es
decir, es el conjunto de tablas, vistas, sinnimos, instantneas, enlaces de base de datos, procedimientos y
funciones, paquetes, etc. creados por un usuario.
Cada usuario tiene su propio esquema y, en principio, un usuario no tiene acceso a los elementos de otro

Oracle /29
usuario, salvo que sea un administrador o que otro usuario ceda el privilegio de utilizacin de uno o ms
de sus objetos al resto de usuarios.
La primera vez que un usuario crea un objeto en la base de datos, se crea un esquema con su mismo
nombre.
4.4. Prdidas de informacin.
Es una de las tareas y herramientas fundamentales que nos proporcionan las bases de datos. Hay posibilidad
de perder datos de nuestra base de datos por alguna de estas razones:
Fallo en una instruccin. Hay instrucciones que pueden provocar la prdida no deseada de cientos de
registros en un momento (DELETE o UPDATE). En ese caso basta con ejecutar una instruccin ROLLBACK
antes de que las instrucciones previas se confirmen.
Fallo en la comunicacin. Si una conexin de usuario se corta anulando el proceso de usuario
relacionado. En ese caso, Oracle anula los cambios de la ltima transaccin (el resto de transacciones s se
almacena).
Cada del servidor. Puede que la instancia Oracle se deje de ejecutar. En ese caso basta con lanzar de
nuevo la instancia. El proceso SMON se encargar de grabar los archivos deshacer y aplica de nuevo las
transacciones confirmadas. Se anulan los cambios no confirmados.
Prdida de datos en los archivos. Es el nico caso en el que tiene que intervenir el administrador. La
nica posibilidad es recuperarlos de una copia de seguridad.
4.5. Copias de seguridad.
Es una de las herramientas fundamentales de toda base de datos. Al hacer la copia de seguridad se nos
permite recuperar la informacin de esa copia. Eso hace que perdamos definitivamente los datos perdidos
desde la ltima copia de seguridad, de ah la importancia de hacer copias a menudo.
Hay una posibilidad de perder menos informacin y es hacer que la base de datos se ejecute en modo
"Archivo Log", lo que significa que se almacena, en un archivo de datos especial, los datos que se van
rechazando en los registros de deshacer por estar llenos. Lo malo de esta opcin es que el servidor funciona
ms lento; lo bueno es que en caso de desastre se pueden recuperar los datos almacenados.
Hay dos tipos de copia de seguridad:
En fro. La copia se realiza tras parar la instancia de Oracle. La copia de seguridad almacena todos los
datos de la base (incluidos los archivos de control y de deshacer).
En caliente. Ya que en muchos casos no se puede parar la instancia tan fcilmente (por estar 24 horas al
da funcionando). En ese caso es una indicacin la que se hace a la base de datos y la copia se realiza desde
el sistema operativo (copiando sin ms).
Otras posibilidades de copias son:
Catlogos de copia de seguridad. Que almacenan informacin sobre las copias realizadas, fechas,
datos, estructura,...
Copias de seguridad incrementales. Un problema de las copias es que, en bases extensas, la copia
tarda muchas horas. Cuando la copia termina, la informacin ya est desfasada. Las copias incrementales
slo almacenan los datos que han cambiado recientemente.
4.6. Bases de datos distribuidas.
Se trata de una base de datos a nivel lgico (los usuarios la manejan como una base de datos normal), pero
que en realidad (fsicamente) est implementada en varias ubicaciones fsicas, incluso en mquinas diferentes y
distantes.
Cada mquina ejecuta su propia instancia y conjuntos de archivos y todas se conectan en red para hacer que el
usuario no tenga que cambiar su cdigo para reflejar esta distribucin. La dificultad de esta estructura suele
estar aliviada por medio de instantneas que graban momentneamente los datos de las tablas distantes.
Permiten trabajar con los datos copiados y se programan para que cada cierto tiempo recojan nuevamente los
datos a fin de reflejar sus cambios.
Gracias a las instantneas no hace falta una sobrecarga excesiva de la base de datos.
4.7. Herramientas de Oracle.
El software del sistema de bases de datos Oracle incorpora herramientas para realizar la mayora de tareas
comunes en una base de datos:
Oracle Universal Installer. Gestor de instalaciones, controla cada nueva instalacin de software Oracle
a fin de que se integren de la mejor manera posible.

Oracle /30
SQL*plus. Programa cliente que permite conexin con el servidor Oracle para enviarle secuencias SQL
y PL/SQL.
iSQL*plus. Permite conexiones al servidor Oracle con la misma finalidad que el anterior pero utilizando
un navegador de Internet, lo que facilita el trabajo.
SQL*plus WorkSheet. Permite conexiones al servidor de Oracle, utilizando un entorno ms potente
(procede del Oracle Enterprise Manager).
Oracle Enterprise Manager. Entorno que permite la administracin y configuracin completa del
servidor Oracle.
SQL*Loader. Permite cargar en bases de datos de Oracle informacin que procede de un archivo de
texto. Necesaria para utilizar en las bases de datos de Oracle, informacin que procede de otro software.
Import/Export. Para importar y exportar datos entre instancias de Oracle. De un servidor a otro por
ejemplo. Tambin se utiliza como herramienta de copia de seguridad.
Servidor http de Oracle. Basado en el servidor Apache, permite opciones de documentacin y sobre
todo la comunicacin directa a travs de iSQL*Plus con el servidor Oracle sin tener necesidad de instalar
software adicional.
Net Manager. Permite la administracin de los servicios de red a fin de configurar las conexiones hacia
instancias de Oracle.
Oracle Forms. Permite crear aplicaciones visuales sobre bases de datos de Oracle.
Oracle Reports. Asistente para la produccin de informes.
Oracle Designer. Herramienta CASE de Oracle, para crear esquemas en el ordenador y que el software
produzca los resultados del mismo.
Oracle JDeveloper. Crea aplicaciones Java pensadas para desarrollar formularios sobre datos de Oracle
Oracle Developer Suite. Integra todos los componentes anteriores.
Oracle AS (Application Server). Servidor de aplicaciones de Oracle. Permite compilar aplicaciones J2EE.
Pro C/C++. Precompilador de C/C++ para Oracle.

Oracle /31
II. LENGUAJE DE CONSULTAS

1. SQL para Oracle


1.1. Introduccin.
El lenguaje de consulta estructurado SQL (Standar Query Language) es un lenguaje de base de datos
normalizado, utilizado por el motor de los Gestores de Base de Datos relacionales que existen en la
actualidad.
SQL pretende ser un lenguaje que simula su escritura en lenguaje normal. De ah que se le considere un
lenguaje de cuarta generacin. Consta de palabras especiales y de expresiones.
Se trata de un lenguaje que intenta agrupar todas las funciones que se le pueden pedir a una base de datos.
Las instrucciones SQL se introducen a travs de una herramienta que las traduce inmediatamente a la base de
datos, por lo que se ejecutan al instante.
Las instrucciones SQL se colocan como parte del cdigo de otro lenguaje anfitrin (C, Java, Pascal, Visual
Basic, etc.). Estas instrucciones estn separadas del resto del cdigo de forma conveniente. Al compilar el
cdigo se utiliza un precompilador de la propia base de datos para traducir el SQL.
Las aplicaciones clientes deben acceder al servidor de Oracle a travs del puerto 1521.
1.2. Cdigo SQL y normas de escritura.
El cdigo SQL consta de los siguientes elementos:
- Comandos. Las distintas instrucciones que se pueden realizar desde SQL: SELECT, DML, DDL,
instrucciones de transferencia, e instrucciones de control del lenguaje.
- Clusulas. Son palabras especiales que permiten modificar el funcionamiento de un comando ( WHERE,
ORDER BY, etc.).
- Operadores. Permiten crear expresiones complejas.
- Funciones. Para conseguir valores complejos (SUM(), DATE(), etc.).
- Constantes. Valores literales para las consultas, nmeros, textos, caracteres, etc.
- Datos. Obtenidos de la propia base de datos
Las normas de escritura son:
- En SQL no se distingue entre maysculas y minsculas. Da lo mismo cmo se escriba.
- El final de una instruccin lo determina el signo del punto y coma.
- Los comandos SQL (SELECT, INSERT, ...) pueden ser partidos por espacios o saltos de lnea antes de
finalizar la instruccin.
- Se pueden tabular lneas para facilitar la lectura, si fuera necesario.
- Los comentarios en el cdigo SQL comienzan por /* y terminan por */.
1.3. SQL*Plus.
Para poder enviar sentencias SQL al servidor Oracle, ste incorpora la herramienta SQL*Plus. Toda
instruccin SQL que el usuario escribe es verificada por este programa. Si la instruccin es vlida se enva
a Oracle, el cual retornar la respuesta a la instruccin; respuesta que puede ser transformada por el
programa SQL*Plus para modificar su salida.
Para que el programa SQL*Plus funcione en el cliente, el ordenador cliente debe haber sido configurado
para poder acceder al servidor Oracle. En cualquier caso, al acceder a Oracle con este programa siempre
preguntar por el nombre de usuario y contrasea. stos son datos que nos tiene que proporcionar el
administrador de la base de datos Oracle (DBA).
Para conectarnos mediante SQL*Plus podemos ir a la lnea de comandos y escribir el texto sqlplus. A
continuacin aparecer la pantalla siguiente:

Oracle /32
En esa pantalla se nos pregunta el nombre de usuario y contrasea para acceder a la base de datos
(informacin que deber indicarnos el administrador o DBA). Tras indicar esa informacin conectaremos con
Oracle mediante SQL*Plus, y veremos aparecer el smbolo:
SQL>
Tras el cual podremos comenzar a escribir nuestros comandos SQL. Ese smbolo puede cambiar por un
smbolo con nmeros 1, 2, 3, etc.; en ese caso se nos indica que la instruccin no ha terminado y la lnea en la
que estamos.
Otra posibilidad de conexin consiste en llamar al programa SQL*Plus indicando la contrasea y base de
datos a conectar. El formato es:
slplus usuario/contrasea@nombreServicioBaseDeDatos
Ejemplo:
slplus usr1/miContra@inicial.forempa.net
En este caso conectamos con SQL*Plus indicando que somos el usuario usr1 con contrasea miContra y que
conectamos a la base de datos inicial de la red forempa.net. El nombre de la base de datos no tiene porqu
tener ese formato, habr que conocer cmo es el nombre que representa a la base de datos como servicio de
red en la red en la que estamos.
1.4. Versin grfica de SQL*Plus.
Oracle incorpora un programa grfico para Windows para utilizar SQL*Plus. Se puede llamar a dicho
programa desde las herramientas instaladas en el men de programas de Windows, o desde la lnea de
programas escribiendo sqlplusw. Al llamarle aparece esta pantalla:

Como en el caso anterior, se nos solicita el nombre de usuario y contrasea. La cadena de Host es el
nombre completo de red que recibe la instancia de la base de datos a la que queremos acceder en la red en la
que nos encontramos.
Tambin podremos llamar a este entorno desde la lnea de comandos utilizando la sintaxis comentada
anteriormente. En este caso:
slplusw usuario/contrasea@nombreServicioBaseDeDatos
Esta forma de llamar al programa permite entrar directamente sin que se nos pregunte por el nombre de
usuario y contrasea.
1.5. iSQL*Plus.
Es un producto ideado desde la versin 9i de Oracle. Permite acceder a las bases de datos Oracle desde un

Oracle /33
navegador. Para ello necesitamos tener configurado un servidor web Oracle que permita la conexin con la
base de datos. Utilizar iSQL*Plus es indicar una direccin web en un navegador, esa direccin es la de la
pgina iSQL*Plus de acceso a la base de datos: http://host_oracle:7778/isqlplus. (El nmero de puerto, en este
caso 7778, puede variar en cada instalacin.)
Desde la pgina de acceso se nos pedir nombre de usuario, contrasea y nombre de la base de datos con la
que conectarnos (el nombre de la base de datos es el nombre con el que se la conoce en la red). Si la conexin
es vlida aparece esta pantalla:

En esa pantalla, en el apartado Introducir Sentencias, se escribe la sentencia que deseamos enviar. El botn
Ejecutar hace que se valide y se enve a Oracle. Se pueden almacenar sentencias SQL usando el botn
Examinar y cargar sentencias previamente guardadas mediante Cargar archivos de comandos.
2. Estructura del lenguaje SQL.
En SQL se distinguen los siguientes tipos de instrucciones:
- SELECT. Se trata del comando que permite realizar consultas sobre los datos de la base de datos.
Obtiene datos de la base de datos.
- DML, Data Manipulation Language (Lenguaje de manipulacin de datos). Modifica filas (registros) de la
base de datos. Lo forman las instrucciones INSERT, UPDATE, MERGE y DELETE.
- DDL, Data Definition Language (Lenguaje de definicin de datos). Permiten modificar la estructura de las
tablas de la base de datos. Lo forman las instrucciones CREATE, ALTER, DROP, RENAME y TRUNCATE.
- Instrucciones de transferencia. Administran las modificaciones creadas por las instrucciones DML. Lo
forman las instrucciones ROLLBACK, COMMIT y SAVEPOINT.
- DCL, Data Control Language (Lenguaje de control de datos). Administran los derechos y restricciones de
los usuarios. Lo forman las instrucciones GRANT y REVOKE.
2.1. Tipos de datos.
Como todo lenguaje de programacin, SQL-Oracle posee una serie de tipos de datos. stos se corresponden
con los tipos de datos que pueden utilizarse en Oracle al definir tablas.

Oracle /34
Datos numricos:
Number(38) Equivale al tipo Integer, Int o SamllInt
Number Equivale al tipo Float, Double o Real
Number(m,d) Nmeros decimales de coma fija, con m cifras en total y d decimales
ROWID Valor hexadecimal que representa la direccin nica de una fila en su tabla.
Datos de carcter:
Char(n) Almacena n caracteres en formato ASCII (como mximo 2000). Siempre se utilizan los
n caracteres indicados, incluso si la entrada de datos es inferior. Cuando se recuperen
los datos es como si fuesen rellenados con espacios en blanco hasta completar la
longitud del campo.
Varchar2(n) Almacena n caracteres en formato ASCII (como mximo 4000). Al recuperar los datos,
slo se recupera el texto asignado con su longitud original.
Nchar(n) Almacena n caracteres en formato UNICODE. Siempre se utilizan los n caracteres
indicados, incluso si la entrada de datos es inferior.
Nvarchar2(n) Almacena n caracteres en formato UNICODE.
Datos de fecha:
Date Almacena fechas en formato da, mes, ao, hasta el nivel de segundos.
TimeStamp Almacena fechas hasta el nivel de fracciones de segundo.
Interval Almacena intervalos de tiempo. Por ejemplo, para indicar un perodo de 3 aos y
algunos meses:
CREATE TABLE tiempo (meses INTERVAL YEAR(3) TO MONTH);
INSERT INTO tiempo VALUES ('3-2');
Para indicar un intervalo hasta segundos (sin decimales en segundos):
CREATE TABLE tiempo (das INTERVAL DAY(3) TO SECOND(0));
INSERT INTO tiempo VALUES('2 7:12:23');
El valor entre parntesis indicado para YEAR y DAY establece la precisin del ao y del
da respectivamente.
Datos binarios grandes:
Raw Sirve para almacenar valores binarios de hasta 2000 bytes (se puede especificar el
tamao mximo entre parntesis).
Long Raw Almacena hasta 2GB.
Blob, Clob, Almacenan datos binarios de varios gigas (imgenes, vdeos, etc.).
Nclob y Bfile
Datos de texto grandes:
Long Clob Almacenan secuencias de caracteres de varios gigas.

2.2. Operadores
SQL-Oracle incluye los operadores habituales:
Operadores de comparacin Significado
= Igual que
<> != ^= Distinto de
< Menor que
<= Menor o igual que
> Mayor que
>= Mayor o igual que

Operadores lgicos Significado


AND Y lgico
OR O lgico
NOT Complementario

Operadores para nulos Significado


IS NULL Indica si una expresin es nula

Oracle /35
IS NOT NULL Indica si una expresin no es nula

Operadores para texto Significado


|| Concatenador de texto
LIKE Evala un texto contra una expresin regular

2.3. Funciones predefinidas.


Todos los SGBD implementan funciones para facilitar la creacin de consultas complejas. Esas funciones
dependen del SGBD que utilicemos; las que aqu se comentan son algunas de las que se utilizan con Oracle.
Oracle proporciona una tabla llamada DUAL con la que se permiten hacer pruebas. Esa tabla tiene un solo
campo (llamado DUMMY) y una sola fila de modo que es posible hacer pruebas sobre ella. Por ejemplo, la
consulta:
SELECT SQRT(5) FROM DUAL;
Muestra una tabla con el contenido del clculo SQRT(5) (la raz cuadrada de 5).
2.3.1. Funciones de cadena.
ASCII(texto) Retorna la representacin decimal (en el juego de caracteres de la base de datos)
del primer caracter del texto.
CHR(cdigo) Retorna el caracter que se corresponde con el cdigo dado en el juego de
caracteres de la base de datos.
CONCAT(texto1, texto2) Concatena dos textos (igual que el operador ||).
INITCAP(texto) Coloca la primera letra de cada palabra en maysculas.
INSTR(texto, textoBuscado Obtiene la posicin en la que se encuentra el texto buscado en el texto inicial. Se
[,posInicial [, nAparicin]]) puede empezar a buscar a partir de una posicin inicial concreta e incluso indicar
el nmero de aparicin del texto buscado. Ejemplo, si buscamos la letra a y
ponemos 2 en nAparicin, devuelve la posicin de la segunda letra a del texto). Si
no lo encuentra devuelve 0.
LENGTH(texto) Obtiene el tamao del texto.
LOWER(texto) Convierte el texto a minsculas.
LPAD(texto,longitud,pad) Alarga por la izquierda. Crea un nuevo texto a partir del dato con la longitud
especificada aadiendo por la izquierda el caracter pad especificado o espacios en
blanco si no se especifica.
LTRIM(texto) Elimina los espacios a la izquierda que posea el texto.
REPLACE(texto, textoABuscar, Buscar el texto a buscar en un determinado texto y lo cambia por el indicado
textoReemplazo) como texto de reemplazo.
RPAD(texto,longitud,pad) Alarga por la derecha. Crea un nuevo texto a partir del dato con la longitud
especificada aadiendo por la derecha el caracter pad especificado o espacios en
blanco si no se especifica.
RTRIM(texto) Elimina los espacios a la derecha del texto.
SOUNDEX(texto) Retorna la representacin fontica de un texto.
SUBSTR(texto,n[,m]) Obtiene los m siguientes caracteres del texto a partir de la posicin n (si m no se
indica se cogen desde n hasta el final).
TRIM(caracteres Elimina del texto los caracteres indicados. Por ejemplo TRIM('h' FROM nombre)
FROM texto) elimina las haches de la columna nombre que estn a la izquierda y a la derecha.
TRIM(texto) Elimina los espacios en blanco a la izquierda y la derecha del texto y los espacios
dobles del interior.
UPPER(texto) Convierte el texto a maysculas.
REGEXP_INSTR, Versiones de INSTR, REPLACE y SUBSTR para expresiones regulares.
REGEXP_REPLACE y
REGEXP_SUBSTR
Cmo cortar y pegar cadenas.
Veremos cmo aplicar las funciones LPAD, RPAD, LTRIM, RTRIM, TRIM, LENGTH, SUBSTR y INSTR para cortar
y pegar cadenas de caracteres. Cada una de estas funciones realiza algo para cortar y pegar.
La funcin ms simple, LENGTH, nos dice la longitud de una cadena (cuntos caracteres tiene). Por ejemplo,
LENGTH('012345') retorna el valor 6.
RPAD y LPAD son muy parecidas. RPAD permite rellenar una cadena existente con un conjunto de caracteres
por el lado derecho. LPAD hace lo mismo pero por el lado izquierdo.

Oracle /36
Como ejemplo, la expresin RPAD('12345', 8) retorna la cadena ' 12345', en la cual se ha rellenado con tres
espacios en blanco por la derecha para que el resultado ocupe 8 caracteres.
Podemos tambin especificar el caracter de relleno. Por ejemplo, LPAD('12345',10,'.') produce la salida
'12345.....', donde se ha rellenado por la izquierda con cinco puntos.
Estas dos funciones son interesantes porque aplicadas a un campo de una base de datos nos pueden
garantizar que todos los valores de cada fila tengan la misma longitud.
Las funciones LTRIM, RTRIM y TRIM nos permiten recortar los espacios en blanco previos y posteriores de
cualquier cadena de caracteres. LTRIM elimina espacios en blanco por la izquierda, RTRIM por la derecha y
TRIM por ambos lados. Por ejemplo, RTRIM(' 12 34 ') produce la salida '12 34', donde se han recortado los
espacios en blanco por la derecha.
Tambin podemos especificar los caracteres de recorte. Por ejemplo, LTRIM('..0.012345..','0.') produce la
salida '12345..', donde se han recortado los puntos y los ceros por la izquierda.
Podemos combinar LTRIM y RTRIM para recortar por ambos lados. Por ejemplo, la expresin
LTRIM( RTRIM('000012345......','.'), '0')
produce la salida '12345', donde se han recortado primero los puntos por la derecha y despus los ceros por
la izquierda.
Si los caracteres a recortar por la izquierda y la derecha son los mismos podemos usar la funcin TRIM. Por
ejemplo, TRIM('0' FROM '00123450') produce la salida '12345', donde se han recortados los ceros por la
izquierda y por la derecha.
Podemos usar la funcin SUBSTR para extraer un trozo de una cadena. Se indica la posicin inicial del trozo
dentro de la cadena y opcionalmente se indica el nmero de caracteres del trozo. Por ejemplo, SUBSTR('Soy
una cadena',6,4) produce la salida 'a ca'.
Se pueden tambin usar nmero negativos en la funcin SUBSTR. Cuando se indica una posicin inicial
negativa, entonces es relativa al final de la cadena. Por ejemplo, SUBSTR('Soy una cadena",-4) produce la salida
'dena'. Ya que no se especifica la longitud en un tercer parmetro se retorna la subcadena hasta el final.
El valor del tercer parmetro de la funcin SUBSTR debe ser siempre positivo o no especificado. Si se usa un
nmero negativo la funcin retorna el valor NULL.
La funcin INSTR permite bsquedas simples o sofisticadas dentro de una cadena por un conjunto de
caracteres. Esta funcin no produce una nueva cadena como las funciones previas, sino que determina en qu
posicin dentro de la cadena est la subcadena buscada. INSTR tiene dos opciones, una dentro de la otra.
Podemos especificar la posicin de inicio para la bsqueda, de forma que se salta los caracteres anteriores a
esa posicin. Por ejemplo, INSTR('AABBAACCAADD','BB',1) busca la subcadena 'BB' dentro de la cadena
'AABBAACCAADD' a partir del primer caracter. El resultado de esta funcin ser 3.
Tambin podemos especificar qu ocurrencia buscamos. Si la subcadena buscada se repite varias veces dentro
de la cadena sobre la que se busca podemos indicar cul subcadena buscamos. Por ejemplo,
INSTR('AABBAACCAADD','AA',3,2) busca la segunda ocurrencia de la subcadena 'AA' a partir del tercer
caracter. El resultado de esa funcin ser 9.
Si slo especificamos la cadena y la subcadena, la funcin realiza la bsqueda de la primera ocurrencia desde
el primer caracter. Por ejemplo, INSTR('AABBAACCAADD','CC') devuelve el resultado 7.
Cmo trabajar a nivel de caracteres en una cadena.
Las funciones LOWER, UPPER e INITCAP permiten modificar los caracteres de una cadena.
La funcin LOWER toma como argumento una cadena y retorna otra con todos sus caracteres en minsculas.
Por ejemplo, LOWER('tEXto') produce la salida 'texto'. La funcin UPPER hace lo opuesto, convierte todos los
caracteres a maysculas. Por ejemplo, LOWER('TEXto') produce la salida 'TEXTO'. Por su parte, la funcin
INITCAP convierte a maysculas la letra inicial de cada palabra de la cadena. Por ejemplo, INITCAP('uno dos')
produce la salida 'Uno Dos'.
Aunque las funciones ASCII y CHR se usan raramente en consultas, son tiles para trabajar con caracteres no
habituales o no imprimibles. CHR convierte un valor numrico a su representacin de caracter ASCII. Por
ejemplo CHR(70) equivale al caracter 'F'. La funcin ASCII realiza la operacin inversa, convierte un caracter a
su valor numrico equivalente. Por ejemplo, ASCII('FSOUG') produce el resultado 70, ya que slo se tiene en
cuenta el primer caracter.
Cmo comparar cadenas por su parecido sonoro.
La funcin SOUNDEX tiene la inusual habilidad de encontrar palabras que suenan como otras palabras,
independientemente de cmo sean deletreadas. Podemos usar SOUNDEX sobre dos cadenas distintas y
comparar el resultado para saber si suenan igual o no. Por ejemplo, la expresin de comparacin SOUNDEX('a

Oracle /37
ver t')=SOUNDEX('abierto') evala a verdadero.
SOUNDEX hace determinadas asunciones sobre cmo las letras y combinaciones de letras se pronuncian
normalmente en ingls, y las dos cadenas a comparar deben comenzar con la misma letra.
Podemos usar SOUNDEX para encontrar erratas sobre una lista de valores y corregirlas, evitando de esta forma
incoherencias entre los datos. Por ejemplo, en una tabla VENTA que contenga nombres de cliente, podemos
buscar erratas en un mismo nombre de cliente con la siguiente consulta.
SELECT V1.IdVenta, V1.Nombre, V2.IdVenta, V2.Nombre
FROM VENTA V1, VENTA V2
WHERE V1.Nombre > V2.Nombre AND SOUNDEX(V1.Nombre)=SOUNDEX(V2.Nombre);
Si endos registros de VENTA aparecen los nombres 'Jos Prez' y 'Jose Perez' obtendremos en el resultado los
ID's de ambos registros, lo cual nos permitir despus corregir uno de los nombres. (La condicin V1.Nombre >
V2.Nombre impide que obtengamos dos registros con el mismo emparejamiento.)
Soporte para otros idiomas distintos del ingls.
Oracle no usa slo caracteres ingleses; puede representar datos en cualquier idioma porque implementa el
soporte para lenguajes nacionales (NLS). Al usar una representacin que usa ms espacio que el que ocupan
los caracteres ordinarios, Oracle puede representar caracteres japoneses y de otros idiomas. Las funciones
NLS_SORT, NLS_INITCAP, NLS_LOWER y NLS_UPPER son versiones para NLS de las funciones ordinarias.
Adems de la funcin SUBSTR, Oracle incluye SUBSTRB (para buscar bytes en vez de caracteres), SUBSTRC
(para buscar caracteres Unicode), SUBSTR2 (para buscar codepoints UCS2) y SUBSTR4 (para buscar
codepoints UCS4).
Soporte para expresiones regulares.
Desde Oracle Database 10g, las funciones de cadena INSTR, REPLACE y SUBSTR han sido extendidas para
soportar expresiones regulares con las funciones. En la siguiente seccin se describen estas nuevas funciones.
2.3.2. Funciones que trabajan con expresiones regulares.
Las nuevas funciones que soportan expresiones regulares son REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_LIKE
y REGEXP_REPLACE.
Bsqueda de cadenas.
Con la funcin REGEXP_SUBSTR podemos realizar bsquedas ms sofisticadas que las realizadas con la
funcin SUBSTR. Por ejemplo, si tenemos cdigos de producto con el formato '123-ABC-456' donde cada
secuencia de dgitos y letras separados por guiones tiene un significado determinado, puede ser necesario
acceder slo a la secuencia de letras de cada cdigo de producto. Si sabemos que la secuencia de letras est
siempre encapsulada entre guiones podemos usar una expresin regular para realizar la bsqueda de esta
secuencia. Con la expresin
REGEXP_SUBSTR('123-ABC-456', '-[^-]+-')
le decimos a Oracle que empiece buscando una subcadena que comience con un guin, a continuacin la
expresin [^-] le dice a Oracle que puede seguirle cualquier caracter que no sea un guin, y el signo + indica
que se puede repetir una o ms veces lo anterior (es decir, caracteres seguidos que no sean guiones), y por
ltimo debe incluir un guin. En este ejemplo, la funcin REGEXP_SUBSTR retorna '-ABC-'.
Si intentsemos este mismo ejemplo usando funciones ordinarias tendramos una expresin como la
siguiente:
SUBSTR( '123-ABC-456',
INSTR('123-ABC-456', '-',1,1),
INSTR('123-ABC-456', '-',1,2)-INSTR('123-ABC-456', '-',1,1))
Que evidentemente es menos concisa que la anterior.
La tabla siguiente describe la simbologa de las expresiones regulares:
Expresin Descripcin
. Representa a cualquier caracter (excepto el salto de lnea)
* Indica que lo anterior se puede repetir cero o ms veces
+ Indica que lo anterior se puede repetir una o ms veces
| Operador de alternancia. Se usa para indicar expresiones alternativas
() Los parntesis se usan para agrupar expresiones, de forma que sean tratadas como
una unidad
$ Representa el final del texto o de la lnea. No es un caracter sino una posicin
^ Representa el inicio del texto. No es un caracter sino una posicin
A? Indica una A opcional. El ? es vlido para hacer opcional cualquier expresin

Oracle /38
A{3} Tres A'es seguidas. Las llaves indican repeticin exacta de expresiones
A{3,} Al menos tres A'es seguidas
A{3,8} Al menos tres A'es y menos de ocho A'es
[aBcD] Alguno de los caracteres a, B, c o D
[C-G] Un caracter en el rango entre C y G inclusive
[^aBcD] Cualquier carcter distinto de a, B, c o D
[.ch.] Especifica el caracter ch espaol
\t El caracter tabulador
\r El caracter retorno de carro
\n El caracter de nueva lnea
\a El caracter beep
\e El caracter de escape
\f El caracter salto de pgina
\v El caracter tabulador vertical
\x00A2 El caracter de cdigo ASCII 0042
\d Un dgito del 0 al 9
\w Cualquier carcter alfanumrico
\s Un espacio en blanco
\D Cualquier caracter que no sea un dgito
\W Cualquier caracter no alfanumrico
\S Cualquier carcter que no sea un espacio en blanco
\A Representa el inicio de la cadena. No un caracter sino una posicin
\Z Representa el final de la cadena. No un carcter sino una posicin
\b Marca el inicio y el final de una palabra
\B Marca la posicin entre dos caracteres alfanumricos o dos no-alfanumricos
Adems de esta simbologa, Oracle soporta las siguientes clases de caracteres segn las definiciones de clases
de caracteres en NLS.
Clase Descripcin
[:alnum:] Todos los caracteres alfanumricos
[:alpha:] Todos los caracteres alfabticos
[:blank:] Todos los caracteres de espacio en blanco
[:cntrl:] Todos los caracteres de control (no imprimibles)
[:digit:] Todos los dgitos numricos
[:graph:] Todos los caracteres[:punct:], [:upper:], [:lower:], y [:digit:]
[:lower:] Todos los caracteres alfabticos en minsculas
[:print:] Todos los caracteres imprimibles
[:punct:] Todos los caracteres de puntuacin
[:space:] Todos los caracteres de espacio (no imprimibles)
[:upper:] Todos los caracteres alfabticos en maysculas
[:xdigit:] Todos los caracteres hexadecimales vlidos
La funcin REGEXP_SUBSTR.
La funcin REGEXP_SUBSTR, como se ha visto, usa expresiones regulares para especificar el punto inicial y
final de la subcadena retornada. La sintaxis completa de esta funcin es la siguiente:
REGEXP_SUBSTR(source_string, pattern [, position [, occurrence [, match_parameter ]]])
Esta funcin retorna una cadena de tipo VARCHAR2 o CLOB con el mismo juego de caracteres que el
parmetro source_string, que especifica la cadena en la que se busca. El parmetro pattern especifica la
expresin regular, que puede contener un mximo de 512 bytes. El parmetro position indica dnde empieza
la bsqueda dentro de source_string; el valor por defecto es 1. El parmetro ocurrence es un entero que indica
que posicin de la ocurrencia buscamos; su valor por defecto es 1. Se puede usar el parmetro
match_parameter para cambiar el comportamiento de bsqueda de la funcin; los posibles valores que
podemos incluir en este parmetro son:
i Se usa para indicar bsquedas no sensibles a maysculas y minsculas.
c Se usa para indicar bsquedas sensibles a maysculas y minsculas.
n Permite que el caracter punto (.) tambin case con el salto de lnea.

Oracle /39
m Trata la cadena de origen como una cadena de varias lneas. Oracle tratar ^ y $ como el inicio y
final, respectivamente, de cada lnea.
Si se especifican valores contradictorios en el parmetro match_parameter, Oracle usa el ltimo valor.
El siguiente ejemplo realiza una bsqueda insensible a maysculas y minsculas:
REGEXP_SUBSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940','mi',1,1, 'i')
Siendo el resultado 'MI'.
Si ahora cambiamos el modificador de bsqueda:
REGEXP_SUBSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940', 'mi', 1, 1, 'c')
El resultado ser el valor NULL.
Por defecto, las bsquedas son sensibles a maysculas y minsculas. En el siguiente ejemplo, se busca el
segundo dgito:
REGEXP_SUBSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940', '[[:digit:]]', 1, 2)
Siendo en este caso el resultado 9.
La funcin REGEXP_INSTR.
La funcin REGEXP_INSTR usa expresiones regulares para retornar el punto inicial o final de una bsqueda. La
sintaxis de esta funcin es como sigue:
REGEXP_INSTR (source_string, pattern[, position [, ocurrence[, return_option[, match_parameter ]]]])
Esta funcin retorna un entero que indica la posicin inicial o final de la subcadena especificada por el
patrn, o cero si no encuentra ninguna subcadena.
Esta funcin es similar a la funcin REGEXP_SUBSTR, y aade una nueva funcionalidad. El parmetro
return_option permite especificar el significado del valor devuelto por la funcin:
Si return_option es 0, la funcin retorna la posicin del primer caracter de la ocurrencia. ste es el valor
por defecto.
Si return_option es 1, la funcin retorna la posicin del caracter que sigue a la ocurrencia.
Por ejemplo, la siguiente expresin retorna la posicin del primer dgito dentro de una cadena:
REGEXP_INSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940','[[:digit:]]')
Siendo el resultado 56.
Si queremos la posicin siguiente a la de este dgito, la expresin ser:
REGEXP_INSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940', '[[:digit:]]', 1, 1, 1)
La funcin REGEXP_LIKE.
La funcin REGEXP_LIKE permite evaluar una cadena para ver si coincide con un patrn especificado con una
expresin regular. Esta funcin retorna verdadero o falso. Por ejemplo, la expresin establece si una cadena
comienza por '111':
REGEXP_LIKE('111-222-333', '111+')
En este caso la funcin se evala a verdadero.
El formato de esta funcin es:
REGEXP_LIKE(source_string, pattern, [match_parameter ])
Donde el significado de los parmetros es similar al de las funciones vistas previamente.
Las funciones REPLACE y REGEXP_REPLACE.
La funcin REPLACE reemplaza una subcadena dentro de una cadena por otra. Por ejemplo, podemos
reemplazar cada ocurrencia de una letra con un nmero. El formato para REPLACE es:
REPLACE (source_string, search_string [, replace_string])
Si no especificamos un valor para el parmetro replace_string, la subcadena search_string es quitada de la
cadena de origen. La cadena de origen puede ser de cualquiera de los tipos de caracteres ( CHAR, VARCHAR2,
NCHAR, NVARCHAR2, CLOB o NCLOB). Por ejemplo:
REPLACE('GEORGE', 'GE', 'EG')
Produce el resultado 'EGOREG', y:
REPLACE('GEORGE', 'GE', NULL)
Produce el resultado 'OR'.
La funcin REGEXP_REPLACE extiende las capacidades de la funcin REPLACE de varios modos. Soporta el uso
de expresiones regulares en el parmetro search_string, y adems incluye los parmetros de las funciones
descritas en este captulo: position, ocurrence y match_parameter. La sintaxis para la funcin REGEXP_REPLACE es
la siguiente:
REGEXP_REPLACE(source_string, pattern[, replace_string[, position[, ocurrence[, match_parameter ]]]])
En el siguiente ejemplo se pone entre parntesis cada terna de un nmero telefnico:
REGEXP_REPLACE ('111222333', '([[:digit:]]{3})([[:digit:]]{3})([[:digit:]]{3})', '(\1) (\2) (\3)')

Oracle /40
El resultado de este ejemplo es '(111) (222) (333)'.
2.3.3. Funciones numricas.
ABS(n) Devuelve el valor absoluto del argumento.
ACOS(n) Devuelve, en radianes, el arcocoseno del argumento.
ASIN(n) Devuelve, en radianes, el arcoseno del argumento
ATAN(n) Devuelve, en radianes, el arcotangente del argumento
ATAN2(n, m) Devuelve, en radianes, la arcotangente de dos argumentos.
BITAND (n, m) Realiza una operacin AND a nivel de bits entre los argumentos y devuelve un
entero con el resultado.
CEIL(n) Devuelve el valor entero ms pequeo mayor o igual que el argumento.
COALESCE(n, m, ) Retorna el primer valor no NULL de la lista de argumentos.
COS(n) Devuelve el coseno del argumento (el cual tiene que estar en radianes).
COSH(n) Devuelve el coseno hiperblico del argumento.
EXP(n) Devuelve el valor de e elevado al argumento n.
FLOOR(n) Devuelve el valor entero ms grande menor o igual que el argumento
GREATEST(n, m, ) Retorna el valor ms grande de la lista de argumentos, o NULL si uno de ellos es
nulo.
LEAST(n, m, ) Retorna el valor ms pequeo de la lista de argumentos, o NULL si uno de ellos es
nulo.
LN(n) Devuelve el logaritmo neperiano del argumento.
LOG(n) Devuelve el logaritmo en base 10 del argumento n.
MOD(n1,n2) Devuelve el resto de la divisin entera de los argumentos.
NANVL(n,m) Para nmeros BINARY_FLOAT y BINARY_DOUBLE, esta funcin retorna el
segundo argumento si el primero no es un nmero, sino retorna el primer
argumento
NVL(n, m) Retorna el segundo argumento si el primero es NULL, sino retorna el primer
argumento.
NVL2(n,m,p) Retorna el tercer argumento si el primero es NULL, sino retorna el segundo
argumento.
POWER(valor, exponente) Retorna el resultado de elevar un valor al exponente indicado.
REMAINDER(n, m) Retorna el resto de dividir dos nmeros.
ROUND(n, decimales) Redondea el nmero al siguiente nmero con el nmero de decimales indicado
ms cercano.
SIGN(n) Devuelve 1 si el argumento es positivo, cero si vale cero y -1 si es negativo
SIN(n) Devuelve el seno del argumento (el cual tiene que estar en radianes).
SINH(n) Devuelve el seno hiperblico del argumento.
SQRT(n) Devuelve la raz cuadrada del argumento.
TAN(n) Devuelve la tangente del argumento (el cual tiene que estar en radianes).
TANH(n) Devuelve la tangente hiperblica del argumento.
TRUNC(n, decimales) Los decimales del nmero se cortan para devolver slo el nmero de decimales
indicado.
VSIZE(n) Almacena el tamao del argumento en Oracle.
Las funciones de Oracle tratan con tres clases de nmeros: valores simples, grupos de valores y las listas de
valores. Como con las funciones de cadenas, algunas funciones numricas cambian los valores que les son
aplicados, mientras que otras reportan informacin acerca de los valores.
Un valor simple es un nmero procedente de:
Una expresin literal, como 544.3702.
Una variable de SQL*Plus o PL/SQL.
Una columna de una fila de base de datos.
Las funciones de valores simples normalmente cambian estos valores tras algn clculo.
Un grupo de valores son todos los nmeros de una columna de una serie de filas. Las funciones sobre grupos
de valores realizan alguna operacin sobre todos los nmeros del grupo, como el promedio de los precios de
venta, pero no sobre los valores individuales. (Las funciones numricas sobre grupos de valores se
denominan funciones de agregado y se estudiarn en el captulo correspondiente.)
Una lista de valores es una serie de nmero que pueden proceder de:

Oracle /41
Una lista de expresiones literales separadas por comas, como 1, 7.3, 22.
Variables de SQL*Plus o PL/SQL.
Columnas de una base de datos.
Las funciones de listas de valores seleccionan uno de los valores de la lista segn algn criterio.
Funciones de valor simple.
La mayor parte de funciones de valor simple son bastante intuitivas.
La funcin ABS retorna el valor independientemente del signo. Por ejemplo ABS(-23) devuelve el valor 23.
La funcin CEIL busca el valor entero ms pequeo que sea ms grande o igual que uno dado. Hay que
prestar atencin especial a su efecto sobre nmeros negativos. La siguiente tabla muestra algunos ejemplos:
CEIL(2) = 2
CEIL(1.3) = 2
CEIL(-2) = -2
CEIL(-2.3) = -2
La funcin FLOOR es la opuesta a CEIL. La siguiente tabla muestra algunos ejemplos:
FLOOR(2) = 2
FLOOR(1.3) = 1
FLOOR(-2) = -2
FLOOR(-2.3) = -3
La funcin MOD permite dividir un nmero entre otro y retorna el resto de la divisin entera. Por ejemplo
MOD(23,6) divide 23 entre 6 y devuelve el resto 5. El valor de MOD es cero si el divisor es cero o negativo. La
siguiente tabla muestra algunos ejemplos:
MOD(100,10) = 0
MOD(22,23) = 22
MOD(10,3) = 1
MOD(-30.23,7) = -2.23
MOD(4.1,.3) = .2
MOD(44, 1) = 0
Esta funcin puede ser interesante para saber si un nmero es par o impar. Simplemente hay que tener en
cuenta que si dividimos por 2, los nmeros pares tienen resto 0 y los impares resto 1. Tambin es til para
normalizar cualquier nmero dentro de un rango. Por ejemplo, cualquier nmero dividido entre 10 dar como
resto un valor entre 0 (inclusive) y 10 (exclusive).
La funcin TRUNC trunca, o recorta, los dgitos de precisin de un nmero; mientras que la funcin ROUND
redondea un nmero segn el nmero de dgitos de precisin especificado. El formato de ambas funciones es
el siguiente:
ROUND(valor, precisin)
TRUNC(valor, precisin)
Si no se especifica la precisin se toma por defecto precisin cero. La siguiente tabla muestra ejemplos de
ambas funciones:
ROUND(11, 2) = 11 TRUNC(11, 2) = 11
ROUND(-22, 2) = -22 TRUNC(-22, 2) = -22
ROUND(33.33, 2) = 33.33 TRUNC(33.33, 2) = 33.33
ROUND(55.5, 2) = 55.5 TRUNC(55.5, 2) = 55.5
ROUND(66.666, 2) = 66.67 TRUNC(66.666, 2) = 66.66
En todos estos ejemplos se redondea y trunca en base a dos decimales. Hay que tener en cuenta que el valor
decimal de .5 es redondeado siempre hacia arriba, de forma que ROUND(55.5) da como resultado 56.
Tambin podemos trabajar con precisiones negativas, de forma que se mueve el punto decimal hacia la
izquierda. Por ejemplo:
ROUND(11, -1) = 10 TRUNC(11, -1) = 10
ROUND(-22, -1) = -20 TRUNC(-22, -1) = -20
ROUND(33.33, -1) = 30 TRUNC(33.33, -1) = 30
ROUND(55.5, -1) = 60 TRUNC(55.5, -1) = 50
ROUND(66.666, -1) = 70 TRUNC(66.666, -1) = 60
En estos ejemplos al usar precisin -1 se redondea alnivel de decenas, si se usase precisin -2 se redondeara
al nivel de centenas, y as sucesivamente. El redondeo con un nmero negativo puede ser til para generar
informes econmicos, donde las sumas de poblaciones o moneda tienen que ser redondeadas hasta los
millones, billones o trillones.

Oracle /42
La funcin SIGN es la otra cara del valor absoluto. Mientras que ABS nos da la magnitud de un valor, pero no
su signo, SIGN nos da el signo de un valor, pero no su magnitud. Por ejemplo, SIGN(146) nos da 1, mientras
que SIGN(-30) nos da -1. Adems, SIGN(0) da 0.
La funcin SIGN es normalmente usada en conjuncin con la funcin DECODE.
Las funciones trigonomtricas seno, coseno y tangente son funciones cientficas y tcnicas que no se usan
mucho en los negocios. SIN, COS y TAN obtienen los valores correspondientes para un ngulo expresado en
radianes (grados multiplicados por pi dividido por 180).
Funciones de lista.
Las funciones de lista trabajan sobre un grupo de valores, realizando una seleccin simple sobre ellos. As, las
funciones GREATEST y LEAST pueden ser usadas sobre varios valores (numricos o de caracteres) de la
siguiente forma:
GREATEST('Bob', 'Jorge', 'Andrs, 'Isaas') = Isaas
LEAST('Bob', 'Jorge', 'Andrs, 'Isaas') = Andrs
GREATEST obtiene el mayor valor de la lista de valores, mientras que LEAST obtiene el menor valor de la lista
de valores. Para el ejemplo previo se utiliza la ordenacin alfabtica de caracteres para establecer qu nombre
es mayor y menor.
Podemos usar la funcin COALESCE para evaluar varios valores que pueden incluir nulos. COALESCE retorna el
primer valor de una lista que no sea nulo, y si todos son nulos retorna el valor NULL. Por ejemplo:
COALESCE( NULL, 4, NULL, 7) = 4
2.3.4. Funciones que trabajan con nulos.
NVL(valor, sustituto) Si el valor es NULL, devuelve el valor sustituto; de otro modo, devuelve valor.
NVL2(valor,sustituto1,sustituto2) Variante de la anterior, devuelve el valor sustituto1 si valor no es nulo. Si valor
es nulo devuelve el sustituto2.
NANVL(valor, sustituto) Anloga a NVL para los tipos BINARY_FLOAT y BINARY_DOUBLE.
Los valores nulos no pueden ser usados para realizar clculos. Cuando se realiza una operacin entre dos
valores, uno de los cuales es NULL, el resultado siempre ser NULL. Debemos tener en cuenta que el valor
NULL no es igual que el valor cero; ms bien el valor NULL quiere decir un valor no conocido o irrelevante.
Sin embargo, habr consultas donde debamos realizar clculos sobre campos que admiten el valor nulo. En
estos casos es importante saber si un valor determinado es nulo y, en ese caso, poder sustituirlo por un valor
determinado. Por ejemplo, si tenemos una tabla de ventas, que tiene una columna "cantidad" que admite
valores nulos, podemos querer interpretar los valores nulos como el valor cero. Esto se puede hacer con la
funcin NVL aplicndola de la siguiente manera:
SELECT idVenta, NVL(cantidad, 0) FROM Ventas;
Esta consulta permite mostrar los id's de venta y las cantidades en cada venta. Si el valor de cantidad est a
nulo se mostrar el valor cero. El formato de esta funcin es el siguiente:
NVL(valor, sustituto)
Si el argumento valor es NULL, esta funcin retorna el argumento sustituto, sino retorna el propio valor. NVL
funciona con cualquier tipo de datos, pero tanto valor como sustituto deben ser del mismo tipo. NVL es
realmente til en casos donde el dato es desconocido pero no irrelevante.
En los casos donde debamos evaluar si el dato es nulo pero su valor concreto es irrelevante podemos usar la
funcin NVL2. Su formato es el siguiente:
NVL2 ( expr1 , expr2 , expr3 )
En NVL2, expr1 nunca ser retornada; sino que, o bien expr2oexpr3sern retornados. Si expr1no es NULL, NVL2
retorna expr2. Siexpr1es NULL, NVL2 retorna expr3. El primer argumento puede ser de cualquier tipo. Los
otros dos argumentos deben ser del mismo tipo excepto LONG.
Desde Oracle Database 10g, podemos usar la funcin anloga NANVL para los tipos de datos BINARY_FLOAT
y BINARY_DOUBLE. NANVL toma dos argumentos, y retorna el segundo si el primero no es un nmero.
2.3.5. Funciones de fecha y hora.
ADD_MONTHS(fecha,n) Aade a la fecha el nmero de meses indicado por n.
CURRENT_DATE Retorna la fecha y hora actual en la zona horaria de la sesin.
CURRENT_TIMESTAMP Retorna la fecha y hora actual con la informacin de zona horaria activa.
DBTIMEZONE Retorna la zona horaria actual en formato UTC.
EXTRACT(valor FROM fecha) Extrae un valor de una fecha concreta. El valor puede ser day (da), month
(mes), year (ao), etc.

Oracle /43
FROM_TZ(timestamp) Convierte un valor timestamp a otro timestamp con un valor de zona
horaria.
GREATEST(fecha1, ...) Devuelve la fecha ms moderna de la lista.
LAST_DAY(fecha) Obtiene el ltimo da del mes al que pertenece la fecha. Devuelve un valor
DATE.
LEAST(fecha1, fecha2,...) Devuelve la fecha ms antigua de la lista.
LOCALTIMESTAMP Retorna el timestamp local en la zona horaria activa, pero sin mostrar la
informacin de zona horaria.
MONTHS_BETWEEN(fecha1,fecha2) Obtiene la diferencia en meses entre las dos fechas (puede ser decimal).
NEW_TIME(fecha,esta,otra) Obtiene la fecha (y hora) en esta zona horaria. El valor del argumento esta
puede ser reemplazado por una abreviatura de tres letras para la zona
horaria actual. El valor del argumento otra puede ser reemplazado por una
abreviatura de otra zona horaria para la cual queremos saber la fecha y hora.
Los valores de zonas horarias son:
AST/ADT Atlantic standard/daylight time
BST/BDT Bering standard/daylight time
CST/CDT Central standard/daylight time
EST/EDT Eastern standard/daylight time
GMT Greenwich mean time
HST/HDT Alaska-Hawaii standard/daylight time
MST/MDT Mountain standard/daylight time
NST Newfoundland standard time
PST/PDT Pacific standard/daylight time
YST/YDT Yukon standard/daylight time
NEXT_DAY(fecha,da) Indica cual es el da que corresponde a aadir a la fecha el da indicado. El
da puede ser el texto 'Lunes', 'Martes', 'Mircoles',... (si la configuracin
est en espaol) o el nmero de da de la semana (1=lunes, 2=martes,...)
NUMTODSINTERVAL(valor,formato) Convierte el argumento valor a un literal de intervalo de tiempo segn las
unidades especificadas en el segundo argumento. El argumento formato
puede ser 'DAY', 'HOUR', 'MINUTE' o 'SECOND'.
NUMTOYMINTERVAL(valor,formato) Convierte el argumento valor a un literal de intervalo de tiempo segn las
unidades especificadas en el segundo argumento. El argumento formato
puede ser 'YEAR' o 'MONTH'.
ROUND(fecha [,'formato']) Redondea la fecha al valor de aplicar el formato a la fecha. El formato
puede ser 'YEAR', 'MONTH', 'HH24' o 'DAY'.
SESSIONTIMEZONE Retorna el valor de la zona horaria de la sesin actual.
SYS_EXTRACT_UTC Extrae de la fecha actual al valor UTC (Coordinated Universal Time).
SYSDATE Obtiene la fecha y hora actuales.
SYSTIMESTAMP Obtiene la fecha y hora actuales en formato TIMESTAMP.
TO_CHAR(fecha,formato) Da formato a una fecha segn el patrn especificado en el segundo
argumento.
TO_DATE(texto,formato) Interprete un texto como una fecha segn el patrn especificado en el
segundo argumento.
TO_DSINTERVAL(texto) Convierte un texto de tipo CHAR, VARCHAR2, NCHAR o NVARCHAR2 a un
tipo de intervalo entre das y segundos.
TO_TIMESTAMP(texto) Convierte un texto de tipo CHAR, VARCHAR2, NCHAR o NVARCHAR2 a un
valor de tipo TIMESTAMP.
TO_TIMESTAMP_TZ(texto) Convierte un texto de tipo CHAR, VARCHAR2, NCHAR o NVARCHAR2 a un
tipo TIMESTAMP con zona horaria.
TO_YMINTERVAL(texto) Convierte un texto de tipo CHAR, VARCHAR2, NCHAR o NVARCHAR2 a un
tipo de intervalo entre aos y meses.
TRUNC(fecha, [formato]) Trunca la fecha al valor de aplicar el formato a la fecha. El formato puede
ser 'YEAR', 'MONTH', 'HH24' o 'DAY'.
TZ_OFFSET(texto) Retorna la diferencia de zona horaria correspondiente al valor del
argumento.
Una de las bazas de Oracle es su capacidad de almacenar y calcular fechas, y el nmero de segundos, minutos,
horas, das, meses y aos entre fechas. Adems de las funciones de fecha bsicas, Oracle soporta muchas

Oracle /44
funciones de conversin y la habilidad de dar formato a fechas en cualquier manera concebible.
Aritmtica de fechas.
El tipo de dato para fechas en Oracle es DATE. Un tipo DATE es almacenado en un formato interno especial
que incluye el da, mes, ao, horas, minutos y segundos de la fecha. Tambin se puede usar el tipo
TIMESTAMP para almacenar fechas hasta fracciones de segundo.
SQL*Plus y SQL reconocen columnas que tienen el tipo DATE e interpretan las instrucciones donde se
utilizan operaciones aritmticas con fechas como aritmtica de fechas y no como aritmtica matemtica. Por
ejemplo, sumando el valor 1 a una fecha se obtiene otra fecha con el da siguiente; y si restamos dos fechas,
obtenemos la diferencia de das entre ellas.
Sin embargo, dado que las fechas de Oracle incluyen horas, minutos y segundos, la aritmtica de fechas puede
ser difcil de interpretar; por ejemplo, podramos decir que la diferencia entre hoy y maana es de 0,516 das!
Las funciones SYSDATE, CURRENT_DATE y SYSTIMESTAMP.
Oracle consulta el sistema operativo del ordenador para obtener la fecha y hora actuales. Para ello
proporciona una funcin especial llamada SYSDATE. Podemos ver SYSDATE como una funcin que siempre
retorna la fecha y hora actual. Por ejemplo, la siguiente consulta:
SELECT SYSDATE FROM DUAL;
Retorna una fila con una columna con el valor de la fecha (da, mes y ao) actual del ordenador.
Una segunda funcin, CURRENT_DATE, recupera la fecha del sistema en la zona horaria de la sesin (podemos
asignar la zona horaria dentro de nuestra sesin local, la cual puede diferir de la zona horaria de la base de
datos).
Otra funcin, SYSTIMESTAMP, recupera la fecha del sistema en un formato ms completo que incluye la hora
e informacin de zona horaria.
Cmo aadir y sustraer meses a una fecha.
Se puede utilizar la funcin ADD_MONTHS para aadir un nmero de meses a una fecha dada. Por ejemplo
ADD_MONTHS('1/2/2011', 6) da como resultado la fecha '1/8/2011'.
Esta funcin siempre se mantendr dentro del margen de fechas vlidas. Por ejemplo,
ADD_MONTHS('31/1/2011', 1) da como resultado la fecha '28/2/2011'.
Aadiendo valores negativos a esta funcin conseguiremos restar meses a una fecha. Por ejemplo
ADD_MONTHS('31/1/2011', -4) da como resultado '30/09/10'.
Las funciones GREATEST y LEAST.
Las funciones GREATEST y LEAST trabajan sobre expresiones de tipo fecha igual que sobre otros tipos de
datos, excepto si se aplican sobre una lista de valores literales. Por ejemplo GREATEST('2/1/2011','2/2/2000')
da como resultado el valor '2/2/2000', que es claramente una fecha anterior a '2/1/2011'. Esto es as porque
estas funciones interpretan los literales de fechas como strings.
Para que estas funciones trabajen apropiadamente sobre valores literales de fecha debemos aplicar la funcin
TO_DATE sobre los literales. Por ejemplo GREATEST(TO_DATE('2/1/2011'),TO_DATE('2/2/2000')) da ahora
como resultado el valor '2/1/2011'.
La funcin NEXT_DAY.
NEXT_DAY computa la fecha correspondiente al da de la semana indicado (esto es, lunes, martes, mircoles,
jueves, viernes, sbado o domingo) despus de una fecha dada. Por ejemplo, en una tabla de citas, la cita
puede ser siempre el primer viernes despus de una fecha inicial dada. En este caso podemos almacenar en la
tabla la fecha en que se concierta la fecha y consultar la tabla para obtener la fecha concreta de la cita, de la
siguiente manera:
SELECT NEXT_DAY(FechaInicial, 'Viernes') FROM Citas;
Si el valor de FechaInicial es'1/11/2011' el resultado ser '04/11/2011', que se corresponde con el viernes
siguiente. Sin embargo si aplicamos NEXT_DAY('4/11/2011','Viernes') obtendremos como resultado el
'11/11/2011', es decir, el siguiente viernes y no el actual. Si queremos evitar esto y mostrar el propio da si
coincide con el viernes, nos basta con restar un da a la fecha, obteniendo as la consulta:
SELECT NEXT_DAY(FechaInicial - 1,'Viernes') FROM Citas;
La funcin LAST_DAY.
LAST_DAY computa la fecha del ltimo da del mes. Podemos aplicar esta funcin sobre una fecha dada para
obtener la fecha del ltimo da del mismo mes. Por ejemplo, LAST_DAY('4/2/2011') retorna el valor '28/02/11'.
Meses entre dos fechas.
La funcin MONTHS_BETWEEN permite computar el nmero de meses de diferencia entre dos fechas.
Podemos utilizar esta funcin, por ejemplo, para calcular la edad actual (en aos) de una persona. La siguiente

Oracle /45
consulta hacer esto sobre una persona nacida el '23/4/1987':
SELECT FLOOR( MONTHS_BETWEEN(SYSDATE, '23/4/1987') / 12 ) FROM DUAL;
En este caso de aplica la funcin FLOOR para eliminar valores decimales del resultado.
Redondear y truncar clculos sobre fechas.
Si asumimos que SYSDATE retorna el valor '23/3/2011' podemos realizar una resta de fechas como:
SELECT TO_DATE('28/3/2011') - SYSDATE FROM DUAL;
Siendo el resultado 4,4135 en vez de 5 das. La razn de este nmero con decimales es porque SYSDATE
incluye horas, minutos y segundos, y Oracle los utiliza para realizar la sustraccin.
Para simplificar alguna de las dificultades que podemos encontrarnos usando fracciones de das, Oracle hace
algunas asunciones acerca de las fechas:
Un literal de fecha, como '28/03/2011', asume por defecto la hora 12:00:00 A.M.
Una fecha introducida a travs de SQL*Plus, a menos que se especifique, asume por defecto la hora
12:00:00 A.M.
SYSDATE siempre incluye la fecha y la hora, a menos que lo redondeemos explcitamente. Usar la funcin
ROUND sobre una fecha la redondea a las 12 A.M. del mismo da si es antes del medioda, y a las 12 A.M. del
da siguiente si es despus del medioda. La funcin TRUNC acta de forma similar, excepto que asigna la
hora a las 12 A.M. del mismo da e incluyendo un segundo despus de medianoche.
Para obtener el nmero redondeado de das debemos usar la siguiente consulta:
SELECT TO_DATE('28/3/2011') ROUND(SYSDATE) FROM DUAL;
Si la fecha actual es despus del medioda la diferencia ser de 4 das.
Formatos para TO_DATE y TO_CHAR.
TO_DATE y TO_CHAR son parecidos en la medida en que ambos tienen poderosas capacidades de formato.
TO_DATE convierte una cadena o un nmero en una fecha, mientras que TO_CHAR convierte una fecha en una
cadena de caracteres. Los formatos de ambas funciones son los siguientes:
TO_CHAR( fecha [, formato [, parametrosNLS]])
TO_DATE( cadena [, formato [, parametrosNLS]])
Elargumento fecha debe ser un valor literal (con un formatode fecha vlido) o una columna de tipo DATE.
Elargumento cadena debe ser un literal de texto, un literalnumrico o una columna de base de datos que
contenga un string o un nmero. En cada caso, el formato de la cadena debe corresponderse con el descrito
en el argumento formato. Si se omite el argumento de formato slo se admiten los formatos por defecto:
'da/mes/ao' o 'da-mes-ao'.
El argumento formato es una coleccin de opciones que podemos combinar para indicar un patrn de fecha.
El argumento parametrosNLS es un string que asigna la opcin NLS_DATE_LANGUAGE a un idioma especfico,
en vez de usar el idioma de la sesin actual. Normalmente no es necesario usar este argumento opcional.
Oracle retorna nombres de das y meses en el idioma asignado por la sesin.
Como ejemplo, la expresin TO_CHAR(SYSDATE, 'DD/MM/YYYY') retorna la fecha actual en un formato como
'25/06/2012'. Mientras que la expresin TO_CHAR(SYSDATE, 'DD-MON-YYYY') retorna la fecha actual en un
formato como '25-JUN-2012'.
En el argumento de formato podemos usar las siguientes opciones para especificar un patrn de fecha:
Formato Significado
/, -:.; Signos de puntuacin que sern incorporados en TO_CHAR e ignorados en TO_DATE.
A.D. AD Indicador de AD.
A.M. AM Muestra A.M. o P.M., dependiendo del momento del da.
B.C. BC Indicador de BC.
CC Siglo (por ejemplo, 21 para 2004).
SCC Siglo, para fechas BC prefijadas con guin.
D Nmero del da de la semana: de 1 a 7.
DAY El da con nombre completo.
DD Nmero del da en el mes: de 1 a 31.
DDD Nmero del da en el ao (desde el 1 de enero): 1 a 366.
DL La fecha en un formato largo, como por ejemplo 'Martes 14 de Junio de 2011'.
DS La fecha en un formato corto, como por ejemplo '14/06/2011'.
DY Las tres letras de abreviatura del da. Por ejemplo, VIE para el viernes.
E Abreviatura del nombre de era (para calendarios Japanese Imperial, ROC Official y Thai
Buddha).

Oracle /46
EE Versin a nombre completo del formato E.
FF [1..9] Fracciones de segundo. El nmero que sigue a FF especifica el nmero de dgitos en la parte
de fracciones de segundo.
FM Suprime espacios en blanco de rastreo y administracin. Sin FM, todos los meses y das son
mostrados con el mismo ancho.
FX Especifica que case el formato exacto para el argumento de texto y de formato.
HH HH12 Hora del da: 1 a 12.
HH24 Hora del da: 0 a 23.
I Un dgito de ao del estndar ISO.
IW Semanas en el ao del estndar ISO: 1 a 53.
IY Dos dgitos de ao del estndar ISO.
IYY Tres dgitos de ao del estndar ISO.
IYYY Cuatro dgitos de ao del estndar ISO.
J Valor Juliano (das desde el 31 de Diciembre de 4712 B.C.).
MI Minutos de la hora: 0 a 59.
MM Nmero del mes: 1 a 12.
MON Abreviatura de tres letras del mes (por ejemplo, AGO para agosto).
MONTH El nombre completo del mes.
P.M. Anlogo a A.M.
Q Cuatrimestre del ao: 1 a 4.
RM Nmero romano del mes.
RR ltimos dos dgitos del ao relativo a la fecha actual.
RRRR Ao redondeado, aceptando dos o cuatro dgitos.
SS Segundos del minuto: 0 a 59.
SSSSS Segundos desde medianoche: 0 a 86399.
TS Formato de hora corta, para usar con DL o DS.
TZD Informacin de tiempo de ahorros de luz del da.
TZH Hora de la zona horaria.
TZM Minuto de la zona horaria.
TZR Regin de la zona horaria.
W Nmero de semanas en un mes (desde 1 para la primera semana del mes).
WW Nmero de semanas en un ao (desde 1 para la primera semana del ao).
X Carcter de raz local.
YEAR El ao hablado en ingls. Por ejemplo, una fecha con el ao 2011 se corresponde con 'twenty
SYEAR eleven'.
YYYY El ao con cuatro dgitos.
SYYYY
Y,YYY Ao con separador de miles.
Y ltimo dgito del ao.
YY Dos ltimos dgitos del ao.
YYY Tres ltimos dgitos del ao.
Los formatos que slo trabajan con TO_CHAR, pero no con TO_DATE, son los siguientes:
Formato Significado
TH Sufijo para un nmero. Por ejemplo, ddTH o DDTH produce 24th o 24TH, respectivamente.
SP Sufijo para un nmero que fuerza la versin hablada del nmero en ingls. Por ejemplo, MMSP
aplicado sobre junio muestra 'six' (seis en ingls).
SPTH Combinacin de los sufijos SP y TH.
THSP Combinacin de los sufijos TH y SP.
Adems, podemos insertar texto literal en el formato encapsulndolo entre comillas dobles. Por ejemplo,
TO_CHAR(SYSDATE,'("YYYY") YYYY') puede producir '(YYYY) 2011'.
La funcin NEW_TIME para cambiar zonas horarias.
La funcin NEW_TIME nos da la fecha y hora para otra zona horaria a la actual. El formato de esta funcin es
el siguiente:
NEW_TIME(fecha, zonaHorariaActaul, otraZonaHoraria)
El primer argumento es una fecha (y hora) de la zona horaria especificada en el segundo argumento. La fecha

Oracle /47
ser retornada para la zona horaria especificada en el tercer argumento. Los argumentos de zonas horarias
usan una abreviatura de tres letras.
Esta funcin puede ser til para comparar fechas de distintas zonas horarias. Por ejemplo, para comparar un
campo fecha de una tabla Amigo de la zona de Europa del Este con la zona de Hawi, podemos usar la
siguiente consulta:
SELECT fecha, NEW_TIME(fecha, 'EST', 'HST') FROM Amigo;
Clculos con TO_DATE.
TO_DATE sigue las mismas convenciones de formato que TO_CHAR, con algunas restricciones. El propsito de
TO_DATE es convertir un string, como 'MAY 20, 1949', en un valor de tipo DATE. Esto permite que las fechas
sean usadas para clculos. Si queremos convertir un valor como '22-MAR-04' tenemos que usar la expresin
TO_DATE('22-MAR-04','DD-MON-YY'). Si omitimos el argumento de formato, el primer argumento tiene que
expresar una fecha en uno de los formatos estndar para fechas (separando la fecha con guiones o barras).
Supongamos que obtenemos el da de mes en un campo de base de datos expresado como un nmero y
queremos mostrarlo en su forma de nombre completo. La funcin TO_CHAR permite hacer esto sobre una
fecha completa, pero no sobre un nmero. Por tanto, podemos convertir previamente el nmero de mes a
fecha con la funcin TO_CHAR. La consulta sera como sigue:
SELECT TO_CHAR( TO_DATE( numeroMes , 'MM') , 'MONTH' ) FROM Tabla;
En este ejemplo, la funcin TO_DATE convierte previamente un nmero en una fecha que incluye el da 1, el
mes que casa con el nmero y al ao actual.
Tambin podemos compactar una fecha en un nico nmero del estilo 23022011. Podemos convertir este
nmero en una fecha mediante la expresin TO_DATE(23022011,'DDMMYYYY'), que devuelva la fecha con valor
'23/2/2011'.
Como regla general, la funcin TO_DATE fallar si no seguimos las siguientes normas:
No se permiten literales en el string a convertir. Por ejemplo 'La fecha es 12/1/2000' no es vlido.
Los das no pueden ser expresados en su forma hablada. Siempre deben ser nmeros.
Se permiten los signos de puntuacin.
El formato fm no es necesario. Si se usa, se ignora.
Si se usa Month, el mes en el string debe estar en su forma hablada. Si se usa Mon, el mes debe expresarse
con una abreviatura de tres letras. Las maysculas y minsculas sern ignoradas.
Cmo tratar con varios siglos.
Si nuestra aplicacin usa slo dos dgitos para los aos, podemos encontrarnos con problemas relacionados
con el ao 2000. Si especificamos '98' para el ao '1998', e insertamos la fecha en una base de datos despus
del ao 2000, podemos tener problemas con el valor de siglo asignado a la fecha, puesto que se le asignar el
siglo 21.
Es por ello importante especificar siempre los aos con cuatro dgitos cuando insertemos datos.
Usando la funcin EXTRACT.
Podemos usar la funcin EXTRACT en lugar de TO_CHAR para seleccionar parte de una fecha. La sintaxis de
esta funcin es la siguiente:
EXTRACT( parte FROM fecha )
Donde parte puede ser uno de los siguiente valores: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND,
TIMEZONE_HOUR, TIMEZONE_MINUTE, TIMEZONE_REGION o TIMEZONE_ABBR.
Por ejemplo, si queremos obtener el ao actual podemos usar la expresin EXTRACT(YEAR FROM SYSDATE).
Usando el tipo de dato TIMESTAMP.
El tipo de dato DATE almacena la fecha y hora hasta segundos, el tipo TIMESTAMP almacena la fecha hasta
billones de segundo.
Por defecto, la precisin para fracciones de segundo en un TIMESTAMP es de 6, pero puede llegarse hasta 9
decimales. Al definir una columna de tipo TIMESTAMP podemos establecer esta precisin de la siguiente
forma:
CREATE TABLE X1 (TSCOLTIMESTAMP(5));
Si queremos que los valores insertados especifiquen la zona horaria podemos crear la columna con la opcin
WITH TIME ZONE de la siguiente forma:
CREATE TABLE X1 (TSCOLTIMESTAMP(5) WITH TIME ZONE);
Oracle tambin soporta el tipo de dato TIMESTAMP(precisin) WITH LOCAL TIMEZONE, que permite
normalizar los valores a la zona horaria donde es almacenada la base de datos.
Tambin podemos usar la funcin SYSTIMESTAMP para obtener la fecha y horas actuales como un tipo

Oracle /48
TIMESTAMP.
Adems del tipo TIMESTAMP, Oracle soporta dos tipos de datos para intervalos:
INTERVALYEAR(precisin_del_ao) TO MONTH
INTERVAL DAY (precisin_del_da) TO SECOND (precisin_fraccin_segundos)
El tipo INTERVAL YEAR TO MONTH almacena un periodo de tiempo en aos y meses, donde la precisin es el
nmero de dgitos del ao (siendo por defecto 2). El tipo INTERVAL DAY TO SECOND almacena un periodo de
tiempo de das, horas, minutos y segundos; la precisin para el da y segundos acepta valores entre 0 a 9.
Los tipos INTERVAL son normalmente usados en anlisis estadsticos de datos.
2.3.6. Funciones que retornan valores del sistema.
USER Pseudo-columna de SQL*Plus que devuelve un valor VARCHAR2 que contiene el
nombre de usuario actual de Oracle.
UID Esta funcin retorna el ID de la se sesin. El ID de usuario es un identificador
nico para cada usuario en una base de datos y puede seleccionarse de la vista
DBA_USERS.
USERENV('atributo') Devuelve un valor VARCHAR2 que contiene informacin acerca de la sesin
actual, segn la opcin seleccionada. Las opciones son:
CLIENT_INFO, para obtener al usuario actual de la sesin.
ENTRYID, para obtener el identificador de entrada.
INSTANCE, para obtener el nmero de identificador de la instancia actual.
ISDBA, para determinar si el usuario actual tiene privilegios DBA.
LANG, para obtener una abreviatura del lenguaje.
LANGUAGE, para obtener el lenguaje, territorio y caracteres de la sesin.
SESSIONID, para obtener el identificador de sesin.
TERMINAL, para obtener el identificador del sistema operativo.
Esta funcin se considera obsoleta y se recomienda SYS_CONTEXT.
SYS_CONTEXT('namespace', Esta funcin permite recuperar informacin (como un VARCHAR2) asociada a un
'atributo' [, len]) atributo de un espacio de nombres de la sesin actual. Por ejemplo, el espacio de
nombres relacionado con el usuario actual es USERENV, el cul describe nuestra
sesin.
Existen una gran diversidad de parmetros para el espacio de nombres USERENV,
entre ellos:
CURRENT_SCHEMA, CURRENT_SCHEMAID,
HOST, INSTANCE, INSTANCE_NAME,
IP_ADDRESS, ISDBA,
LANG, LANGUAGE,
NETWORK_PROTOCOL, NLS_CALENDAR,
NLS_CURRENCY, NLS_DATE_FORMAT,
NLS_SORT, NLS_DATE_LANGUAGE,
NLS_TERRITORY, OS_USER,
SERVER_HOST, SERVICE_NAME,
SESSION_USER, SESSION_USERID,
SESSIONID, SID,
TERMINAL.

Oracle permite crear espacios de nombres en el contexto actual que permiten almacenar informacin asociada
a un nombre de atributo. Se usa el comando CREATE CONTEXT para:
Crear un espacio de nombres para un contexto.
Asociar el espacio de nombres con un paquete creado externamente, el cual asigna el contexto.
Podemos usar el procedimiento DBMS_SESSION.SET_CONTEXT dentro del paquete para asignar o reasignar
los atributos del contexto.
Para crear un espacio de nombres de contexto debemos tener el permiso del sistema CREATE ANY CONTEXT.
El siguiente comando crea un espacio de nombres llamado Mi_Contexto asociado a un paquete llamado
Paquete_Contexto:
CREATE OR REPLACE CONTEXT Mi_Contexto USING Paquete_Contexto;
Podemos aadir un atributo (usuario) al espacio de nombres con el siguiente comando:
DBMS_SESSION.SET_CONTEXT('MiContexto', 'usuario', 'Pedro');
Y podemos recuperar el valor del atributo como un VARCHAR2 con:

Oracle /49
SYS_CONTEXT('Mi_Contexto', 'usuario')
2.3.7. Funciones de conversin.
ASCIISTR Traslada un string a algn juego de caracteres y retorna un string ASCII en el
juego de caracteres de la base de datos.
BIN_TO_NUM Convierte valores binarios en su equivalente numrico.
CAST Moldea un tipo predefinido o de coleccin a otro. Se usa normalmente con tablas
anidadas y arrays variables.
CHARTOROWID Cambia un string de caracteres para que acten como un identificador de fila
interno de Oracle, o RowID.
COMPOSE Traslada un string de algn tipo de dato o un string Unicode a una forma
completa normalizada.
CONVERT Convierte una cadena de caracteres desde un lenguaje nacional a otro.
DECODE Selecciona un valor CHAR, VARCHAR2 o NUMBER de una lista segn un valor.
DECOMPOSE Traslada un string de algn tipo a un string Unicode despus de su
descomposicin cannica en el mismo juego de caracteres.
HEXTORAW Cambia una cadena de caracteres de nmeros hexadecimales en un valor binario.
NUMTODSINTERVAL Convierte un nmero a un literal INTERVAL DAY TO SECOND.
NUMTOYMINTERVAL Convierte un nmero a un literal INTERVAL YEAR TO MONTH.
RAWTOHEX Cambia un string de nmeros binarios a un string de caracteres de nmeros
hexadecimales.
RAWTONHEX Convierte un raw a un valor NVARCHAR2 que contiene su equivalente
hexadecimal.
ROWIDTOCHAR Cambia un identificador de fila interno de Oracle, o RowID, a un string.
ROWIDTONCHAR Convierte un valor RowID a un valor NVARCHAR2.
SCN_TO_TIMESTAMP Convierte un nmero de cambio de sistema a su aproximado TIMESTAMP.
TIMESTAMP_TO_SCN Convierte un TIMESTAMP a nmero de cambio de sistema aproximado.
TO_BINARY_DOUBLE Cambia un valor binario a un nmero de doble precisin con coma flotante.
TO_BINARY_FLOAT Cambia un valor binario a un nmero de simple precisin con coma flotante.
TO_CHAR Convierte un NUMBER o DATE a un string.
TO_CLOB Convierte un valor NCLOB a un valor CLOB.
TO_DATE Convierte un NUMBER, CHAR o VARCHAR2a DATE.
TO_DSINTERVAL Convierte un string del tipo CHAR, VARCHAR2, NCHAR oNVARCHAR2a un valor
INTERVAL DAY TO SECOND.
TO_LOB Convierte un LONG a un LOB como parte de una insercin o seleccin.
TO_MULTI_BYTE Convierte caracteres de un byte en un string de caracteres de varios bytes.
TO_NCHAR Convierte un string, NUMBER o DATE a al formato nacional.
TO_NCLOB Convierte valores CLOB a valores NCLOB.
TO_NUMBER Convierte un CHAR o VARCHAR2 a nmero.
TO_SINGLE_BYTE Convierte un CHAR o VARCHAR2a bytes simples.
TO_TIMESTAMP Convierte un string a un valor TIMESTAMP.
TO_TIMESTAMP_TZ Convierte un string a un valor TIMESTAMP WITH TIME ZONE.
TO_YMINTERVAL Convierte un string del tipo CHAR, VARCHAR2, NCHAR o NVARCHAR2 a un valor
INTERVAL YEAR TO MONTH.
TRANSLATE Traslada caracteres en un string dentro de diferentes caracteres.
UNISTR Convierte un string a Unicode.
Las funciones ms usadas para conversin de datos son las siguientes:
TO_CHAR. Transforma un DATE o NUMBER en un string.
TO_DATE. Transforma un NUMBER, CHAR o VARCHAR2 en un DATE. Para trabajar con valores timestamp
podemos usar TO_TIMESTAMP o TO_TIMESTAMP_TZ.
TO_NUMBER. Transforma un CHAR o VARCHAR2 en un NUMBER. Se indica el formato de la conversin
utilizando estos smbolos: 9 (posicin del nmero), 0 (posicin del nmero mostrando ceros), $ (formato
dlar), L (smbolo local de la moneda), S (hace que aparezca el smbolo del signo), D (posicin del smbolo
decimal, la coma), G (posicin del separador de grupo, el punto).
Conversin automtica de tipos de datos.
Oracle es capaz de convertir datos automticamente a fin de que la expresin final tenga sentido. En ese

Oracle /50
sentido son fciles las conversiones de texto a nmero y viceversa. Por ejemplo:
SELECT 5 + '3' FROM DUAL -- El resultado es 8
SELECT 5 || '3' FROM DUAL -- El resultado es 53
Tambin ocurre esto con la conversin de textos a fechas, de hecho es la forma habitual de asignar fechas.
Las reglas bsicas de conversin son las siguientes:
Cualquier NUMBER o DATE puede convertirse a un string. Cualquier funcin de cadenas puede usarse
sobre una columna de tipo NUMBER o DATE.
Un valor CHAR o VARCHAR2 sern convertidos a un NUMBER si contiene un valor numrico vlido.
Un valor CHAR o VARCHAR2 ser convertido a un DATE slo si contiene una fecha con un formato por
defecto. Esto es vlido para todas las funciones excepto para GREATEST y LEAST, las cuales tratan los
valores como strings.
Funciones especializadas de conversin.
Oracle incluye varias funciones de conversin especializadas. Si esperamos usar SQL*Plus y Oracle
simplemente para generar informes, probablemente no necesitaremos usar estas funciones.
Las funciones de conversin generalmente toman un valor simple como entrada y retornan un valor simple
convertido como salida. Por ejemplo, la funcin BIN_TO_NUM convierte valores binarios a un valor numrico
decimal. Los valores de entrada son una lista de dgitos como valores binarios separados por comas. As,
BIN_TO_NUM(1,1,1,0) produce la salida 14 (=1110 en base 2).
Cuando trabajamos con operaciones de recuperacin flashback, podemos convertir nmeros de cambio del
sistema (SCN's) a valores timestamp mediante la funcin SCN_TO_TIMESTAMP; TIMESTAMP_TO_SCN retorna
el SCN para un timestamp dado.
Desde Oracle Database 10g, podemos usar las funciones TO_BINARY_DOUBLE y TO_BINARY_FLOAT para
convertir valores entre doble y simple precisin respectivamente.
Funciones de transformacin.
Hay dos funciones especiales que podemos usar para controlar la conversin segn el tipo de entrada, en vez
de simplemente realizar una transformacin. Estas funciones son TRANSLATE y DECODE.
TRANSLATE es una funcin simple que realiza una sustitucin ordenada caracter a caracter dentro de un
string. El formato de esta funcin es el siguiente:
TRANSLATE( string , if, then)
TRANSLATE mira cada caracter dentro del string y comprueba el segundo argumento para ver si este caracter
est tambin dentro del segundo argumento. Si lo encuentra guarda su posicin en el segundo argumento y
busca en el tercer argumento el caracter situado en la misma posicin y lo enva como parte de la salida de la
funcin. Si no encuentra el caracter del string en el segundo argumento se enva este caracter como parte de la
salida de la funcin. Por ejemplo, la siguiente consulta
SELECT TRANSLATE(7671234, 234567890,
'BCDEFGHIJ') FROM DUAL
produce la salida 'GFG1BCD'.
Aunque TRANSLATE es tcnicamente una funcin de cadenas, podemos ver que convierte automticamente
los datos y trabaja con strings y nmeros.
Por su parte, la funcin DECODE puede ser considerada como una funcin de sustitucin valor por valor. Es
similar a una estructura IF-THEN-ELSE para seleccionar un valor. Su sintaxis es:
DECODE ( expresinBase, comparando1, valor1, comparando2, valor2, ... [, valorPorDefecto] )
El primer argumento es una expresin base que se compara con otras. A continuacin, cada dos argumentos
definen una expresin de comparacin y un valor. Si la expresin base coincide con la expresin de
comparacin la funcin retorna el valor asociado. Si no coincide ninguna comparacin la funcin retorna el
ltimo argumento (que es opcional) con un valor por defecto.
Todos los posibles valores devueltos deben ser del mismo tipo o convertibles al mismo tipo. Por ejemplo, la
siguiente consulta retorna el valor 2:
SELECT DECODE('abc' , 'a' , 1 , 'abc', 2 , 3) FROM DUAL;
2.3.8. Funciones de seleccin.
Oracle proporciona una estructura y varias funciones para seleccionar valores basndose en una o varias
condiciones. Las funciones de seleccin como DECODE, GREATEST o LEAST ya han sido vistas previamente.
La estructura CASE.
La estructura CASE no se trata de una estructura de control, sino de una instruccin que evala una expresin
booleana y retorna un valor (que podemos asignar a una variable o usar en la lista de campos de un SELECT).

Oracle /51
Admite dos sintaxis:
CASE expresin
WHEN valor_expresion1 THEN valor_devuelto1
WHEN valor_expresion2 THEN valor_devuelto2
ELSE valor_devuelto_por_defecto
END
CASE
WHEN valor operador1 expresion1 THEN valor_devuelto1
WHEN valor operador2 expresion2 THEN valor_devuelto2
ELSE valor_devuelto_por_defecto
END
Todos los posibles valores devueltos deben ser del mismo tipo. Por ejemplo, la siguiente consulta retorna el
valor 1 si la fecha actual es mayor que el '1/1/2010':
SELECT CASE WHEN SYSDATE >'1/1/2010' THEN 1 ELSE 2 END FROM DUAL;

3. Trabajando con objetos


3.1. Introduccin.
Segn los estndares actuales, una base de datos de Oracle es un conjunto de objetos pensados para gestionar
datos. Estos objetos estn contenidos en esquemas, y los esquemas estn asociados al perfil de un usuario
concreto.
En el estndar SQL-Oracle existe el concepto de catlogo, que sirve para almacenar esquemas. As, el nombre
completo de un objeto vendra dado por:
catlogo.esquema.objeto
Si no se indica el catlogo, se toma el catlogo por defecto. Si no se indica el esquema, se entiende que el
objeto est en el esquema actual.
Bsicamente, existen dos tipos de comandos SQL:
Los DLL, que permiten crear y definir los objetos de bases de datos: tablas, campos e ndices.
CREATE Utilizado para crear nuevas tablas, campos e ndices
DROP Empleado para eliminar tablas e ndices
ALTER Utilizado para modificar las tablas agregando campos o cambiando la definicin de los
campos.
Los DML, que permiten generar consultas para ordenar, filtrar y extraer datos de la base de datos.
SELECT Utilizado para consultar registros de la base de datos que satisfagan un criterio
determinado
INSERT Utilizado para cargar lotes de datos en la base de datos en una nica operacin.
UPDATE Utilizado para modificar los valores de los campos y registros especificados
DELETE Utilizado para eliminar registros de una tabla de una base de datos
3.2. Diccionario de datos de Oracle.
El diccionario de datos (DD) es una parte fundamental de las bases de datos Oracle. Est formado por tablas,
vistas y paquetes a los que se puede acceder para obtener informacin. Las tablas se crean automticamente
durante la instalacin y permiten saber:
- La estructura lgica y fsica de la base de datos.
- Los usuarios de la base de datos.
- Las restricciones de integridad sobre las tablas de la base de datos.
- El espacio asociado a cada objeto en la base de datos y la cantidad que se est utilizando por los distintos
objetos creados por los usuarios de la base de datos.
El usuario SYS es el dueo del DD y tiene todos los permisos sobre cualquier objeto de la base de datos
(tambin los de cualquier usuario). Componentes del DD son:
Tablas base: Una serie de tablas a las que el servidor de datos accede cada vez que se procesa una
instruccin DDL de SQL o en algunos comandos DML.
Vistas estticas: Decodifican y resumen la informacin contenida en las tablas base. Durante la
creacin de estas vistas se generan sinnimos pblicos para proveer el acceso a los usuarios de la base de
datos. Estas vistas deben ser utilizadas para las labores de administracin rutinarias que necesiten
informacin especfica sobre configuracin y estado de la base de datos. Tienen el nombre de estticas
porque no mantienen informacin relacionada con las sesiones. Se dividen en 3 categoras:
Oracle /52
Vistas con prefijo USER_: Puede utilizarlas cualquier usuario de la base de datos y se refieren a objetos
posedos por dicho usuario. Por ejemplo:
SELECT * FROM USER_TABLES;
Muestra toda la informacin de las tablas del usuario actual.
Vistas con prefijo ALL_: Evidente, las podr usar cualquier usuario y adems aaden la columna OWNER
al resto de informacin. Con estas vistas se puede tener acceso a la informacin de los objetos de los
cuales el usuario es dueo adems de los objetos pblicos y a los que el usuario tiene acceso (por
pertenecer a un grupo de seguridad o poseer ciertos privilegios).
Vistas con prefijo DBA_: Dan informacin sobre todos los objetos de la base de datos. Usualmente
tambin tienen la columna OWNER. Slo las puede utilizar el administrador o usuarios con privilegio
"SELECT ANY TABLE" o pertenezca a un rol que incluya el privilegio.
Vistas dinmicas (o performance views): Incluyen informacin sobre las condiciones actuales de
operacin en la base de datos. La mayor parte son creadas durante la instalacin y algunas se crean
especficamente para monitorear cierta actividad. Todas se identifican por el prefijo V$. Por ejemplo, la
vista dinmica V$_SESSION incluye informacin sobre las sesiones actuales y la vista V$SYSSTAT provee
informacin estadstica sobre el uso de la base de datos. Para obtener informacin general sobre las vistas
del diccionario de datos se podra utilizar esta consulta:
SELECT * FROM Dictionary WHERE table_name LIKE '%indicador%';
Por ejemplo, para ver todas las vistas relacionadas con tablas podramos ejecutar:
SELECT * FROM Dictionary WHERE table_name LIKE '%TABLE%';
Algunas vistas con el prefijo USER_ (pueden verse en ALL_VIEWS) son:
USER_OBJECTS: Lista de todos los objetos pertenecientes al usuario (tablas, vistas, paquetes, ndices,
triggers, sinnimos...).
USER_TABLES: Lista de todas las tablas del usuario.
USER_VIEWS: Vistas del usuario.
USER_USERS: Diversos datos sobre el usuario.
USER_UPDATABLE_COLUMNS: Columnas que pueden ser modificadas.
USER_JOBS: Tareas pertenecientes al usuario.
USER_TRIGGERS: Disparadores (triggers) del usuario.
USER_SYNONYMS: Sinnimos pertenecientes al usuario.
USER_INDEXES: ndices pertenecientes al usuario.
USER_CONSTRAINTS: Restricciones pertenecientes al usuario.
USER_TAB_PRIVS: Permisos sobre objetos con el usuario involucrado. Si se pone _COL_ en vez de _TAB_
se refiere a las columnas. Se puede distinguir entre:
USER_TAB_PRIVS_MADE: Permisos sobre los objetos del usuario.
USER_TAB_PRIVS_RECD: Permisos recibidos por el usuario.
USER_TAB_COLUMNS: Descripciones de las columnas del usuario.
USER_TAB_COMMENTS y USER_COL_COMMENTS: Comentarios sobre las tablas y columnas del usuario, si
se han insertado con el comando COMMENT:
COMMENT ON [TABLE|COLUMN] <Tabla>[.<Columna>] IS '<Texto>';
3.3. Crear y usar bases de datos.
Para crear una base de datos debemos usar la siguiente instruccin:
CREATE DATABASE MiBaseDeDatos;
Una vez creada la base de datos, debemos indicar explcitamente que queremos trabajar con ella:
USE MiBaseDeDatos;
Para eliminar una base de datos existente debemos usar:
DROP DATABASE MiBaseDeDatos;
3.4. Crear y usar tablespaces.
Nos podemos encontrar con los siguientes tipos de tablespaces:
El tablespace SYSTEM. Es el nico que se crea con la base de datos (CREATE DATABASE). Este tablespace
contiene: el Diccionario de Datos (incluidos los procedimientos almacenados), y el segmento de rollback
del sistema. No debe usarse para contener datos de aplicaciones.
Tablespaces TEMPORALES. Son aquellos en los que solamente puede haber objetos temporales. No se
pueden crear objetos permanentes como pueden ser los ndices, las tablas o los segmentos de rollback.

Oracle /53
Se utilizan para optimizar operaciones de ordenacin.
De tipo deshacer cambios (desde Oracle 9i). Se utilizan para gestionar poder deshacer las transacciones
incompletas.
Con tamao de bloque variable (desde Oracle 9i).
De tipo BigFile (desde Oracle 10g).
3.4.1. Estado del tablespace.
Su estado puede ser ONLINE u OFFLINE. Existe una vista que nos da informacin sobre los tablespaces de
nuestra base de datos. Esta vista es la siguiente:
SELECT Tablespace_Name, Status FROM DBA_TABLESPACES;
Para poder realizar una copia de seguridad del tablespace, estando completamente seguros de que nadie est
modificando los objetos del tablespace, es necesario establecer el modo OFFLINE. As mismo, se actuar de
igual forma para poder actualizar una aplicacin que se basa en los objetos de este tablespace sin que ningn
usuario pueda modificar los datos en medio de la actualizacin.
3.4.2. Para crear un tablespace:
La sintaxis general para crear un tablespaces es:
CREATE [UNDO] TABLESPACE nombre_tablespace
DATAFILE Opciones_Datafile Opciones_Almacenamiento ;
Donde Opciones_Datafile tiene la sintaxis:
'nombre fichero' [AUTOEXTEND OFF]
'nombre fichero' [AUTOEXTEND ON [NEXT int K | M] [MAXSIZE int K | M]]
La opcin AUTOEXTEND MAXSIZE es por defecto UNLIMITED si no se especifica valor.
Donde Opciones_Almacenamiento tiene la sintaxis:
DEFAULT [COMPRESS|NOCOMPRESS] STORAGE storage_clause
MINIMUM EXTENT int {K|M}
BLOCKSIZE int K
LOGGING | NOLOGGING
FORCE LOGGING
ONLINE | OFFLINE
PERMANENT | TEMPORARY
EXTENT MANAGEMENT {DICTIONARY | LOCAL {AUTOALLOCATE | UNIFORM [SIZE int K | M]} }
SEGMENT SPACE MANAGEMENT {MANUAL | AUTO}
3.4.3. Para aumentar el tamao del tablespace:
Se utiliza la instruccin ALTER DATABASE TABLESPACE, como por ejemplo:
ALTER DATABASE TABLESPACE prueba ADD DATAFILE 'c:\oracleexe\oradata\XE\prueba02.dbf'SIZE 50M;
/
ALTER DATABASE DATAFILE'/users/oradata/orcl/prueba01.dbf'RESIZE 150M;
3.4.4. Para borrar un tablespace:
Se utiliza la instruccin DROP TABLESPACE nombre_tablespace;
3.4.5. Tablespaces temporales:
Para crear un tablespace temporal simplemente hay que aadir la palabra TEMPORARY a la instruccin utilizada
para crear tablespaces normales.
CREATE TABLESPACE prueba DATAFILE '/users/oradata/orcl/prueba01.dbf' SIZE 100M TEMPORARY;
/
ALTER USER nombre_de_usuario TEMPORARY TABLESPACE nombre_de_tablespace;
/
SELECT username, temporary_tablespace FROM dba_users;
/
SELECT tablespace_name, contents FROM dba_tablespaces;
3.4.6. Tablespaces read-only (de solo lectura):
Los tablespace de solo lectura permiten consultar los datos de los objetos, pero no se puede ni borrar ni
insertar nada en ellos. La principal ventaja de un tablespace read-only es que no hace falta hacer un backup
del mismo.
Ejemplo de los tablespaces read-only:
SQL>ALTER TABLESPACE DataCursoxy READ ONLY;
Tablespace modificado.
SQL>INSERT INTO tabla01 VALUES ('PRIMERA FILA');

Oracle /54
ORA-00372: el fichero 3 no puede ser modificado en este momento
ORA-01110: fichero de datos 3: '/u02/oradata/CURSOxy/datacursoxy01.dbf'
SQL> DROP TABLE TABLA01;
Tabla borrada.
SQL> alter tablespace DataCursoxy READ WRITE;
Tablespace modificado.
SQL>INSERT INTO tabla02 VALUES ('PRIMERA FILA');
1 fila creada.
SQL>COMMIT;
Validacin terminada.
3.4.7. Tablespace de Undo (deshacer):
Podemos tener varios tablespaces de "undo", pero slo uno de ellos estar activo. No se pueden crear objetos
sobre un tablespace de "undo".
Al cambiar de tablespace "undo" activo (con UNDO TABLESPACE), los segmentos de rollback que contiene el
nuevo tablespace pasan a estar ONLINE, mientras que los del tablespace anterior se ponen OFFLINE.
Se crean de dos formas:
- Mediante CREATE DATABASE.
- Mediante CREATE TABLESPACE:
CREATE UNDO TABLESPACE undotbs02 DATAFILE 'c:\oraclexe\oradata\ex\undo02.dbf'SIZE 25M
REUSE AUTOEXTEND ON;
Parmetros de inicializacin de los espacios de tablas de deshacer:
- Undo_Management (valores MANUAL/AUTO). Si AUTO se gestionar de forma automtica el espacio de
deshacer. No es dinmico, cuando se cambia de estado se debe re arrancar la instancia.
- Undo_tablespace (MANUAL/AUTO). Se usa en entornos RAC (Real Application Clusters).
3.5. Crear esquemas.
Cada esquema est asociado a un usuario de Oracle. Por tanto, para crear un esquema debemos crear primero
el usuario, y tambin los tablespaces dnde ubicar los objetos que creemos dentro del esquema (aunque se
pueden utilizar tablespaces ya existentes).
Para poder realizar estos pasos es necesario iniciar la sesin en la base de datos con un usuario con permisos
de administracin, lo ms sencillo es utilizar directamente el usuario SYSTEM.
Para crear un tablespace para datos y otro para ndices, usaremos
CREATE TABLESPACE "APPDAT" LOGGING
DATAFILE '/export/home/oracle/oradata/datafiles/APPDAT.dbf' SIZE 1024M
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
para los datos, con tamao inicial de 1024 Mb, y auto extensible; y usaremos
CREATE TABLESPACE "APPIDX" LOGGING
DATAFILE '/export/home/oracle/oradata/datafiles/APPIDX.dbf' SIZE 512M
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
para los ndices, con tamao inicial de 512 Mb, y auto extensible.
Para crear el usuario que va a trabajar sobre estos tablespaces, y que ser el propietario de los objetos que se
creen en ellos usaremos
CREATE USER "APP" PROFILE "DEFAULT" IDENTIFIED BY "APPPWD"
DEFAULT TABLESPACE "APPDAT" TEMPORARY TABLESPACE "TEMP" ACCOUNT UNLOCK;
Sino se especifica un tablespace, la BD le asignar el tablespace USERS, que es el tablespace
que se utiliza por
defecto para los nuevos usuarios.
Se puede apreciar tambin que no hay ninguna referencia al tablespace de ndices APPIDX que hemos creado.
Si queremos mantener datos e ndices separados habr que acordarse de especificar este tablespace en las
sentencias de creacin de ndices de este usuario, sino se crearn en APPDAT:
CREATE INDEX mi_indice ON mi_tabla(mi_campo)
TABLESPACE APPIDX;
Slo falta asignar al usuario los permisos necesarios para trabajar. Si se le asignan los roles "Connect" y
"Resource" ya tiene los permisos mnimos, podr conectarse y podr realizar las operaciones ms habituales de
consulta, modificacin y creacin de objetos en su propio esquema.
GRANT "CONNECT" TO "APP";
GRANT "RESOURCE" TO "APP";
En el momento que el usuario crea el primer objeto en la BD, se crea automticamente el esquema.

Oracle /55
3.6. Crear y usar tablas.
3.6.1. Crear el esquema de una tabla.
Para crear una tabla se usa la siguiente instruccin SQL:
CREATE TABLE tabla (
campo1 tipo (tamao) restricciones1 ,
...,
campoN tipo (tamao) restriccionesN ,
CONSTRAINT nombre_restriccin tipo_restriccin (columnas)
...
);
En donde tabla es el nombre de la tabla que se va a crear; campo1...campoN
son el nombre de los campos que se
van a crear en la nueva tabla (la nueva tabla debe contener, al menos, un campo); tipo es el tipo de datos de
cada campo; tamao es el tamao del campo segn su tipo; restricciones1... restriccionesN son clusulas de
restriccin opcionales que restringen el comportamiento del campo; CONSTRAINT define restricciones con
nombre propio (vase la siguiente seccin).
Como ejemplo crearemos una tabla para almacenar empleados:
CREATE TABLE Empleado (
ID INTEGER PRIMARY KEY,
Nombre VARCHAR2(25)NOT NULL,
Apellidos VARCHAR2(50) NOT NULL,
Fecha_Nacimiento DATE,
Categoria VARCHAR2(1) DEFAULT 'A');
Se crea una nueva tabla llamada Empleado con un campo Nombre de tipo texto y longitud 25 y otro llamado
Apellidos con longitud 50 que no admiten valores nulos; crea otro campo llamado Fecha_Nacimiento de tipo
DATE, y el campo Categoria admite un nico caracter cuyo valor por defecto es 'A'; y crea el campo ID de tipo
entero, que se establece como clave principal.
3.6.2. Crear una tabla a partir de otra.
Oracle permite crear una nueva tabla al aire, basndose en una consulta sobre una tabla existente. Por
ejemplo, el siguiente comando crea una versin simplificada de la tabla Empleado.
CREATE TABLE Empleado_2 AS
SELECT Apellidos, Categoria FROM Empleado;
La nica restriccin de este comando es que no trabaja con consultas que devuelven columnas del tipo LONG.
Si se describe la nueva tabla (con el comando DESCRIBE), se revela que hereda la definicin de sus columnas
de la tabla Empleado.
La nueva tabla creada ser poblada con los datos procedentes de la consulta. Si deseamos filtrar los registros
que se deben insertar en la nueva tabla podemos especificar condiciones con la clusula WHERE. El siguiente
comando crea una nueva tabla con columnas para los apellidos, categora y ao de nacimiento de aquellos
empleados nacidos antes de 1980:
CREATE TABLE Empleado_3 AS
SELECT Apellidos, Categoria, EXTRACT(Year from Fecha_Nacimiento) AS AoNacimiento
FROM Empleado
WHERE EXTRACT(Year from Fecha_Nacimiento) < 1980;
Si queremos crear la nueva tabla sin insertarle ningn registro basta con especificar una condicin que no
cumpla ninguno de los registros de la consulta.
Esta forma de crear una nueva tabla permite utilizar consultas que devuelven columnas nuevas, bien como
producto de funciones o por la combinacin de otras columnas. Las columnas basadas en caracteres se
ajustarn al tamao necesario para contener los datos de las columnas nuevas. Las columnas numricas que
proceden de la computacin de columnas de la tabla original que especifican una precisin, se simplifican al
tipo NUMBER, sin especificar la precisin, en la nueva tabla.
Podemos crear la nueva tabla sin generar entradas de registro de deshacer (registros cronolgicos de acciones
de base de datos usadas durante la recuperacin de la base de datos). Se evita la generacin de estas entradas
usando la palabra clave NOLOGGING en el comando CREATE TABLE. Haciendo esto se aumenta el rendimiento
del comando porque tendr menos trabajo qu hacer. Sin embargo, haciendo esto la tabla no podr ser
recreada si, despus de un fallo de la base de datos, se utilizan los archivos de deshacer para recuperar la base
de datos. El siguiente ejemplo muestra cmo usar la palabra clave NOLOGGING.
CREATE TABLE Empleado_2 NOLOGGING AS

Oracle /56
SELECT * FROM Empleado;
3.6.3. Eliminar una tabla.
Para eliminar una tabla se usa la instruccin:
DROP TABLE nombreTabla ;
3.6.4. Cambiar de nombre.
La orden RENAME permite el cambio de nombre de cualquier objeto. Sintaxis:
RENAME nombreViejo TO nombreNuevo ;
3.6.5. Borrar el contenido de tablas.
La orden TRUNCATE TABLE seguida del nombre de una tabla, hace que se elimine el contenido de la tabla,
pero no la tabla en s. Incluso borra del archivo de datos el espacio ocupado por la tabla.
TRUNCATE TABLE nombreTabla ;
3.6.6. Modificar el esquema de una tabla.
Una vez creado el esquema de una tabla podemos modificarlo con la instruccin ALTER TABLE.
Para aadir un nuevo campo a una tabla creada:
ALTER TABLE Empleado ADD Tipo VARCHAR(20) NULL;
Para cambiar el tipo de datos y propiedades de una determinada columna:
ALTER TABLE Empleado MODIFY (Tipo INT);
Para eliminar un campo existente de una tabla:
ALTER TABLE Empleado DROP COLUMN Tipo;
Reglas para aadir o modificar una columna.
Las reglas para aadir una columna a una tabla son las siguientes:
Podemos aadir una columna directamente si no se ha especificado NOT NULL sobre ella.
Podemos aadir una columna NOT NULL en tres pasos:
1. Aadir la columna sin especificar NOT NULL.
2. Llenar esta columna con datos en cada fila.
3. Modificar la columna para ser NOT NULL.
Nota. Si usamos la clusula DEFAULT cuando aadimos una columna, Oracle actualizar cada
registro con el valor por defecto cuando se aada la columna.
Las reglas para modificar una columna son las siguientes:
Podemos incrementar el tamao de una columna de caracteres.
Podemos incrementar el tamao de una columna numrica.
Podemos incrementar o decrementar el nmero de lugares decimales de una columna numrica.
Podemos pasar de CHAR a VARCHAR2 y viceversa (si no se modifica el tamao).
Podemos pasar de DATE a TIMESTAMP y viceversa.
Adems, si una columna tiene el valor NULL en cada registro de la tabla, podemos hacer los siguientes
cambios:
Podemos cambiar el tipo de dato de la columna.
Podemos decrementar el tamao de una columna de caracteres.
Podemos decrementar el nmero de dgitos de una columna numrica.
Hay una notable excepcin en las restricciones de cambio de tipo de dato. Oracle soporta el cambio de
columnas LONG a un tipo LOB, incluso si hay datos en la columna LONG.
Otros modos de eliminar columnas.
Podemos eliminar varias columnas de una tabla en un nico comando. Por ejemplo, el siguiente comando
elimina los campos Nombre y Apellidos de la tabla Empleado:
ALTER TABLE Empleado DROP (Nombre, Apellidos);
Si eliminamos columnas que son parte de la clave primaria o tienen la restriccin UNIQUE, necesitaremos
tambin usar la clusula CASCADE CONSTRAINTS al final del comando ALTER TABLE. Cuando se elimina una
columna que es la clave primaria, tambin se elimina su ndice.
Eliminar una columna es ms complejo internamente que aadir o modificar una columna, ya que requiere un
trabajo adicional por parte de Oracle. Quitar la columna de la lista de columnas de la tabla es ms fcil. Quitar
una columna hace que se oculte cuando se consulta la tabla, pero no modifica el espacio actual reservado
fsicamente para ella. Podemos ocultar una columna inmediatamente marcndola como UNUSED, y eliminarla
permanentemente ms tarde, cuando el impacto de rendimiento por tener que redimensionar todos los
registros de la tabla no afecte a nuestro trabajo con la base de datos.

Oracle /57
En el siguiente ejemplo se oculta una columna de la tabla Empleado:
ALTER TABLE Empleado SET UNUSED COLUMN Fecha_Nacimiento;
Al marcar la columna como "unused" no liberamos el espacio previamente asignado para cada valor de esta
columna en cada registro, hasta que eliminamos las columnas no usadas de la siguiente forma:
ALTER TABLE Empleado DROP UNUSED COLUMNS;
Para ver todas las tablas con columnas marcadas como no usadas, podemos consultar las vistas
USER_UNUSED_COL_TABS, ALL_UNUSED_COL_TABS y DBA_UNUSED_COL_TABS.
3.6.7. Obtener el esquema de una tabla.
El comando DESCRIBE permite obtener la estructura de una tabla. Ejemplo:
DESCRIBE Empleado;
Y aparecern los campos de la tabla Empleado, de forma parecida a la siguiente:
Nombre Null? Tipo
------------------------- ------------- ----------------------
ID NOT NULL NUMBER(38,0)
NOMBRE NOT NULL VARCHAR2(25)
APELLIDOS NOT NULL VARCHAR2(50)
FECHA_NACIMIENTO DATE
CATEGORIA VARCHAR2(1)
Esta instruccin no es parte del SQL estndar, pero casi es considerada as ya que casi todos los SGBD la
soportan.
3.6.8. Aadir comentarios a las tablas.
Se le pueden poner comentarios a las tablas y las columnas. Un comentario es un texto descriptivo utilizado
para documentar la tabla. Su sintaxis es:
COMMENT ON { TABLE NombreTabla | COLUMN tabla.nombreColumna } IS 'Comentario'
Para mostrar los comentarios puestos se usan las siguientes vistas del diccionario de datos mediante la
instruccin SELECT:
- USER_TAB_COMMENTS. Comentarios de las tablas del usuario actual.
- USER_COL_COMMENTS. Comentarios de las columnas del usuario actual.
- ALL_TAB_COMMENTS. Comentarios de las tablas de todos los usuarios (slo administradores).
- ALL_COL_COMMENTS. Comentarios de las columnas de todos los usuarios (slo administradores).
3.6.9. Determinar si existe una tabla.
Para determinar si ya existe una tabla en un esquema determinado podemos consultar las siguientes vistas del
diccionario de datos del sistema: DBA_TABLES, USER_TABLES o ALL_TABLES.
Por ejemplo, para saber si existe la tabla MITABLA dentro del esquema actual usaramos:
SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME='MITABLA'
Si esta consulta no retorna registros es que no existe dicha tabla. Si queremos obtener toda la informacin
sobre una tabla llamada MITABLA perteneciente a un usuario llamado USER1 usaramos:
SELECT * FROM ALL_TABLES WHERE TABLE_NAME='MITABLA' AND OWNER='USER1';

Nota. En las vistas del diccionario de datos, todos los nombres de objetos se guardan en
maysculas.
3.6.10. Uso de tablas temporales.
Podemos crear tablas que existan nicamente para nuestra sesin o cuyos datos persistan slo durante nuestra
transaccin. Podemos usar tablas temporales para soportar consultas de resumen especializadas o
requerimientos especficos de la aplicacin.
Para crear una tabla temporal se usa el comando CREATE GLOBAL TEMPORARY TABLE. Cuando se crea una
tabla temporal podemos especificar si sus datos deberan durar hasta que termine nuestra sesin (mediante la
clusula ON COMMIT PRESERVE ROWS) o si las filas deben ser eliminadas cuando la transaccin se complete
(mediante la clusula ON COMMIT DELETE ROWS).
Al contario que una tabla permanente, una tabla temporal no reserva automticamente espacio cuando es
creada. El espacio ser asignado dinmicamente a mediada que las filas son insertadas. El siguiente ejemplo
muestra cmo crear una tabla temporal:
CREATE GLOBAL TEMPORARY TABLE FALTA_ROLLUP (
ao NUMBER(4),
mes VARCHAR2(9),
contador NUMBER)

Oracle /58
ON COMMIT PRESERVE ROWS;
Podemos ver la duracin de nuestros datos en FALTA_ROLLUP consultando la columna Duration de la vista
USER_TABLES para esta tabla. En este caso, el valor de Duration es SYS$SESSION. Si hubisemos especificado
la clusula ON COMMIT DELETE ROWS, el valor de Duration debera ser SYS$TRANSACTION.
Ahora que existe la tabla FALTA_ROLLUP, podemos poblarla mediante un comando INSERT a partir de una
subconsulta sobre otra tabla. Podemos entonces usar la tabla temporal como parte de una combinacin con
otras tablas.
3.7. Restricciones.
Una restriccin es una condicin de obligado cumplimiento para una o ms columnas de la tabla. A cada
restriccin se le pone un nombre (en el caso de no poner un nombre, entonces el propio Oracle lo crea a
partir del nombre de tabla, columna y tipo de restriccin). Los nombres de restriccin no se pueden repetir
para el mismo esquema, por lo que es buena idea incluir de algn modo el nombre de la tabla, los campos
involucrados y el tipo de restriccin en el nombre de la misma. Por ejemplo pieza_id_pk podra indicar que el
campo id de la tabla pieza tiene una clave principal (PRIMARY KEY).
3.7.1. Tipos de restricciones.
Oracle admite las siguientes restricciones:
NULL, para indicar que el campo admite nulos (por defecto).
CREATE TABLE cliente ( dni VARCHAR2(9) NULL ); /* o tambin */
CREATE TABLE cliente ( dni VARCHAR2(9) );
NOT NULL, para indicar que el campo no admite nulo.
CREATE TABLE cliente (dni VARCHAR2(9) NOT NULL); /* o tambin */
CREATE TABLE cliente(dni VARCHAR2(9) CONSTRAINT cli_dni_nn NOT NULL);
UNIQUE, para indicar no repetidos en el campo.
CREATE TABLE cliente (dni VARCHAR2(9) UNIQUE); /* o tambin */
CREATE TABLE cliente(dni VARCHAR2(9) CONSTRAINT dni_u UNIQUE);
PRIMARY KEY, para indicar que el campo es la clave primaria.
CREATE TABLE cliente(dni VARCHAR2(9) PRIMARY KEY) ; /* o tambin */
CREATE TABLE cliente(dni VARCHAR2(9) CONSTRAINT cliente_pk PRIMARY KEY) ;
Se puede crear una clave primaria sobre ms de un campo:
CREATE TABLE alquiler(
dni VARCHAR2(9), cod_pelicula NUMBER(5),
CONSTRAINT alquiler_pk PRIMARY KEY(dni, cod_pelicula)
);
FOREIGN KEY ...REFERENCES, para indicar que el campo es una clave fornea, y de esta forma activar la
integridad referencial.
En la siguiente instruccin,
CREATE TABLE alquiler(
dni VARCHAR2(9) CONSTRAINT dni_fk REFERENCES cliente(dni),
cod_pelicula NUMBER(5),
CONSTRAINT pelicula_fk FOREIGN KEY (cod_pelicula) REFERENCES pelicula(cod),
CONSTRAINT alquiler_pk PRIMARY KEY(dni,cod_pelicula));
Se indica que el campo dni se relaciona con la columna dni de la tabla clientes, y que el campo cod_pelicula
se relaciona con la columna cod de la tabla pelcula.
La integridad referencial puede provocar varios problemas en cuanto a borrados. Por ello Oracle ofrece
soluciones a aadir tras la clusula REFERENCES:
- ON DELETE SET NULL, coloca nulos todas las claves secundarias relacionadas con la borrada.
- ON DELETE CASCADE, borra todos los registros cuya clave secundaria es igual que la clave del registro
borrado.
En esas clusulas se podra sustituir la palabra DELETE por la palabra UPDATE, haciendo que el
funcionamiento se refiera a cuando se modifica un registro de la tabla principal.
DEFAULT valor_por_defecto, establece un valor por defecto para el campo.
CREATE TABLE cliente (dni VARCHAR2(9)DEFAULT '00000000X');
CHECK, establece una condicin que deben cumplir los contenidos de una o ms columnas.
Una misma columna puede tener mltiples CHECK en su definicin (se pondran varios CONSTRAINT
seguidos, sin comas). Por ejemplo:

Oracle /59
CREATE TABLE ingreso (
cod NUMBER(5) PRIMARY KEY,
importe NUMBER(11,2) CONSTRAINT importe_min_ck CHECK (importe>0)
CONSTRAINT importe_max_ck CHECK (importe<8000)
);
O bien:
CREATE TABLE ingreso (
cod NUMBER(5) PRIMARY KEY,
importe NUMBER(11,2),
CONSTRAINT importe_rango_ck CHECK (importe>0 AND importe<8000)
);
En este caso, CHECK prohbe aadir datos cuyo importe no est entre 0 y 8000.
3.7.2. Reglas para nemotcnicas.
Oracle aconseja esta regla a la hora de poner nombre a las restricciones:
- Tres letras para el nombre de la tabla
- Carcter de subrayado
- Tres letras con la columna afectada por la restriccin
- Carcter de subrayado
- Dos letras con la abreviatura del tipo de restriccin. La abreviatura puede ser: NN (NOT NULL), PK
(PRIMARY KEY), UK (UNIQUE), FK (FOREIGN KEY) y CK (CHECK).
3.7.3. Aadir restricciones.
Es posible querer aadir restricciones tras haber creado la tabla. En ese caso se utiliza la siguiente sintaxis:
ALTER TABLE tabla ADD [CONSTRAINT nombre] tipoDeRestriccin (columnas);
Donde tipoDeRestriccin puede ser CHECK, UNIQUE, PRIMARY KEY o FOREIGN KEY. Las restricciones NOT NULL
deben indicarse mediante ALTER TABLE ... MODIFY colocando NOT NULL en el campo que se modifica.
Para hacer NOT NULL una columna en una tabla:
ALTER TABLE tabla MODIFY (campo NOT NULL);
Para cambiar el valor por defecto de una columna:
ALTER TABLE tabla MODIFY campo VARCHAR2(135) DEFAULT 'ABC...';
3.7.4. Borrar restricciones.
La sintaxis general para eliminar una restriccin es:
ALTER TABLE tabla DROP PRIMARY KEY | UNIQUE (campos) | CONSTRAINT nombreRestriccin [CASCADE]
La opcin PRIMARY KEY elimina una clave principal (tambin quitar el ndice UNIQUE sobre las campos que
formaban la clave). UNIQUE elimina ndices nicos. La opcin CONSTRAINT elimina la restriccin indicada.
La opcin CASCADE hace que se eliminen en cascada las restricciones de integridad que dependen de la
restriccin eliminada.
3.7.5. Desactivar restricciones.
A veces conviene temporalmente desactivar una restriccin para saltarse las reglas que impone. La sintaxis
generales:
ALTER TABLE tabla DISABLE CONSTRAINT nombre [CASCADE]
La opcin CASCADE hace que se desactiven tambin las restricciones dependientes de la que se desactiv.
3.7.6. Activar restricciones.
Para desactivar la anulacin de una restriccin:
ALTER TABLE tabla ENABLE CONSTRAINT nombre [CASCADE]
Slo se permite volver a activar si los valores de la tabla cumplen la restriccin que se activa. Si hubo
desactivado en cascada, habr que activar cada restriccin individualmente.
3.7.7. Cambiar de nombre a las restricciones.
Para hacerlo se utiliza este comando:
ALTER TABLE tabla RENAME CONSTRAINT nombreViejo TO nombreNuevo;
3.7.8. Mostrar restricciones.
El trabajo con restricciones ya se ha visto que es complejo. Por eso todas las bases de datos suelen
proporcionar una vista (o ms) del diccionario de datos que permite consultar las restricciones. En el caso de
Oracle, se puede utilizar la vista del diccionario de datos USER_CONSTRAINTS.
Esta vista permite identificar las restricciones colocadas por el usuario ( ALL_CONSTRAINTS permite mostrar
las restricciones de todos los usuarios, pero slo est permitida a los administradores). En esa vista aparece
toda la informacin que el diccionario de datos posee sobre las restricciones.

Oracle /60
SELECT * FROM USER_CONSTRAINTS;
3.8. Crear y eliminar ndices.
Los ndices son esquemas que hacen que una base de datos acelere las operaciones de consulta y ordenacin
sobre los campos a los que el ndice hace referencia. Se almacenan aparte de la tabla a la que hacen referencia,
lo que permite crearlos y borrarlos en cualquier momento.
Lo que proporcionan es una lista ordenada a la que Oracle puede acceder para facilitar la bsqueda de los
datos. Cada vez que se aade un nuevo registro, los ndices involucrados se actualizan a fin de que su
informacin est al da. De ah que cuantos ms ndices haya, ms le cuesta a Oracle aadir registros, pero
ms rpidas se realizan las instrucciones de consulta.
La mayora de los ndices se crean de manera implcita, como consecuencia de las restricciones PRIMARY KEY
(que obliga a crear un ndice nico sobre los campos clave). La restriccin UNIQUE crea tambin un ndice
nico, y FOREIGN KEY crea un ndice con posibilidad de repetir valores (ndice con duplicados). stos son
ndices obligatorios, porque los crea la propia base de datos. El nombre que se les da a esos ndices suele ser
el mismo que el nombre de la restriccin que los genera.
3.8.1. Especificacin de los tablespaces para ndices.
Las restricciones UNIQUE y PRIMARY KEY crean ndices. A menos que se especifique otra cosa, estos ndices
son ubicados en el tablespace por defecto. Para especificar un tablespace diferente debemos usar la clusula
USING INDEX TABLESPACE en el comando de creacin de la tabla, tal como se muestra en el siguiente
ejemplo:
CREATE TABLE Autor (
Nombre VARCHAR2(50),
Comentarios VARCHAR2(100),
CONSTRAINT Autor_PK PRIMARY KEY (Nombre) USING INDEX TABLESPACE USERS
);
En este ejemplo se especifica que el ndice asociado con la restriccin de clave primaria Autor_PK ser ubicado
en el tablespace USERS. (En la mayora de instalaciones se crea el tablespace USERS, y se establece como
tablespace por defecto.)
3.8.2. Creacin de ndices explcitos.
Aparte de los ndices obligatorios comentados anteriormente, se pueden crear ndices de forma explcita.
stos se crean para aquellos campos sobre los cuales se realizarn bsquedas e instrucciones de ordenacin
frecuente.
La sintaxis para crear un ndice es la siguiente:
CREATE [BITMAP | UNIQUE] INDEX nombreIndice
ON nombreTabla (columna [,columna] . . .) [REVERSE];
Donde nombreIndice debe ser un nombre nico y seguir las convenciones de nombrado de Oracle;
nombreTabla es el nombre de la tabla para la que se establecer el ndice; y columna son los nombres de las
columnas de la tabla que sern indexadas.
La opcin BITMAP permite crear ndices sobre columnas con muy pocos valores distintos. La palabra clave
REVERSE le dice a Oracle que invierta los bytes del valor del ndice, lo cual puede mejorar la distribucin
durante la insercin de muchos datos secuenciales.
Por ejemplo:
CREATE INDEX nombre_completo
ON cliente (apellido1, apellido2, nombre);
Crea un ndice para el valor conjunto de los campos apellido1, apellido2 y nombre. Esto no es lo mismo que
crear un ndice para cada campo; este ndice es efectivo cuando se buscan u ordenan clientes usando los tres
campos a la vez.
Se aconseja crear ndices en campos que:
- Contengan una gran cantidad de valores.
- Contengan una gran cantidad de nulos.
- Son parte habitual de clusulas WHERE, GROUP BY u ORDER BY.
- Son parte de listados de consultas de grandes tablas sobre las que casi siempre se muestran como mucho
un 4% de su contenido.
No se aconseja en campos que:
- Pertenezcan a tablas pequeas.
- No se usan a menudo en las consultas.

Oracle /61
- Pertenecen a tablas cuyas consultas muestran ms de un 6% del total de registros.
- Pertenecen a tablas que se actualizan frecuentemente.
- Se utilizan en expresiones
Los ndices se pueden crear utilizando expresiones complejas:
CREATE INDEX nombre_complejo ON clientes (UPPER(nombre));
Estos ndices tienen sentido si en las consultas se utilizan exactamente esas expresiones.
3.8.3. Forzando unicidad.
Cuando se crea el ndice implcito para la clave de una tabla se aplica por defecto la opcin de unicidad en los
valores del ndice. Esto queda establecido por el uso de la restriccin PRIMARY KEY.
Puede ser importante para nuestra base de datos garantizar unicidad de valores en columnas que no formen
parte de la clave. Por ejemplo, supongamos la tabla Biblioteca, en la que queremos aplicar unicidad sobre los
campos Titulo y Autor, de forma que no puedan existir dos registros con el mismo autor y ttulo de libro
simultneamente. Existen tres formas alternativas de lograr esto:
Creando una restriccin de clave primaria sobre los dos campos al crear la tabla, o bien alterndola
despus de crearla.
ALTER TABLE Biblioteca
ADD CONSTRAINT B_PK PRIMARY KEY (Titulo, Autor);
Creando una restriccin UNIQUE sobre las columnas cuando se crea la tabla, o bien alterando la tabla
despus de crearla.
ALTER TABLE Biblioteca ADD CONSTRAINT B_UK UNIQUE (Titulo, Autor);
Creando un ndice de unicidad. Si creamos primero el ndice de unicidad, todava podremos crear la clave
primaria en la tabla, y adems Oracle usar el ndice existente como el ndice primario clave.
El siguiente comando muestra cmo crear el ndice de unicidad para estas dos columnas:
CREATE UNIQUE INDEX BA$Titulo_Autor
ON Biblioteca (Titulo, Autor);
3.8.4. Crear un ndice bitmap.
Para ayudar a realizar consultas que usan columnas que admiten un rango limitado de valores, podemos usar
ndices bitmap. Los ndices bitmap slo deberan ser usados si los datos raras veces se actualizan, porque
aaden un coste adicional a todas las transacciones de manipulacin de datos sobre las tablas que incluyen el
ndice.
Nota. Los ndices bitmap no deberan usarse con tablas involucradas en aplicaciones que procesan
transacciones online, debido a los mecanismos internos que usa Oracle para mantenerlos.
Para entender estos ndices pensemos que la tabla Biblioteca tiene una columna Valoracion, en la cual se usan
unos pocos valores: del 1 al 5. Crear un ndice B*-tree tradicional sobre la columna Valoracion no suele ser
habitual, a menos que sea una columna muy usada para filtrar las consultas en la clusula WHERE. Sin
embargo, esta columna puede tomar todas las ventajas de un ndice bitmap.
Internamente, un ndice bitmap mapea los diversos valores de la columna a cada registro. Para nuestro
ejemplo, como hay 5 valoraciones diferentes para un libro, habr 5 entradas bitmap diferentes en el ndice.
Por ejemplo, si los cuatro primeros registros tienen una valoracin de 1, y los siguientes seis registros tiene
una valoracin de 3, entonces las entradas del ndice bitmap tendrn los siguientes valores:
1: 1 1 1 1 0 0 0 0 0 0
2: 0 0 0 0 0 0 0 0 0 0
3: 0 0 0 0 1 1 1 1 1 1
4: 0 0 0 0 0 0 0 0 0 0
5: 0 0 0 0 0 0 0 0 0 0
Cada columna de 0's y 1's representa un registro de la tabla. En este caso se muestran slo diez columnas
porque esos son los registros considerados en este ejemplo.
El optimizador de Oracle puede convertir dinmicamente entradas de ndices bitmap a RowID's durante el
procesado de consultas. Esta conversin permite al optimizador usar ndices sobre columnas que tienen
muchos valores distintos y sobre aquellas que tienen pocos valores distintos.
Para crear el ndice bitmap se usa la clusula BITMAP, tal como se muestra a continuacin:
CREATE BITMAP INDEX B$Bitmap_Valoracion
ON Biblioteca (Valoracion);
Si elegimos usar ndices bitmap, debemos sopesar las ventajas de rendimiento durante las consultas frente al
coste de rendimiento durante los comandos de manipulacin de datos. Cuantos ms ndices de bitmap hay en

Oracle /62
una tabla, ms grande es el coste durante cada transaccin. No debemos usar ndices bitmap sobre columnas
que tienen frecuentemente nuevos valores aadidos.
3.8.5. Situar un ndice en la base de datos.
Podemos especificar dnde debe ubicarse el ndice de una tabla asignndolo a un tablespace especfico. Un
tablespace se compone de ficheros de datos fsicos en los cuales se almacenan los registros e ndices de cada
tabla.
Para incrementar la disponibilidad y las opciones de administracin, los ndices de una tabla y la misma tabla
deberan estar ubicados en tablespaces situados sobre unidades de disco fsicamente separadas. Para
especificar el tablespace en el cual colocar un ndice se utiliza la palabra clave TABLESPACE en el comando
CREATE INDEX, tal como se muestra a continuacin:
CREATE UNIQUE INDEX B$Titulo_Autor
ON Biblioteca (Titulo, Autor)
TABLESPACE B_Indices;
En este ejemplo, B_Indices es el nombre de un tablespace creado previamente por el administrador de la base
de datos.
Cuando creamos una clave primaria o una restriccin de unicidad, Oracle crea automticamente un ndice. A
menos que especifiquemos otra cosa, este ndice ser creado en el mismo tablespace que el de la tabla, y usar
los parmetros de almacenamiento por defecto. Ya que esta localizacin de almacenamiento es normalmente
indeseable, deberamos usar la clusula USING INDEX al crear la clave primaria o restriccin de unicidad.
La clusula USING INDEX permite especificar parmetros de almacenamiento y ubicacin de tablespace para el
ndice creado. En el siguiente ejemplo, se crea la clave primaria de la tabla Biblioteca y se ubica en el tablespace
B_Indices. Este ejemplo asume que no existe un ndice sobre las columnas especificadas.
ALTER TABLE Biblioteca
ADD CONSTRAINT B_PK PRIMARY KEY (Titulo, Autor)
USING INDEX TABLESPACE B_Indices;
3.8.6. Eliminar ndices.
La instruccin DROP INDEX seguida del nombre del ndice permite eliminar el ndice en cuestin. Por ejemplo,
para eliminar el ndice llamado B_PK:
DROP INDEX B_PK;
3.8.7. Reconstruir un ndice.
Oracle proporciona una capacidad rpida de reconstruir ndices, que permite recrear un ndice sin tener que
eliminarlo. Esta capacidad permite usar el ndice existente como origen de datos para el ndice reconstruido,
en vez de usar la tabla como origen de datos. Durante la reconstruccin del ndice podemos cambiar los
parmetros de almacenamiento y el tablespace asignado.
En el siguiente ejemplo, el ndice B_PK se reconstruye, y se cambian sus parmetros de almacenamiento para
usar una extensin de tamao inicial de 8MB y un nuevo tamao de extensin de 4MB, en el tablespace
B_Indices.
ALTER INDEX B_PK REBUILD
STORAGE (INITIAL 8M NEXT 4M PCTINCREASE 0)
TABLESPACE B_Indices;

Nota. Cuando se reconstruye el ndice B_PK, debemos tener espacio suficiente para ambos ndices, el
antiguo y el nuevo. Despus de que el nuevo ndice es creado, el antiguo se elimina.
Cuando creamos un ndice basado en columnas previamente indexadas, Oracle puede ser capaz de usar los
ndices existentes como origen de datos para el nuevo ndice. El optimizador de Oracle puede usar parte de
un ndice compuesto existente cuando sea necesario en consultas, as que podemos no necesitar crear muchos
ndices para soportar la mayora de consultas.
Podemos reconstruir ndices mientras estn siendo accedidos, usando la clusula REBUILD ONLINE del
comando ALTER INDEX.
3.8.8. ndices basados en funciones.
Podemos crear ndices basados en funciones. Cualquier consulta que realice una funcin sobre una columna
generalmente no usa el ndice de esta columna. Por lo tanto, la siguiente consulta podra no usar un ndice
sobre la columna Titulo:
SELECT * FROM Biblioteca WHERE UPPER(Titulo) = 'La Fundacin';
Podemos crear ndices que permitan accesos basados en funciones que soporten acceso por ndices. En vez

Oracle /63
de crear un ndice sobre la columna Titulo, podemos crear un ndice sobre la expresin UPPER(Titulo), tal como
se muestra a continuacin:
CREATE INDEX Biblioteca$UPPER_Titulo
ON Biblioteca (UPPER(Titulo));
Aunque los ndices basados en funciones pueden ser tiles, debemos considerar las siguientes cuestiones
antes de crearlos:
Podemos determinar de antemano todas las funciones que sern usadas sobre la columna?
Tenemos el espacio de almacenamiento adecuado para los ndices adicionales?
Cuando eliminamos la tabla se eliminarn todos sus ndices. Cmo impacta al tiempo requerido para
eliminar la tabla?
Los ndices basados en funciones son tiles, pero deberamos usarlos con moderacin. Cuantos ms ndices
creemos sobre una tabla, ms largas sern las operaciones de insercin, actualizacin y borrado.
3.8.9. Lista de ndices.
Para ver la lista de ndices se utiliza la vista USER_INDEXES. Mientras que la vista USER_IND_COLUMNS
muestra la lista de columnas que son utilizadas por ndices.
3.8.10. Creacin de tablas organizadas por ndice.
Una tabla organizada por ndice guarda sus registros ordenados segn los valores de la clave de la tabla, y
almacena los datos como si la tabla entera fuese almacenada en un ndice. Un ndice normal slo almacena las
columnas del ndice; una tabla organizada por ndice almacena todas las columnas en el ndice.
Para crear una tabla organizada por ndice, se usa la clusula ORGANIZATION INDEX, como en el siguiente
ejemplo:
CREATE TABLE Empleado (
Nombre VARCHAR2(13),
Apellidos VARCHAR2(30),
Fecha_Nacimiento DATE,
CONSTRAINT Empleado_PK PRIMARY KEY (Nombre, Apellidos)
) ORGANIZATION INDEX;
Para crear la tabla organizada por ndice, hay que crear primero una restriccin de clave primaria. Esta tabla
Empleado es apropiada para ser organizada por ndice si siempre accedemos a los datos filtrndolos por
nombre y apellidos. Para minimizar la cantidad de actividad requerida para gestionar el ndice, deberamos
usar esta opcin slo si los datos de la tabla son muy estticos. Si los datos de la tabla cambian
frecuentemente, deberamos usar ndices normales.
En general, una tabla organizada por ndice es ms efectiva cuando la clave primaria est formada por muchas
columnas de la tabla. Si la tabla contiene muchos accesos a columnas que no son parte de la clave primaria, la
tabla necesitar repetidamente acceder al rea de desbordamiento. A pesar de esta desventaja, podemos
decidir usar tablas organizadas por ndice para aprovechar una caracterstica importante que no est
disponible con las tablas estndar: la capacidad de usar la opcin MOVE ONLINE del comando ALTER TABLE.
Se puede usar esta opcin para mover una tabla desde un tablespace a otro mientras est siendo accedida por
operaciones de insercin, actualizacin o borrado. No se puede usar esta la opcin MOVE ONLINE para tablas
particionadas organizadas por ndice.
3.9. Uso de tablas particionadas.
Podemos distribuir las filas de una misma tabla en varias partes. Dividir los datos de una tabla de esta manera
es lo que se conoce como particionado de tabla; la tabla que es particionada se llama tabla partida, y las partes
se denominan particiones.
El particionado en habitual en tablas muy grandes. Al distribuir las filas de una tabla grande en varias
particiones pequeas conseguimos varios objetivos importantes:
El rendimiento de las consultas sobre las tablas puede mejorar porque Oracle puede tener que buscar
solo en una particin en vez de en la tabla entera para resolver la consulta.
La tabla puede ser ms fcil de administrar. Puede ser ms fcil cargar y eliminar datos de las particiones
que de la tabla entera.
Las operaciones de copias de respaldo y recuperacin pueden realizarse mejor. Debido a que las
particiones son ms pequeas que la tabla particionada, podemos tener ms opciones para copiar y
recuperar las particiones que para toda la tabla.
El optimizador de Oracle sabr que una tabla est particionada; y podremos especificar la particin a usar en
una consulta.

Oracle /64
3.9.1. Crear una tabla particionada.
Para crear una tabla particionada debemos especificar cmo establecer las particiones de los datos de la tabla
como parte del comando CREATE TABLE. Normalmente las tablas son divididas por rangos de valores
(conocido como el rango de la particin).
Consideremos una tabla Biblioteca:
CREATE TABLE Biblioteca (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(20),
Categoria VARCHAR2(20) );
Si almacenamos un gran nmero de registros en la tabla Biblioteca, podemos querer separara los registros
entre varias particiones. Para dividir los registros se usa la clusula PARTITION BY RANGE en el comando
CREATE TABLE, tal como se muestra a continuacin. Los rangos determinarn los valores almacenados en cada
coleccin.
CREATE TABLE Biblioteca_Partida (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(20),
Categoria VARCHAR2(20) )
PARTITION BY RANGE (Categoria) (
PARTITION Parte1 VALUES LESS THAN ('B') TABLESPACE Parte1_TS,
PARTITION Parte2 VALUES LESS THAN (MAXVALUE) TABLESPACE Parte2_TS );
En este ejemplo, la tabla Biblioteca_Partida ser particionada segn el valor de lacolumna Categoria. Para
categoras cuyo nombre sea menor que 'B' (por ejemplo la categora 'ADULTO'), los registros sern
almacenados en la particin llamada Parte1, que ser almacenada en el tablespace Parte1_TS. Cualquier otra
categora ser almacenada en la particin Parte2. En este ltimo caso no necesitamos especificar un valor
mximo; la palabra clave MAXVALUE le dir a Oracle que use la particin para almacenar cualquier dato que no
haya sido almacenado en las otras particiones. Si queremos crear ms particiones debemos especificar en cada
una de ellas un valor mximo de rango, de forma que el valor mnimo del rango queda determinado por la
definicin de la particin previa.
Adems de particiones de rango, Oracle tambin soporta particiones de hash. Una particin de hash
determina la ubicacin fsica de los datos aplicando una funcin de hash sobre los valores de la clave de la
particin. En particiones de rango, valores consecutivos de la clave son normalmente almacenados en la
misma particin. En particiones de hash, valores consecutivos de la clave no son normalmente almacenados
en la misma particin; sino que distribuye un conjunto de registros sobre un conjunto mayor de particiones,
decrementando potencialmente la probabilidad de contenciones de entrada/salida en los accesos a disco.
Para crear una particin de hash se usa la clusula PARTITION BY HASH en vez de la clusula PARTITION BY
RANGE, tal como se muestra en el siguiente ejemplo:
CREATE TABLE Biblioteca_Hash (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(20),
Categoria VARCHAR2(20) )
PARTITION BY HASH (Categoria)
PARTITIONS 10;
Podemos nombrar cada particin y especificar su tablespace con el siguiente aadido:
...
PARTITION BY HASH (Categoria)
PARTITIONS 2
STORE IN (Parte_TS, Parte2_TS);
Despus de la lnea PARTITION BY HASH (Categoria),
tenemos dos opciones de formato:
Tal como se muestra en el ejemplo previo, podemos especificar el nmero de particiones y los
tablespaces a usar:
PARTITIONS 2
STORE IN (Parte_TS, Parte2_TS);
Este mtodo crear particiones con nombres generados por el sistema con el formato SYS_Pnnn, donde nnn
es un nmero secuencial. El nmero de tablespaces especificados en la clusula STORE IN no tiene que ser
igual al nmero de particiones. Si especificamos ms tablespaces, las particiones sern asignadas a los
tablespaces segn un algoritmo rotatorio "round-robin".

Oracle /65
Podemos especificar el nombre de las particiones:
PARTITION BY HASH (Categoria) (
PARTITION Parte1 TABLESPACE Parte1_TS,
PARTITION Parte2 TABLESPACE Parte2_TS);
3.9.2. Particiones de lista.
Podemos usar particiones de lista en lugar de particiones de rango y de hash. En las particiones de lista se le
dan a Oracle todos los posibles valores y se especifica la particin en la cual guardar los registros
correspondientes a cada valor de la lista. El siguiente ejemplo muestra otra versin de la tabla Biblioteca
particionada por un lista con los posibles valores de categora.
CREATE TABLE Biblioteca_LIST (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(20),
Categoria VARCHAR2(20) )
PARTITION BY LIST (Categoria) (
PARTITION Parte1 VALUES ('ADULTO') TABLESPACE Parte1_TS,
PARTITION Parte2 VALUES ('JOVEN', 'NIO') TABLESPACE Parte2_TS);
3.9.3. Crear subparticiones.
Tambin podemos crear subparticiones; esto es, particiones de particiones. Podemos usar subparticiones para
combinar dos tipos de particiones: de rango y de hash. Podemos usar particiones de hash en combinacin
con particiones de rango, creando particiones de hash en cada particin de rango. Para tablas muy grandes,
esta combinacin de particiones puede ser un modo efectivo de separar datos en divisiones manejables.
El siguiente ejemplo particiona por rango la tabla Biblioteca segn el autor, y particiona por hash cada
particin de autor por los valores de categora:
CREATE TABLE Biblioteca_RANGE_HASH (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(20),
Categoria VARCHAR2(20) )
PARTITION BY RANGE (Autor)
SUBPARTITION BY HASH (Categoria)
SUBPARTITIONS 3 (
PARTITION Parte1 VALUES LESS THAN ('M') TABLESPACE Parte1_TS,
PARTITION Parte2 VALUES LESS THAN (MAXVALUE) TABLESPACE Parte2_TS );
La tabla ser particionada por rango en dos particiones, usando el valor de autor para cada rango. Cada una
de estas dos particiones ser particionada en 3 por hash segn la categora.
3.9.4. Indexacin de las particiones.
Cuando creamos una tabla particionada debemos crear un ndice en la tabla. El ndice puede ser particionado
de acuerdo al mismo rango de valores usados para particionar la tabla. En el siguiente ejemplo, se muestra
cmo crear un ndice basado en la categora para la tabla Biblioteca particionada. Cada ndice particionado es
ubicado en los tablespaces Parte1_NDX_TS y Parte2_NDX_TS.
CREATE INDEX Biblioteca_LIST_Categoria
ON Biblioteca_LIST (Categoria)
LOCAL (
PARTITION Parte1 TABLESPACE Parte1_NDX_TS,
PARTITION Parte2 TABLESPACE Parte2_NDX_TS );
Ntese la palabra clave LOCAL. En el comando CREATE INDEX no se especifican los rangos; sino que la
palabra clave LOCAL le dice a Oracle que cree un ndice separado por cada particin de la tabla Biblioteca_LIST.
En este caso, como hay dos particiones en la tabla, el ndice crea dos particiones de ndices independientes
(uno por cada particin de la tabla). Debido a que hay un ndice por particin se dice que las particiones de
ndice son "locales".
Tambin podemos crear ndices "globales". Un ndice global puede contener valores de varias particiones de
la tabla. Por ejemplo:
CREATE INDEX Biblioteca_LIST_Categoria_G
ON Biblioteca_LIST (Autor)
GLOBAL;
La clusula GLOBAL de este comando CREATE INDEX permite crear un ndice no particionado (tal como se
hace por el campo autor), o especificar rangos para los valores de ndice que son diferentes de los rangos de

Oracle /66
las particiones. Los ndices locales son ms fciles de administrar que los globales; sin embargo, los ndices
globales pueden realizar verificaciones de unicidad ms rpido que los ndices locales.
Nota. No podemos crear ndices globales para particiones de hash o subparticiones.
3.9.5. Administrar tablas particionadas.
Podemos usar el comando ALTER TABLE para aadir (ADD), eliminar (DROP), cambiar (EXCHANCE), mover
(MOVE), renombrar (RENAME), dividir (SPLIT) y truncar (TRUNCATE) particiones. Estas opciones del comando
ALTER TABLE permiten alterar la estructura de particin existente, lo cual puede ser requerido despus de que
una tabla particionada haya sido usada intensivamente. Por ejemplo, la distribucin de valores del campo
Categora de la tabla particionada Biblioteca pueden cambiar, o el valor mximo puede incrementarse.
Durante una insercin dentro de la tabla particionada, Oracle usa las definiciones de las particiones para
determinar en qu particin debe insertarse el nuevo registro. As, podemos usar una tabla particionada como
si fuese una tabla normal, y confiar en Oracle para administrar la separacin interna de los datos.
3.10. Clsteres (o cubos).
El "clustering" es un mtodo de almacenar tablas que estn relacionadas ntimamente y normalmente unidas
en la misma rea de disco. Por ejemplo, podemos tener una tabla Libro y una tabla Autor relacionadas dentro
de una misma rea de disco. Esta rea se denomina clster o cubo.
La clave de clster es la columna o columnas a travs de las cuales las tablas son normalmente combinadas en
una consulta (por ejemplo, las tablas Libro y Autor pueden tener ambas una columna idAutor). Para crear
clsteres en tablas debemos ser propietarios de las tablas. El formato bsico del comando CREATE CLUSTER es
el siguiente:
CREATE CLUSTER nombreCluster
(columna tipoDeDato [, columna tipoDeDato] . . . ) [otras opciones];
Despus del nombre del clster le sigue la convencin de nombrado para definir columnas con su tipo de
dato, las cuales definirn la clave del clster. El nombre de las columnas puede corresponderse con una de las
columnas de una tabla, o puede ser cualquier otro nombre vlido. Por ejemplo:
CREATE CLUSTER LibroAutor (Col1 INT);
Esto crea un clster vaco. El uso de Col1 en la clave del clster es irrelevante; nunca se volver a usar. Sin
embargo, esta definicin debera casar con la clave primaria de la tabla que ser aadida. A continuacin
creamos las tablas que sern incluidas en este clster.
CREATE TABLE Autor (
IdAutor INT PRIMARY KEY,
Nombre VARCHAR2(100) )
CLUSTER LibroAutor (idAutor);
Antes de insertar filas dentro de Autor, debemos crear un ndice de clster:
CREATE INDEX LibroAutorNDX
ON CLUSTER LibroAutor;
Recalcar que la presencia de una clusula CLUSTER aqu excluye el uso de una clusula TABLESPACE o
STORAGE. Ntese cmo esta estructura difiere del comando estndar de creacin de tablas, donde al final se
indica el nombre del clster, LibroAutor, donde se almacenar la tabla, y entre parntesis se indica la columna,
idAutor, de la tabla que ser almacenada en la clave del clster, Col1.
Es posible tener varias claves de clster y tener varias columnas almacenadas en estas claves. La lista de
columnas se har corresponder por orden con la lista de claves.
Ahora aadimos una segunda tabla al clster:
CREATE TABLE Libro (
IdLibro INT PRIMARY KEY,
Titulo VARCHAR2(100),
IdAutor INT REFERENCES Autor(idAutor) )
CLUSTER LibroAutor (idAutor);
Cuando estas dos tablas son almacenadas en el clster, cada id de autor es almacenado una sola vez en la clave
del clster. Cada una de estas claves es asociada a las columnas de ambas tablas, Autor y Libro. Los datos de
ambas tablas son almacenados en una nica localizacin, casi como si el clster fuese una gran tabla que
contuviese los datos de las tablas involucradas.
Una opcin adicional, HASH CLUSTER, usa los valores de las columnas del clster para determinar la ubicacin
fsica en la cual son almacenados los registros. La sintaxis para esta opcin es la siguiente:

Oracle /67
CREATE CLUSTER nombreCluster
(columnatipoDeDato, . . . ) HASH IS columna;
3.11. Secuencias.
Una secuencia sirve para generar automticamente nmeros distintos. Son tiles para generar valores en
campos que se utilizan como clave forzada (claves cuyo valor no interesa, slo sirven para identificar los
registros de una tabla). Es decir, se utilizan en los identificadores de las tablas (campos que comienzan con la
palabra id), siempre y cuando no importe qu nmero se asigna a cada fila.
Es una rutina interna de la base de datos la que realiza la funcin de generar un nmero distinto cada vez. Las
secuencias se almacenan independientemente de la tabla, por lo que la misma secuencia se puede utilizar para
diversas tablas.
3.11.1. Creacin de secuencias.
La sintaxis para crear una secuencia es la siguiente:
CREATE SEQUENCE nombre_secuencia
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n|NOMAXVALUE}]
[{MINVALUE n|NOMINVALUE}]
[{CYCLE|NOCYCLE}]
[{CACHE n|NOCACHE}
Donde:
INCREMENT BY, indica cunto se incrementa la secuencia cada vez que se usa. Por defecto se incrementa de
uno en uno.
START WITH, indica el valor inicial de la secuencia (por defecto 1).
MAXVALUE, es el mximo valor que puede tomar la secuencia. Sino se toma NOMAXVALUE, que permite
llegar hasta el 1027.
26
MINVALUE, es el mnimo valor que puede tomar la secuencia. Por defecto -10 .
CYCLE, hace que la secuencia vuelva a empezar si se ha llegado al mximo valor.
NOCYCLE, (valor por defecto) hace que la secuencia no vuelva a empezar si se ha llegado al mximo valor.
CACHE, especifica cuntos valores de la secuencia sern almacenados en la memoria para accesos rpidos.
El valor asignado debe ser menor que el valor de INCREMENT BY.
NOCACHE, (valor por defecto) especifica que no se almacenen valores en la memoria.

Nota. Si el sistema falla, todos los valores almacenados en cach se perdern y no sern usados
cuando se restaure el sistema. Para recuperar la secuencia de valores perdidos podemos usar el
comando ALTER SEQUENCE para reiniciar el contador al valor correcto.
Un ejemplo de creacin de una secuencia es el siguiente.
CREATE SEQUENCE numeroPlanta
INCREMENT 100 STARTS WITH 100 MAXVALUE 2000;
3.11.2. Para ver la lista de secuencias.
La vista del diccionario de datos USER_SEQUENCES muestra la lista de secuencias del usuario actual. La
columna LAST_NUMBER muestra cul ser el siguiente nmero de secuencia disponible.
3.11.3. Uso de la secuencia.
Los mtodos NEXTVAL y CURRVAL se utilizan para obtener el siguiente nmero y el valor actual de la secuencia
respectivamente. Un ejemplo de uso es el siguiente:
SELECT numeroPlanta.NEXTVAL FROM DUAL;
Eso muestra en pantalla el siguiente valor de la secuencia. Realmente NEXTVAL incrementa la secuencia y
devuelve el valor actual. CURRVAL devuelve el valor de la secuencia, pero sin incrementar la misma.
Ambas funciones pueden ser utilizadas en:
- Una consulta SELECT que no lleve DISTINCT, ni grupos, ni sea parte de una vista, ni sea subconsulta de
otro SELECT, UPDATE o DELETE.
- Una subconsulta SELECT en una instruccin INSERT.
- La clusula VALUES de la instruccin INSERT.
- La clusula SET de la instruccin UPDATE.
No se puede utilizar (y siempre hay tentaciones para ello) como valor para la clusula DEFAULT de un campo
de tabla.

Oracle /68
Su uso ms habitual es como apoyo al comando INSERT:
INSERT INTO plantas (num, uso) VALUES (numeroPlanta.NEXTVAL, 'Suites');
3.11.4. Modificar secuencias.
Se pueden modificar las secuencias, pero la modificacin slo puede afectar a los futuros valores de la
secuencia, no a los ya utilizados. Se usa el comando ALTER SEQUENCE para ello:
ALTER SEQUENCE secuencia
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n|NOMAXVALUE}]
[{MINVALUE n|NOMINVALUE}]
[{CYCLE|NOCYCLE}]
3.11.5. Borrar secuencias.
Se pueden eliminar secuencias con el comando DROP SEQUENCE seguido del nombre de la secuencia a borrar.
Por ejemplo:
DROP SEQUENCE numeroPlanta;
3.12. Sinnimos.
Un sinnimo es un nombre que se asigna a un objeto cualquiera. Normalmente es un nombre menos
descriptivo que el original, a fin de facilitar la escritura del nombre del objeto en diversas expresiones.
3.12.1. Creacin.
Se crea un sinnimo con la siguiente sintaxis:
CREATE [PUBLIC] SYNONYM nombre FOR objeto;
Donde objeto es el objeto al que se referir el sinnimo. La clusula PUBLIC hace que el sinnimo est
disponible para cualquier usuario de la base de datos. Slo se permite utilizar la clusula PUBLIC si disponemos
de privilegios administrativos.
Nota. Los sinnimos pblicos se crean a nivel de la base de datos, por tanto no pueden existir dos
sinnimos pblicos con el mismo nombre en una base de datos.
Por ejemplo, si el usuario Andres tiene una tabla llamada VENTAS, y quiere que otros usuarios que tienen
permiso de acceso a dicha tabla puedan utilizar un nombre ms corto en vez de Andres.VENTAS, puede crear
el siguiente sinnimo:
CREATE PUBLIC SYNONYM VENTAS FOR Andres.VENTAS;
De esta forma, si el usuario Juan tiene permisos de consulta sobre la tabla VENTAS, podr consultarla desde su
cuenta con el siguiente comando:
SELECT * FROM VENTAS;
3.12.2. Borrar sinnimos.
Se puede eliminar un sinnimo con el comando DROP SYNONYM seguido del nombre del sinnimo.
DROP SYNONYM sinnimo;
3.12.3. Lista de sinnimos.
La vista USER_SYNONYMS permite observar la lista de sinnimos del usuario actual, y la vista ALL_SYNONYMS
permite mostrar la lista completa de sinnimos de toda la base de datos.
3.13. Insercin de registros.
Para insertar un nuevo registro o tupla en una tabla se utiliza la instruccin INSERT con la siguiente sintaxis:
INSERT
INTO nombre-tabla [ ( campo1 [ , campo2] ] ]
VALUES ( valor1 [ , valor2 ] ] ;
El orden del listado de campos puede ser arbitrario e incluso pueden omitirse los nombres de campos que
admitan valores nulos o valores por defecto. Si se omite el listado de campos se considerar una referencia a
todos los campos en el orden en que fueron listados en la creacin de la tabla.
El listado de valores debe corresponderse con el orden del listado de campos. Al crear un registro donde se
omita un campo que admita un valor por defecto o un valor nulo, se insertar el valor por defecto o el valor
NULL en dicho campo.
En el siguiente ejemplo, insertaremos un nuevo registro de Empleado:
INSERT
INTO Empleado (Nombre, Apellidos, Fecha_Nacimiento)
VALUES ('Juan', 'Prez Prez', '2/10/1960');

Oracle /69
Para insertar valores por defecto, tambin podemos forzar a que la insercin se realice con los datos por
defecto establecidos para la tabla (o NULL si no tienen valores por defecto).
INSERT INTO Empleado DEFAULT VALUES
3.13.1. Inserciones a partir de una consulta.
Podemos realizar varias inserciones con un comando INSERT, siempre que los datos procedan de una
consulta. En este caso, la sintaxis del comando es la siguiente:
INSERT
INTO nombre-tabla [ ( campo1 [ , campo2] ] ]
Consulta ;
Donde Consulta debe ser sustituida por un comando SELECT que proporcione un valor para cada campo
especificado en al insercin.
Por ejemplo, si tenemos dos tablas Empleado y Temp con el mismo esquema, podemos poblar la tabla Temp con
los datos de aquellos empleados cuya fecha de nacimiento sea anterior a 1980.
INSERT
INTO Temp (Nombre, Apellidos, Fecha_Nacimiento)
SELECT Nombre, Apellidos, Fecha_Nacimiento
FROM Empleado
WHERE EXTRACT(Year FROM Fecha_Nacimiento) < 1980;
3.13.2. Uso del indicador APPEND para mejorar el rendimiento de inserciones.
Oracle usa un optimizador para determinar el modo ms eficiente de realizar cada comando SQL. Para los
comandos de insercin, Oracle intenta insertar cada nuevo registro dentro de un bloque de datos existente ya
asignado a la tabla. Este plan de ejecucin optimiza el uso del espacio requerido para almacenar los datos. Sin
embargo, esto puede afectar al rendimiento adecuado cuando insertemos varios registros en un mismo
comando (usando una consulta). Podemos corregir el plan de ejecucin usando el indicador APPEND para
mejora el rendimiento de inserciones con procesos largos. El indicador APPEND le dice a la base de datos que
encuentre el ltimo bloque de la tabla del cual se hizo una insercin. Los nuevos registros sern insertados a
partir del siguiente bloque despus del ltimo previamente usado. Adems, los datos insertados son escritos
directamente a los ficheros de datos, evitando la cach de datos. Por consiguiente, durante la insercin hay
mucho menos trabajo de administracin del espacio para la base de datos para hacer. Por lo tanto, la
insercin puede ser completada ms rpido cuando se usa el indicador APPEND.
Se especifica el indicador APPEND con la siguiente sintaxis:
INSERT /*+ APPEND */ INTO Nombre_Tabla . . .
Debido a que los nuevos registros no reutilizan el espacio disponible ya usado por la tabla, los requerimientos
para la tabla se incrementan. En general, slo deberamos usar el indicador APPEND cuando insertamos un
gran volumen de datos dentro de tablas con un espacio reutilizado pequeo.
El punto en el cual los registros aadidos son insertados se llama la "gran marca de agua" de la tabla, y el
nico modo de reinicializar esta marca es truncando la tabla con el comando TRUNC. Debido a que truncar
una tabla elimina todos los registros de forma que ya no pueden ser recuperados, deberamos asegurarnos de
hacer una copia de seguridad de la tabla antes de realizar la operacin de truncado.
3.13.3. Inserciones multitabla.
Es posible tambin realizar varias inserciones sobre tablas distintas en un mismo comando. En estos casos
podemos hacer inserciones incondicionales o podemos especificar condiciones.
Para ilustrar esto, supongamos las siguientes tablas:
Tabla Temperaturas Tabla Temp Tabla TempC
Metal Celsius Fahrenheit Metal Escala Valor Metal Valor
Hierro -18 -2
Plata 12,5 54 Tabla TempF
Cobre -9,8 14 Metal Valor
Oro 14,4 57

La tabla Temperaturas almacena valores de temperatura para varios metales tanto para la escala Celsius como
para escala Fahrenheit. Se pretende poblar la tabla Temp con los registros de Temperaturas, pero especificando
en cada fila un nico valor de temperatura y la escala utilizada (Celsius o Fahrenheit). De esta forma, la tabla
Temp tendr dos filas por cada registro de la tabla Temperaturas.
El comando para poblar Temp con los datos de Temperaturas de forma incondicional es especificando la

Oracle /70
clusula ALL con INSERT:
INSERT ALL
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Celsius', Celsius)
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Fahrenheit', Fahrenheit)
SELECT Metal, Celsius, Fahrenheit FROM Temperaturas
Esta consulta le dice a Oracle que por cada registro procedente de la consulta SELECT realice dos inserciones
(especificadas con cada INTO). La consulta retorna 4 registros, cuyos valores se utilizan para ambas
inserciones; pero en la primera insercin se especifica el literal 'Celsius' para el campo Escala, mientras que en
la segunda insercin se especifica el literal 'Fahrenheit' para el campo Escala. Como resultado, la tabla Temp se
puebla con los siguientes datos:
Metal Escala Valor
Hierro Celsius -18
Plata Celsius 12,5
Cobre Celsius -9,8
Oro Celsius 14,4
Hierro Fahrenheit -2
Plata Fahrenheit 54
Cobre Fahrenheit 14
Oro Fahrenheit 57
Pero si ahora queremos poblar la tabla TempC con las temperaturas en Celsius y la tabla TempF con las
temperaturas en Fahrenheit, tambin podemos hacerlo:
INSERT ALL
INTO TempC (Metal, Valor) VALUES (Metal, Celsius)
INTO TempF (Metal, Valor) VALUES (Metal, Fahrenheit)
SELECT Metal, Celsius, Fahrenheit FROM Temperaturas
Para realizar inserciones mltiples condicionadas debemos combinar la clusula ALL con la clusula WHEN.
Por ejemplo, al poblar la tabla Temp restringiremos los valores de temperatura a solo valores positivos
(independientemente de la escala).
INSERT ALL
WHEN Celsius >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Celsius', Celsius)
WHEN Fahrenheit >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Fahrenheit', Fahrenheit)
SELECT Metal, Celsius, Fahrenheit FROM Temperaturas
En este caso, como resultado, la tabla Temp se puebla con los siguientes datos:
Metal Escala Valor
Plata Celsius 12,5
Oro Celsius 14,4
Plata Fahrenheit 54
Cobre Fahrenheit 14
Oro Fahrenheit 57
Si en vez de ALL se utiliza la clusula FIRST, slo se insertar como mximo una fila por registro a travs de la
insercin que primero cumpla la condicin de su respectivo WHEN. De esta forma, el comando siguiente:
INSERT FIRST
WHEN Celsius >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Celsius', Celsius)
WHEN Fahrenheit >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Fahrenheit', Fahrenheit)
SELECT Metal, Celsius, Fahrenheit FROM Temperaturas
Produce como resultado:
Metal Escala Valor
Plata Celsius 12,5
Oro Celsius 14,4
Cobre Fahrenheit 14
Aunque las filas (Plata, Fahrenheit, 54) y (Oro, Fahrenheit, 57) cumplen la condicin de insercin para el segundo
Oracle /71
WHEN, los registros de los cuales proceden ya produjeron una insercin a travs del primer WHEN, y por ello
no son enviados a la tabla Temp.
Con INSERT FIRST podemos subordinar varios INTO a una misma condicin:
INSERT FIRST
WHEN Celsius >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Celsius', Celsius)
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Celsius', -Celsius)
WHEN Fahrenheit >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Fahrenheit', Fahrenheit)
SELECT Metal, Celsius, Fahrenheit FROM Temperaturas
En este ejemplo previo, si un registro de Temperaturas cumple con la primera condicin (Celsius >= 0) se
insertarn dos registros en la tabla Temp: uno con el valor positivo, y otro con el valor negativo.
Por ltimo, podemos tambin especificar una clusula ELSE para realizar inserciones en otra tabla si un
registro de la consulta no cumple con ninguna condicin de los WHEN. Como ejemplo, supongamos la
existencia de una tercera tabla, Temperaturas2, con el mismo esquema que la tabla Temperaturas. El siguiente
comando:
INSERT ALL
WHEN Celsius >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Celsius', Celsius)
WHEN Fahrenheit >= 0 THEN
INTO Temp (Metal, Escala, Valor) VALUES (Metal, 'Fahrenheit', Fahrenheit)
ELSE
INTO Temperaturas2
SELECT Metal, Celsius, Fahrenheit FROM Temperaturas
Produce como resultado que la tabla Temperaturas2 se pueble con los registros de Temperaturas que no
provocaron una insercin en Temp:
Metal Celsius Fahrenheit
Hierro -18 -2

3.14. Actualizacin de registros.


Para modificar los valores en un registro se utiliza la instruccin UPDATE con la siguiente sintaxis:
UPDATE nombre-tabla
SET campo = expresin-escalar
[ , campo = expresin_escalar ] . . .
[ WHERE condicin ]
Todos los registros que cumplan la condicin sern actualizados de acuerdo con las asignaciones. Si no se
especifica una condicin todos los registros de la tabla sern modificados.
En el siguiente ejemplo modificaremos un solo registro. En este caso cambiaremos el nombre y apellidos del
empleado con ID 7:
UPDATE Empleado
SET Nombre = 'Jos Lus' ,Apellidos = 'Serantes Garca'
WHEREID =7
3.15. Eliminacin de registros.
Para eliminar registros se utiliza la instruccin DELETE con la siguiente sintaxis:
DELETE
FROM nombre_tabla
[ WHERE condicin ] ;
Si se omite la condicin se borrarn todos los registros de la tabla indicada.
En el siguiente ejemplo se elimina un solo registro. En este caso, el empleado de ID 10:
DELETE
FROM Empleado WHERE ID = 10
Para eliminar todos los registros de una tabla se puede hacer de dos maneras:
DELETE FROM Empleado;
TRUNCATE TABLE Empleado;
Siendo la instruccin TRUNCATE ms rpida.

Oracle /72
3.16. Combinar registros con MERGE.
Oracle proporciona la instruccin MERGE para actualizar (UPDATE) o insertar (INSERT) registros en una misma
operacin dependiendo de alguna condicin. Los datos para actualizar o insertar deben provenir de una tabla
o consulta diferente a la tabla que se quiere actualizar.
MERGE es una instruccin determinista, esto es, no permite actualizar el mismo registro en la tabla destino
varias veces.
Como ejemplo, supongamos las siguientes tablas con datos insertados:
ID Nombre ID Nombre Saldo
Tabla "Persona" 1 Juan Prez Tabla "Cliente" 2 Mara Lpez 10000
2 Mara Lpez 4 Jos Prez 90000
3 Ramn Llull 6 Javier Llull 15000
4 Jos Prez

La siguiente instruccin modifica la tabla Cliente segn los registros de la tabla Persona:
MERGE INTO Cliente C
USING (SELECT ID, Nombre FROM Persona) P ON (C.ID = P.ID)
WHEN MATCHED THEN UPDATE SET C.Saldo = C.Saldo + 200
DELETE WHERE (C.Saldo > 80000)
WHEN NOT MATCHED THEN INSERT (C.ID, C.Nombre, C.Saldo)
VALUES (P.ID, P.Nombre, 100);
Realiza inserciones, actualizaciones y borrados de registros en la tabla "Cliente" segn las siguientes
condiciones:
- Se incrementa en 200 unidades el saldo de los registros de Cliente si existe un registro de Persona con el
mismo ID.
- Se eliminan los registros de Cliente con un saldo superior a 80000 unidades, siempre que sea uno de los
registros que se iba a actualizar. Es decir, el ID del registro a eliminar debe corresponderse con un registro
de la tabla Persona.
- En la tabal Cliente se insertan aquellos registros de la tabla Persona cuyos ID's todava no existen en la
tabla Cliente, y se les asigna un saldo inicial de 100 unidades.
Como resultado de esta instruccin, el contenido de la tabla Cliente ser el siguiente:
ID Nombre Saldo
Tabla "Cliente" 1 Juan Prez 100
modificada 2 Mara Lpez 10200
3 Ramn Llull 100
6 Javier Llull 15000

4. Consultas de seleccin
Las consultas de seleccin se utilizan para indicar al motor de base de datos que devuelva informacin de una
o varias tablas; esta informacin es devuelta en forma de un conjunto de registros que, en un programa java,
se pueden manipular mediante un objeto ResultSet.
Este captulo se ilustrar con ejemplos de consultas basadas en la base de datos representada en la siguiente
figura:

Oracle /73
ALUMNO NOTA
1
1
nif idNota
nombre n valor
n MODULO
apellidos nif
localidad idModulo 1
idModulo
nombre
MATRICULA FALTA 1
1
n idMatricula idFalta
nif n fecha
ao idMatricula n
idModulo

ESQUEMA DE LA BASE DE DATOS USADA PARA LOS EJEMPLOS

4.1. Consultas bsicas.


La sintaxis bsica de una consulta de seleccin es la siguiente:
SELECT campos FROM Tabla;
En donde campos es la lista de campos o columnas que se desean recuperar y tabla es el origen de los mismos.
Por ejemplo, la consulta
SELECT nombre, apellidos FROM Alumno;
devuelve un conjunto de registros con dos columnas: los valores de nombre y apellidos de la tabla Alumno. El
resultado podra ser algo como lo siguiente:
NOMBRE APELLIDOS
----------------- --------------------------
Juan Martnez Pan
Marian Lpez Sobrado
Por regla general, las columnas del resultado son asociadas con un nombre igual al de la expresin
especificada en el comando SELECT.
4.2. Alias.
En determinadas circunstancias es necesario asignar un nombre concreto a alguna columna de un conjunto
devuelto; otras veces se hace por simple capricho o por otras circunstancias. Para resolver esto se dispone de
la palabra reservada AS, que se encarga de asignar el nombre concreto a la columna deseada. Como ejemplo,
podemos hacer una consulta que retorne una columna con los apellidos de alumnos, pero en lugar de llamarse
apellidos (igual que el campo devuelto) se llame Alumno. En este caso procederamos de la siguiente forma:
SELECT apellidos AS Alumno FROM Alumno; -- o bien:
SELECT apellidos Alumno FROM Alumno; -- no es necesaria la palabra AS
Si queremos asignar un alias que incluya espacios en blanco o caracteres especiales, debemos escribir el alias
entre comillas dobles:
SELECT apellidos AS "Apellidos del alumno" FROM Alumno;
4.3. Ordenar los registros.
Adicionalmente se puede especificar el orden en que se desean recuperar los registros de las tablas mediante
la clusula ORDER BY. Ejemplo:
SELECT nif, nombre, apellidos FROM Alumno ORDER BY apellidos;
Esta consulta devuelve los campos nif, nombre, y apellidos de la tabla Alumno ordenados por el campo apellidos.
Se pueden ordenar los registros por ms de un campo, como por ejemplo:
SELECT nif, nombre, apellidos FROM Cliente ORDER BY apellidos, nombre;
Esta consulta ordena los registros primero por apellidos, y cuando se repita este valor en varios registros, en
cada grupo se ordena por nombre.
Incluso se puede especificar el orden de los registros: ascendente mediante la clusula ASC (se toma este valor
por defecto) o descendente (DESC)
SELECT nif, nombre, apellidos FROM Cliente ORDER BY apellidos DESC , nombre ASC;
4.3.1. Sintaxis para ordenar mediante el ordinal y alias de las columnas.
Oracle tambin permite referenciar una columna del SELECT mediante su ordinal. Por ejemplo, la siguiente
consulta:
SELECT nif, nombre, apellidos FROM Cliente ORDER BY 3;

Oracle /74
Ordena los resultados por la columna apellidos (la tercera en las expresiones del SELECT).
As mismo, Oracle permite utilizar los alias asignados a las columnas para ordenar. Por ejemplo, la siguiente
consulta:
SELECT nif, nombre, localidad AS Ciudad FROM Cliente ORDER BY Ciudad;
Ordena los resultados por la columna localidad.
4.3.2. Ordenar con expresiones que no pertenecen al resultado.
La clusula ORDER BY asocia una expresin a cada registro resultante para poder ordenarlo. Normalmente esta
expresin est asociada con una columna dela fila resultante; sin embargo, es posible usar expresiones que no
se corresponden exactamente con los valores de las columnas resultantes de la consulta. Por ejemplo,
podemos realizar una consulta sobre la tabla FALTA y ordenar los resultados por mes en vez de por la fecha
completa.
SELECT * FROM FALTA ORDER BY EXTRACT(MONTH FROM fecha)
An ms, la expresin de ordenacin no tiene por qu corresponderse con un dato de salida. Por ejemplo,
podemos hacer una consulta para obtener los registros de NOTA ordenados por aprobados y por suspensos.
Un aprobado implica que el campo valor sea mayor o igual que 5, y un suspenso implica que valor sea menor
que 5. La consulta podra ser como sigue:
SELECT * FROM NOTA ORDER BY CASE WHEN valor>=5 THEN 'aprobado' ELSE 'suspenso' END, valor;
Para esta consulta las filas resultantes se ordenarn por el orden alfabtico de las palabras 'aprobado' y
'suspenso' y despus por el valor de la nota, formndose as dos grupos: primero los aprobados y despus los
suspensos.
Por ltimo, se puede ordenar tambin por una expresin que no aparezca en la salida. Por ejemplo,
consideremos la siguiente consulta:
SELECT nombre, apellidos FROM ALUMNO ORDER BY localidad;
En esta consulta se ordenan los alumnos por el campo localidad de la tabla base ALUMNO, pero este dato no
aparece en las filas de salida. Esto es slo posible si existe una correspondencia 1 a 1 entre las filas de salida y
las filas de la tabla base.
4.4. Consultas con predicado.
Un predicado es una palabra clave que modifica el comportamiento de una consulta. El predicado se incluye
entre la clusula SELECT y el primer nombre del campo a recuperar. Los posibles predicados son:
ALL Devuelve todos los campos de la tabla.
DISTINCT Omite los registros cuyos campos seleccionados coincidan totalmente
4.4.1. Predicado ALL.
Si no se incluye ninguno de los predicados se asume ALL. El Motor de base de datos selecciona todos los
registros que cumplen las condiciones de la instruccin SQL. El predicado ALL * obliga al motor de la base
de datos a analizar la estructura de la tabla para averiguar los campos que contiene, siendo por tanto ms
rpido indicar el listado de campos deseados.
SELECT ALL * FROM Alumno; -- es equivalente a:
SELECT * FROM Alumno;
4.4.2. Predicado DISTINCT.
El predicado DISTINCT omite los registros que contienen datos duplicados en los campos seleccionados. Para
que se incluya un registro en la salida de la instruccin SELECT el valor conjunto de todos los campos
incluidos debe ser nico.
Por ejemplo, varios alumnos listados en la tabla Alumno pueden tener los mismos apellidos. Si dos registros
contienen Lpez en el campo apellidos, la siguiente instruccin SQL devuelve un nico registro por apellido:
SELECT DISTINCT apellidos FROM Alumno;
Debe quedar claro que el predicado DISTINCT se aplica sobre los registros de salida del SELECT y no sobre los
registros de entrada del FROM.
4.5. Recuperacin de valores calculados.
Es posible obtener valores calculados a partir de los valores originales de la tabla. Por ejemplo, en la siguiente
consulta
SELECT idAlumno, idModulo, valor + 1FROM Nota;
Se obtiene un listado de todas las notas pero incrementadas en una unidad. Si el valor original es 7 en el
resultado se mostrar un 8.
Podemos operar tambin con cadenas de caracteres. En el siguiente ejemplo obtenemos el nombre y

Oracle /75
apellidos de los alumnos con el formato: "apellidos, nombre".
SELECT 'Apellidos y nombre:' , apellidos ||', '|| nombre AS "Nombre completo" FROM Alumno;
En la consulta, como primer campo insertamos un valor literal de tipo cadena de caracteres, y en el segundo
campo se utiliza el operador "||" para concatenar los valores de los campos apellidos y nombre de la tabla
Alumno. Un resultado posible de esta consulta es:
APELLIDOS Y NOMBRE: Nombre completo
------------------------------ ----------------------------------
Apellidos y nombre: Martnez Pan, Juan
Apellidos y nombre: Lpez Sobrado, Marian

4.6. La clusula WHERE.


La clusula WHERE puede usarse para determinar qu registros de las tablas enumeradas en la clusula FROM
aparecern en los resultados de la instruccin SELECT. Despus de escribir esta clusula se deben especificar
las condiciones. Si no se emplea esta clusula, la consulta devolver todas las filas de la tabla. WHERE es
opcional, pero cuando aparece debe ir a continuacin de FROM.
Algunos ejemplos son:
-- Matrculas del ao 2009:
SELECT idMatricula, nif FROM Matricula WHERE ao = 2009;
-- Mdulo y nota donde ha aprobado el alumno de nif '11111111A':
SELECT idModulo, valor FROM Nota WHERE nif = '1111111A' AND valor >= 5;
4.7. Consultas que incluyen nulos
Si un registro tiene un nulo (valor NULL) en un campo, significar que se desconoce el valor de ese campo en
el registro en cuestin.
Debemos tener en cuenta que las expresiones escalares de clculo en las cuales uno de los operandos es nulo
dan nulo como resultado, y las expresiones escalares de comparacin en las cuales uno de los comparandos es
nulo dan como resultado el valor lgico desconocido. En SQL, los nulos provocan ms problemas de los que
resuelven y conviene evitarlos.
Supongamos que, para el siguiente ejemplo, existen registros de alumnos con valor nulo en el nombre y
apellidos. Podemos obtener el nombre completo (nombre + apellidos) como una nica cadena de caracteres
de alumnos:
SELECT nombre ||''|| apellidos
FROM Alumno
WHERE nombre IS NOT NULL AND apellidos IS NOT NULL
En esta consulta se concatenan el valor de nombre y el valor de apellidos, excluyendo las filas donde alguno
de dichos valores sea nulo.
5. Criterios de seleccin
En el captulo anterior se vio la forma de recuperar los registros de las tablas, pero las formas empleadas
devolvan todos los registros de las tablas. A lo largo de este captulo se estudiarn las posibilidades de filtrar
los registros con el fin de recuperar solamente aquellos que cumplan unas condiciones preestablecidas.
Antes de comenzar el desarrollo de este captulo hay que recalcar tres detalles de vital importancia:
- El primero de ellos es que cada vez que se desee establecer una condicin referida a un campo de texto la
condicin de bsqueda debe ir encerrada entre comillas simples.
- La segunda es que no es posible establecer condiciones de bsqueda en los campos binarios grandes
(tipos de imagen o memorando dentro de campos tipo LOB).
- La tercera y ltima hace referencia a las fechas. En Oracle se deben escribir entre comillas separando el
da, mes y ao con guiones o barras inclinadas. El formato vlido de la fecha depende del gestor de base
de datos; en Oracle podemos usar los formatos'20-03-2009' y '20/03/2009'.
5.1. Operadores lgicos.
Los operadores lgicos soportados por SQL son: AND, OR, IS y NOT. A excepcin del ltimo (que es unario)
todos poseen la siguiente sintaxis:
expresin1 operador expresin2
En donde expresin1 y expresin2 son las condiciones a evaluar; el resultado de la operacin vara en funcin
del operador lgico. La tabla adjunta muestra los diferentes posibles resultados:

Oracle /76
expresin1 Operador expresin2 Resultado
Verdad AND Falso Falso
Verdad AND Verdad Verdad
Falso AND Verdad Falso
Falso AND Falso Falso
Verdad OR Falso Verdad
Verdad OR Verdad Verdad
Falso OR Verdad Verdad
Falso OR Falso Falso
Si a cualquiera de las anteriores condiciones le anteponemos el operador NOT el resultado de la operacin ser
el contrario al devuelto sin el operador NOT.
El operador denominado IS se emplea para comparar dos variables de tipo objeto: Objeto1 IS Objeto2. Este
operador devuelve verdad si los dos objetos son iguales. (Vase el modelo objeto-relacional de Oracle.)
Algunos ejemplos de uso de operadores lgicos son los siguientes:
-- Matrculas realizadas entre 1991 y 1999 inclusive:
SELECT * FROM Matricula WHERE ao> 1990 AND ao<2000;
-- Notas del alumno de nif '11111111A' con valores entre 5 y 8 inclusive:
SELECT * FROM Nota WHERE (valor>= 5 AND valor <9) OR nif= '11111111A';
5.2. Intervalos de valores.
Para indicar que deseamos recuperar los registros segn el intervalo de valores de un campo emplearemos el
operador BETWEEN, cuya sintaxis es:
campo [NOT] BETWEEN valor1 AND valor2
En este caso la consulta devolvera los registros que contengan en campo un valor incluido en el intervalo
valor1 y valor2 (ambos inclusive). Si anteponemos la condicin NOT devolver aquellos valores no incluidos en
el intervalo. La siguiente consulta devuelva las matriculas realizadas entre el ao 2008 y 2010 inclusive:
SELECT * FROM Matricula WHERE ao BETWEEN 2008 AND 2010;
5.3. El operador Like.
Se utiliza el operador LIKE para comparar una expresin de cadena con un patrn en una expresin SQL. Su
sintaxis de uso es:
expresin LIKE modelo
En donde expresin es una cadena de texto, y modelo es un patrn contra el que se compara expresin. Se
puede utilizar el operador LIKE para encontrar valores en los campos que coincidan con el modelo
especificado. El modelo puede especificar un valor completo ( 'Ana Mara'), o se pueden utilizar caracteres
comodn (LIKE 'An%') como los siguientes:
% representa cualquier cadena de texto de cero o ms caracteres de cualquier longitud.
_ representa un carcter.
El operador LIKE se puede utilizar en una expresin para comparar un valor de un campo con una expresin
de cadena. Por ejemplo, si introduce LIKE 'C%' en una consulta SQL, la consulta devuelve todos los valores de
campo que comiencen por la letra C. En una consulta con parmetros se puede hacer que el usuario escriba el
modelo que se va a utilizar.
En la tabla siguiente se muestra cmo utilizar el operador LIKE para comprobar expresiones con diferentes
modelos.
Tipo de coincidencia Modelo Planteado Coincide No coincide
Varios caracteres a%a 'aa', 'aBa', 'aBBBa' 'aBC'
Varios caracteres ab% 'abcdefg', 'abc' 'cab', 'aab'
Un solo carcter a_a 'aaa', 'a3a', 'aBa' 'aBBBa'
Adems Oracle proporciona la funcin REGEXP_LIKE(), la cual utiliza expresiones regulares que amplan las
capacidades del operador LIKE para construir patrones. Un ejemplo de uso de esta funcin es el siguiente,
donde se obtienen los alumnos cuyos apellidos comienzan por las letras M o B:
SELECT * FROM Alumno WHERE REGEXP_LIKE(apellidos, '[MB]')
5.4. El operador In.
El operador IN permite retornar aquellos registros en donde una expresin coincida con alguno de los valores
de una lista o una subconsulta. Su sintaxis de uso es:

Oracle /77
expresin [NOT] IN (valor1, valor2, ...) ;
expresin [NOT] IN ( subconsulta ) ;
Donde los valores incluidos en la lista o los valores que retorna la subconsulta deben ser del mismo tipo y
estructura que expresin.
Por ejemplo, la siguiente consulta retorna los alumnos residentes en Madrid, Barcelona o Sevilla.
SELECT * FROM Alumno WHERE localidad IN ('Madrid', 'Barcelona', 'Sevilla');
Pero tambin podemos comparar con listas de elementos compuestos. La siguiente consulta devuelve el nif
de los alumnos cuyo par nota y mdulo corresponde con alguno de la lista:
SELECT * FROM Nota WHERE (valor, idModulo) IN ( (5, 1) , (6, 3) , (5, 2) );

6. Consultas sobre ms de una tabla


La posibilidad de combinar datos de dos o ms tablas en una de las caractersticas ms poderosas de los
sistemas relacionales. Esta caracterstica se resuelve en el modelo ANSI mediante un producto cartesiano o
mediante la operacin de "Join", que es ms restrictiva que el producto cartesiano. En SQL, para realizar un
producto cartesiano entre tablas basta con listar dichas tablas en la clusula FROM separadas por comas.
En el siguiente ejemplo se obtienen todas las combinaciones posibles de alumnos y matrculas donde el nif de
alumno sea diferente del nif de matrcula:
SELECT Alumno.nif, Matricula.nif
FROM Alumno, Matricula
WHERE Alumno.nif <> Matricula.nif;
Ntese que el nombre de la tabla antecede al nombre del campo separado por un punto (.). Esto es as
porque estamos utilizando dos campos (nif) de tablas distintas que poseen el mismo nombre identificador.
El motor de base de datos resuelve esta consulta realizando un producto cartesiano entre los registros de
ambas tablas. Slo aquellos registros combinados que cumplan la condicin sern incluidos en el resultado.
6.1. Reunin de una tabla consigo misma.
Cuando nos pidan una consulta donde deban combinarse los registros de una tabla entre s, la solucin es
considerar que existen dos copias independientes de dicha tabla. Para referenciar cada copia de la misma tabla
usaremos un alias diferente para cada una.
Por ejemplo, la siguiente consulta empareja los nif's de aquellos alumnos que viven en la misma localidad:
SELECT A1.nif , A2.nif
FROM Alumno A1 , Alumno A2
WHERE A1.localidad = A2.localidad;
Esta consulta implica la reunin de la tabla Alumno consigo misma (con base en igualdad de localidades). En la
clusula FROM asignamos dos alias a dicha tabla: A1 y A2. En el resto de la consulta trabajamos con la
suposicin de que A1 y A2 son tablas diferentes, y operamos como en el caso de reunin de dos tablas.
La consulta tal como est establecida empareja el nif de un alumno con su mismo nif, lo cual no tiene mucho
sentido. Para evitar los emparejamientos de un alumno consigo mismo, debemos introducir una condicin
adicional:
SELECT A1.nif , A2.nif
FROM Alumno A1 , Alumno A2
WHERE A1.localidad = A2.localidad AND A1.nif <> A2.nif;
6.2. Consultas de unin internas.
SQL incorpora la clusula JOIN para optimizar las operaciones de combinacin entre tablas que tengan
concordancia de valores en un campo comn. Su sintaxis es:
SELECT campos FROM tb1 JOIN tb2 ON tb1.campo1 comp tb2.campo2 ;
SELECT campos FROM tb1 JOIN tb2 USING (campoComn) ;
En donde: tb1 y tb2 son los nombres de las tablas desde las que se combinan los registros; campo1 y campo2
son los nombres de los campos que se combinan; comp es un operador relacional (normalmente se utiliza =); y
campoComn es un campo comn a ambas tablas con el mismo nombre y tipos de datos compatibles.
Existen cuatro variantes de la clusula JOIN:
INNER JOIN, crea una combinacin por equivalencia, conocida tambin como unin interna. Combina
los registros de dos tablas siempre que haya concordancia de valores en campos comunes a ambas tablas.
(Esta variante es soportada desde la versin 9i, y en realidad es equivalente a la clusula JOIN sola.)
Por ejemplo, la siguiente consulta obtiene las notas de cada alumno en cada mdulo:
SELECT A.nif, N.idModulo, N.valor

Oracle /78
FROM Alumno A INNER JOIN Nota N ON A.nif = N.nif;
Esta misma consulta en formato ANSI sera as:
SELECT A.nif, N.idModulo, N.valor
FROM Alumno A, Nota N
WHERE A.nif = N.nif;
LEFT OUTER JOIN o LEFT JOIN, incluye todos los registros de la primera tabla y los combina con
aquellos de la segunda tabla que concuerden en un campo comn. En aquellos registros de la primera tabla
que no combinen con la segunda tabla, se pone a nulo los campos correspondientes a la segunda tabla.
Por ejemplo, la siguiente consulta obtiene las notas de cada alumno en cada mdulo, y si un alumno no
tiene nota se crea un registro con valor nulo en las columnas idModulo y valor:
SELECT A.nif, N.idModulo, N.valor
FROM Alumno A LEFT JOIN Nota N ON A.nif = N.nif;
Esta misma consulta en formato ANSI sera as:
SELECT A.nif, N.idModulo, N.valor
FROM Alumno A, Nota N
WHERE A.nif = N.nif(+);
RIGHT OUTER JOIN o RIGHT JOIN, incluye todos los registros de la segunda tabla y los combina con
aquellos de la primera tabla que concuerden en un campo comn. En aquellos registros de la segunda que
no combinen con la primera tabla, se pone a nulo los campos correspondientes a la primera tabla.
Por ejemplo, la siguiente consulta obtiene las notas de cada mdulo para cada alumno, y si mdulo no
tiene nota se crea un registro con valor nulo en las columnas nif y valor:
SELECT M.idModulo, N.nif, N.valor
FROM Nota N RIGHT JOIN Modulo M ON N.idModulo = M.idModulo;
Esta misma consulta en formato ANSI sera as:
SELECT M.idModulo, N.nif, N.valor
FROM Nota N, Modulo M
WHERE N.idModulo(+) = M.idModulo;
FULL OUTER JOIN FULL JOIN, incluye todos los registros ambas tablas.
Por ejemplo, la siguiente consulta combina los registros de nota con los registros de falta por el mdulo en
comn. Fuerza que aparezcan todos los registros de ambas tablas en el resultado:
SELECT N.idModulo, N.nif, N.valor, F.fecha
FROM Nota N FULL JOIN FaltaF ON N.idModulo = F.idModulo;
Para Oracle 9i no existe una sintaxis alternativa. Este tipo de consultas se resolva creando dos consultas
de seleccin externa, una por la izquierda y otra por la derecha, y aplicando una unin.
Si se intenta combinar campos que contengan datos largos (tipo LOB), se produce un error. Se pueden
combinar dos campos numricos cualesquiera, incluso si son de diferente tipo de datos.
JOIN/USING permite establecer relaciones indicando qu campo (o campos) comn a las dos tablas hay que
utilizar:
SELECT nif, A.nombre, A.apellidos, N.valor FROM Alumno A JOIN NotaN USING (nif);

Nota. Cuando se utiliza JOIN/USING sobre un campo comn, en la combinacin resultante se


genera una nica columna para el campo comn. Esto implica que no puede referenciarse dicho
campo a travs del nombre de su tabla. Por ejemplo, sera errnea la siguiente consulta:
SELECT ALUMNO.nif FROM ALUMNO JOIN NOTA USING (nif);

JOIN/ON permite establecer relaciones cuya condicin se establece manualmente, lo que permite realizar
asociaciones ms complejas o bien asociaciones cuyos campos en las tablas no tienen el mismo nombre:
SELECT * FROM Alumno JOIN Nota ON (Alumno.nif=Nota.nif AND valor >= 5);

Nota. Cuando se utiliza JOIN/ON sobre la igualdad de un campo comn, en la combinacin


resultante se genera una columna para el campo comn por cada tabla. Esto implica que debe
referenciarse dicho campo a travs del nombre de su tabla. Por ejemplo, sera errnea la siguiente
consulta:
SELECT nif FROM ALUMNO JOIN NOTA ON ALUMNO.nif = NOTA.nif;

Tambin se pueden combinar ms de dos tablas usando varios JOIN. Por ejemplo, La siguiente consulta
obtiene los apellidos de alumno, el nombre de un mdulo y la nota correspondiente:
SELECT A.apellidos, M.nombre, N.valor

Oracle /79
FROM (Alumno A JOIN Nota N ON A.nif = N.nota) JOIN Modulo M ON N.idModulo = M.idModulo;
Otra sintaxis permite obtener las faltas de los alumnos en cada mdulo en el ao 2009:
SELECT N.nif
FROM Matricula M JOIN (Falta F JOIN Modulo M ON F.idModulo=M.idModulo) ON M.idMatricula=F.idMatricula;
Por ltimo, dos reglas de anidamiento de JOIN:
Un LEFT JOIN o un RIGHT JOIN pueden anidarse dentro de un INNER JOIN.
Un INNER JOIN no puede anidarse dentro de un LEFT JOIN o un RIGHT JOIN.
6.3. Consultas con operaciones de conjuntos.
Hay tres tipos de operaciones con conjuntos: UNION, MINUS, e INTERSECT.
6.3.1. Consultas de unin externa.
Se utiliza la operacin UNION para crear una consulta de unin, combinando los resultados de dos o ms
consultas con el mismo esquema. Su sintaxis es:
consulta1 UNION [ALL] consulta2 [UNION [ALL] . . . consultaN]
En donde consulta1...consultaN son instrucciones de tipo SELECT.
Se pueden combinar los resultados de dos o ms consultas SELECT, en cualquier orden, en una nica
operacin UNION siempre y cuando posean el mismo esquema. El ejemplo siguiente combina los alumnos
con las matrculas para obtener los nif's:
SELECT nif FROM Alumno UNION SELECT nif FROM Matricula ;
Si no se indica lo contrario, no se devuelven registros duplicados cuando se utiliza la operacin UNION, no
obstante puede incluirse el predicado ALL para asegurar que se devuelvan todos los registros repetidos. Esto
hace que la consulta se ejecute ms rpidamente. Todas las consultas en una operacin UNION deben pedir el
mismo nmero de campos, no obstante los campos no tienen porqu tener el mismo tamao o el mismo tipo
de datos.
Se puede utilizar una clusula GROUP BY y HAVING en cada consulta para agrupar los datos devueltos. A partir
de Oracle 10i se puede utilizar una clusula ORDER BY al final de las consultas de la unin. Anteriormente si
queramos establecer una ordenacin al resultado de la unin tenamos que subordinarla a un SELECT
superior. Por ejemplo, la unin ordenada de los nif's se obtiene con:
SELECT nif
FROM (SELECT nif FROM Alumno UNION SELECT nif FROM Matricula)
ORDER BY nif;
O bien:
SELECT nif FROM Alumno UNION SELECT nif FROM Matricula
ORDER BY nif;
6.3.2. Consultas de diferencia:
La operacin MINUS devuelve la diferencia (resta) de dos o ms conjuntos de resultados.
Por ejemplo, la siguiente consulta obtiene los nif's de alumnos todava no matriculados.
SELECT nif FROM Alumno
MINUS
SELECT nif FROM Matricula;
6.3.3. Consultas de interseccin:
La operacin INTERSECT devuelve la interseccin entre dos o ms conjuntos de resultados en uno.
Por ejemplo, la siguiente consulta obtiene los nif's de alumnos de 'Madrid' matriculados:
SELECT nif FROM Alumno WHERE localidad='Madrid'
INTERSECT
SELECT nif FROM Matricula;

7. Agrupaciones
7.1. Funciones de agregado.
SQL incluye un conjunto de funciones estndar predefinidas que nos permiten obtener valores resumen
sobre los resultados de una consulta. Se denominan funciones de agregado o de grupo.
7.1.1. Funciones de grupo estndar.
Las funciones de agregado estndar en SQL son:
AVG. Calcula la media aritmtica de un conjunto de valores contenidos en los registros especificados de
una consulta. Su sintaxis es la siguiente
AVG(expr)

Oracle /80
En donde expr representa el campo que contiene los datos numricos para los que se desea calcular la
media o una expresin que realiza un clculo con los datos de un registro. La media calculada por AVG es la
media aritmtica (la suma de los valores dividido por el nmero de valores). Para realizar el clculo
resumen, la funcin AVG no incluye a ningn registro con la expresin a NULL.
Por ejemplo, la siguiente consulta obtiene la media de las notas del alumno de nif '11111111A':
SELECT AVG(valor) AS "Nota media" FROM Nota WHERE nif='11111111A';
COUNT. Calcula el nmero de registros devueltos por una consulta. Su sintaxis es la siguiente
COUNT(expr)
En donde expr puede ser el smbolo *, el nombre de un campo de una tabla, una constante o una funcin
(la cual puede ser intrnseca o definida por el usuario, pero no otras de las funciones de agregado de SQL).
Puede contar cualquier tipo de datos, incluso texto.
Aunque expr puede realizar un clculo sobre un campo, COUNT simplemente cuenta el nmero de registros
sin tener en cuenta qu valores se almacenan en los registros. La funcin COUNT no cuenta los registros
cuya expresin evala a NULL a menos que expr sea el carcter comodn asterisco (*). En ese sentido,
COUNT(*) es considerablemente ms eficiente que COUNT(expresin).
La siguiente consulta calcula el nmero de alumnos registrados:
SELECT COUNT(*) AS Total FROM Alumno;
Si el campo localidad admite valores nulos, la siguiente consulta calcula el nmero de alumnos registrados
que tengan asignada alguna localidad:
SELECT COUNT(localidad) AS Total FROM Alumno;
Tambin se puede especificar la clusula DISTICNT en la expresin para no contar aquellos registros con
valores repetidos en dicha expresin. Por ejemplo, la siguiente consulta cuenta el nmero de alumnos que
viven en localidades distintas:
SELECT COUNT( DISTINCT localidad) AS Total FROM Alumno;
MAX, MIN. Devuelven el mnimo o el mximo de un conjunto de valores obtenidos de una expresin de
una consulta. Su sintaxis es:
MIN(expr)
MAX(expr)
En donde expr es el campo o expresin sobre el que se desea realizar el clculo. Expr puede incluir el
nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida
por el usuario, pero no otras de las funciones de agregado de SQL).
La siguiente consulta obtiene la nota mnima y mxima del alumno de nif '11111111A':
SELECT MIN(valor) AS 'Nota mnima', MAX(valor) AS 'Nota mxima'
FROM Nota
WHERE nif = '11111111A';
SUM. Devuelve la suma del conjunto de valores obtenidos de una expresin de una consulta. Su sintaxis
es:
SUM(expr)
En donde expr representa el nombre de un campo que contiene los datos que desean sumarse o una
expresin que realiza un clculo sobre un registro. Los operandos de expr pueden incluir el nombre de un
campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el usuario
pero no otras de las funciones de agregado de SQL).
La siguiente consulta obtiene la suma de las notas del alumno de nif '11111111A':
SELECT SUM(valor) AS 'Suma de notas' FROM Nota WHERE nif = '11111111A';
7.1.2. Funciones de agregado propias de Oracle.
Adems, Oracle aade otro conjunto propio de funciones de grupo:
CORR(expr1, expr2). Calcula coeficientes de correlaciones de un conjunto de pares de nmeros. La
funcin CORR_K soporta correlaciones no parametrizadas, y la funcin CORR_S soporta correlaciones de
fila.
COVAR_POP(expr1, expr2). Calcula la covarianza demogrfica de un conjunto de pares de valores.
COVAR_SAMP(expr1, expr2). Calcula la covariancia tpica de un conjunto de pares de valores.
MEDIAN(expr). Retorna el valor medio de un grupo de valores ignorando los nulos.
STDDEV(expr).Calcula la desviacin estndar de todos los valores.
STDDEV_POP(expr). Calcula de desviacin demogrfica estndar.
STDDEV_SAMP(expr). Calcula la desviacin tpica.

Oracle /81
VAR_POP(expr). Calcula la variancia demogrfica.
VAR_SAMP(expr). Calcula la variancia tpica.
VARIANCE(expr). Calcula la variancia de todos los valores del grupo.
WIDTH_BUCKET(expr,min,max,num). Permite crear histogramas por igualdad de tamao.
7.1.3. Cmo afectan los nulos en valores de funciones de grupo.
Las funciones de grupo tratan los valores NULL de forma diferente a cmo lo hacen las funciones de valor
simple. Las funciones de grupo ignoran los valores nulos y calculan el resultado sin tenerlos en cuenta. Sin
embargo, una funcin de agregado que realiza clculos slo sobre valores nulos siempre retorna el valor NULL
(excepto COUNT).
Para analizar como afectan los nulos a las funciones de grupo, tomemos AVG como ejemplo. Supongamos
que tenemos una lista de 100 amigos y sus edades. Si cogemos 20 al azar y calculamos el promedio de sus
edades, nos encontraremos con un valor cercano a si calculamos el promedio de otra lista diferente de 20
amigos elegidos al azar o el promedio sobre los 100 amigos. Esto es as porque AVG es bastante insensible a la
falta de registros, incluso si representan un alto porcentaje del nmero total de registros disponibles.
Esta relativa insensibilidad de AVG ante la falta de datos puede ser contrastada con la funcin SUM. Si
calculamos la suma de edades sobre 20 amigos obtendremos valores muy diferentes si hacemos el clculo
sobre otros grupos.
Si ahora, de los 100 amigos, slo 20 proporcionan una edad y el resto tienen la edad a valor NULL, qu
estadstica sera ms fiable sobre el grupo entero y menos sensible a la ausencia de datos? Si no sabemos
cuntos registros estn a NULL, podemos usar la siguiente consulta para obtener un resultado razonable
respecto al promedio de edades:
SELECT AVG(edad) FROM Amigo;
Sin embargo, no podemos obtener un resultado razonable para sumas de edades con:
SELECT SUM(edad) FROM Amigo;
Otras funciones relativamente insensibles a los nulos son STDDEV y VARIANCE.
Las funcione MAX y MIN obtienen valores extremos sobre nuestros datos. Pueden fluctuar desordenadamente
mientras que AVG se queda relativamente constante. Si aadimos un hombre de 100 aos a un grupo de 99
personas que tienen 50 aos, la edad media slo se acerca a 50.5, pero la edad mxima se ha doblado. Si
aadimos un beb recin nacido, el promedio vuelve a 50, pero la edad mnima es ahora 0. Parece claro que la
omisin o desconocimiento de valores nulos puede afectar profundamente a MAX, MIN y SUM, as que
tenemos que ser cautelosos usndolos, en particular si un porcentaje significativo de los datos es NULL.
La funcin COUNT es un caso especial. Esta funcin siempre retorna un valor diferente de NULL. Si se evala
sobre una expresin, cuenta el nmero de filas donde la expresin es distinta de NULL. Esto quiere decir que
la consulta:
SELECT COUNT(edad) FROM Amigo;
Retorna el valor 20, puesto que en 80 filas el valor para edad es NULL. Sin embargo, la consulta:
SELECT COUNT(*) FROM Amigo;
Retorna el valor 100, puesto que no se tendrn en cuenta los nulos, y simplemente contar todas las filas
existentes.
7.1.4. Combinando funciones de grupo y de valor simple.
Podemos combinar fcilmente funciones de grupo con funciones simples para obtener resultados ms
complejos o ajustados. Por ejemplo, supongamos que queremos obtener para el ao 2010 el ltimo mes en el
cual un alumno falt en cualquier mdulo. La tabla FALTA proporciona un campo fecha sobre el cual
podemos aplicar la funcin MAX para obtener la fecha ms prxima, y despus podemos aplicar una funcin
simple como TO_CHAR para extraer el mes de la fecha. En este caso podemos obtener dos soluciones
equivalentes:
SELECT MAX( TO_CHAR(fecha, 'MM') )
FROM FALTA WHERE idMatricula=1 AND TO_CHAR(fecha, 'YYYY')=2010;
/
SELECT TO_CHAR( MAX(fecha), 'MM')
FROM FALTA WHERE idMatricula=1 AND TO_CHAR(fecha, 'YYYY')=2010;
Podemos combinar funciones de valor simple dentro de funciones de grupo y viceversa, aunque el orden de
aplicacin de las funciones no siempre produce los mismos resultados. En el ejemplo previo, la primera
consulta aplica la funcin de valor simple sobre cada fila obteniendo un nmero de mes, y la funcin de
grupo calcula el valor ms alto. La segunda consulta aplica la funcin de grupo para obtener la fecha ms

Oracle /82
prxima, y la funcin de valor simple extrae el valor de mes de dicha fecha.
Sin embargo, si intentamos anidar funciones de grupo entre s produciremos errores. Por ejemplo
SELECT SUM( AVG(valor)) FROM NOTA;
Provocar el error:
ORA-00978: funcin de grupo anidada sin GROUP BY
Adems, si esto en realidad funcionase debera producir el mismo resultado que AVG(valor). Puesto que
AVG(valor) produce un resultado simple, el SUM de un valor simple es justo el propio valor simple.
Lo que s podemos hacer es operar con los resultados de funciones de grupo. Por ejemplo, la siguiente
consulta sera vlida:
SELECT MAX(valor) - MIN(valor) FROM NOTA;
7.1.5. DISTINCT en funciones de grupo.
Todas las funciones de grupo admiten la opcin DISTINCT o ALL. Cuando no se indica, se toma la opcin ALL
por defecto.
El significado de estas opciones podemos verlo con un ejemplo de uso en la funcin COUNT:
SELECT COUNT(DISTINCT localidad) "N localidades", COUNT(localidad) "N registros", COUNT(*)
FROM ALUMNO;
Un posible resultado podra ser el siguiente
N localidades N registros COUNT(*)
----------------- -------------- -------------
10 25 30
La opcin DISTINCT fuerza que COUNT cuente slo el nmero de filas con localidades diferentes; mientras
que la opcin ALL (por defecto) cuenta todas las filas donde el valor de localidad no sea NULL aunque se
repitan nombres de localidades. En este ejemplo, por los resultados, se ve que hay 5 filas donde la localidad
est a valor nulo.
Aunque puede hacerse, el uso de DISTINCT sobre las dems funciones de grupo suele ser raro, excepto para
algn tipo de clculo estadstico. MAX y MIN producen el mismo resultado con o sin DISTINCT.
7.2. La clusula Group by.
La clusula GROUP BY permite realizara agrupaciones lgicas entre los registros de una tabla de consulta, de tal
forma que dentro de cada grupo todas las filas tengan el mismo valor en los campos indicados con GROUP BY.
Esto es sumamente til cuando queremos utilizar funciones de agregado sobre grupos de registros en vez de
sobre todos los registros.
Por ejemplo, para obtener los apellidos y nota media de los alumnos matriculados en el curso 2004:
SELECT A.apellidos, AVG(N.valor)
FROM Alumno A JOIN Matricula M ON A.nif=M.nif JOIN Nota N ON A.nif=N.nif
WHERE M.ao=2004
GROUP BY A.apellidos ;
La consulta realiza el join entre las tablas Alumno, Matricula y Nota, descartando aquellas
filas que no cumplen la
condicin. Las filas vlidas se agrupan por el mismo nombre de alumno. De cada grupo se calcula la media
del campo valor. En la tabla resultante, por cada grupo, se muestra un registro con los apellidos y el promedio
calculado.
GROUP BY no implica ordenacin. Si queremos presentar el resultado ordenado por apellidos debemos
especificar la clusula ORDER BY A.apellidos despus de la clusula GROUP BY.
Cada expresin en las columnas de la clusula SELECT debe producir un nico valor por grupo; es decir,
puede ser un campo (o alguna expresin sobre dicho campo) de GROUP BY, o un literal, o una funcin de
agregado.
La clusula GROUP BY tambin admite expresiones. Por ejemplo, la siguiente consulta obtiene el nmero de
faltas de cada alumno por mes en el ao 2008:
SELECT M.nif, EXTRACT(Month FROM fecha) AS "Mes", COUNT(*) AS "N de faltas"
FROM Matricula M JOIN Falta F ON M.idMatricula=F.idMatricula
WHERE M.ao=2008
GROUP BY EXTRACT(Month FROM fecha), M.nif ;
Una consideracin: en la consulta anterior no podramos incluir el campo fecha como una columna del
SELECT. Esto es as porque fecha no se corresponde con una expresin de la clusula GROUP BY.
7.2.1. Empleo de HAVING.
HAVING es a los grupos lo que WHERE a las filas (si se especifica HAVING, deber haberse especificado

Oracle /83
tambin GROUP BY). Es decir, HAVING permite indicar condiciones para filtrar grupos de la misma manera que
WHERE nos permite filtrar las filas de las tablas base. Las expresiones de condicin en la clusula HAVING
deben producir un solo valor por grupo.
En el siguiente ejemplo se listan los alumnos matriculados y el nmero de faltas de asistencia cuando superan
las 4 faltas:
SELECT M.nif, COUNT(*) AS "N de faltas"
FROM Matricula M JOIN Falta F ON M.idMatricula=F.idMatricula
GROUP BY M.nif
HAVINGCOUNT(*) > 4

8. Subconsultas
8.1. Introduccin.
Una subconsulta es una instruccin SELECT anidada dentro de una instruccin SELECT, SELECT...INTO,
INSERTINTO, DELETE, o UPDATE o dentro de otra subconsulta.
Se pueden utilizar tres formas de sintaxis para crear una subconsulta:
comparacin [ANY | ALL | SOME] (instruccin_sql)
expresin [NOT] IN (instruccin_sql)
[NOT] EXISTS (instruccin_sql)
En donde: comparacin es una expresin seguida de un operador de comparacin que compara la expresin
con el resultado de la subconsulta; expresin es una expresin por la que se busca el conjunto resultante de la
subconsulta; instruccin_sql es una instruccin SELECT, que sigue el mismo formato y reglas que cualquier otra
instruccin SELECT.
Se puede utilizar una subconsulta en lugar de una expresin en la lista de campos de una instruccin SELECT,
como un origen de registros en la clusula FROM, o en una clusula WHERE o HAVING. En una subconsulta, se
utiliza una instruccin SELECT para proporcionar un conjunto de uno o ms valores especificados para
evaluar en la expresin de la clusula WHERE o HAVING.
Se puede utilizar el predicado ANY o SOME, los cuales son sinnimos, para recuperar registros de la consulta
principal, que satisfagan la comparacin con cualquier otro registro recuperado en la subconsulta.
Por ejemplo, la siguiente consulta devuelve los datos de matrcula de aquellos alumnos que no tienen faltas en
el mdulo 1:
SELECT *
FROM Matricula
WHERE idMatricula <> ALL (SELECT DISTINCT idMatricula FROM Falta WHERE idModulo = 1);
La subconsulta devuelve la lista de matrculas que tiene alguna falta en el Mdulo 1. El predicado ALL se
utiliza para recuperar nicamente aquellos registros de la consulta principal que satisfacen la comparacin con
todos los registros recuperados en la subconsulta. En este caso, el id de Matricula no debe coincidir con
ninguno de la lista establecida por la subconsulta.
Si queremos obtener los alumnos que han aprobado el mdulo 1 podemos plantear la siguiente consulta:
SELECT *
FROM Alumno
WHERE nif = ANY (SELECT nif FROM Nota WHERE idModulo = 1 AND valor>=5);
La subconsulta devuelve la lista de nif's de alumnos que han aprobado el mdulo 1. En este caso basta con
que el nif del Alumno sea alguno de los que estn en la lista establecida por la subconsulta.
8.2. Recuperacin de datos con subconsulta
Si una subconsulta retorna un nico registro con una sola columna, el valor de la columna puede ser tratado
como si fuese un literal. Por ejemplo, la siguiente consulta recupera las matrculas del alumno Jos Prez:
SELECT idMatricula, ao
FROM MATRICULA
WHERE nif = (SELECT nif FROM ALUMNO WHERE nombre='Jos' AND apellidos="Prez")
En esta consulta se compara el nif de cada registro de MATRICULA con el valor del nif del alumno
Jos Prez,
obtenido mediante una subconsulta. Si existe un nico alumno llamado Jos Prez la subconsulta devuelve
una nica fila con un nico valor. Pero si existen varios alumnos con ese mismo nombre, la subconsulta
retornar varios registros y se producir un error del tipo siguiente:
ERROR en lnea 3:
ORA-01427: la subconsulta de una sola fila devuelve ms de una fila

Oracle /84
Si nos solicitan los apellidos de alumnos que tienen faltas en el mdulo 3, podemos resolverlo con la siguiente
consulta:
SELECT DISTINCT Alumno.apellidos
FROM Alumno JOIN Matricula USING(nif) JOIN Falta USING (idMatricula)
WHERE Falta.idModulo = 3;
Pero tambin podramos resolverlo utilizando subconsultas:
SELECT Alumno.apellidos
FROM Alumno
WHERE nif IN (SELECT DISTINCT nif
FROM Matricula
WHERE Matricula.id IN ( SELECT DISTINCT idMatricula FROM Falta WHERE idModulo = 3 ));
En este caso las subconsultas se utilizan mediante una condicin IN. Para evaluar la consulta completa, el
sistema evala primero las subconsultas anidadas, desde la ms interior a la ms exterior. La subconsulta ms
interior produce como resultado el conjunto de id's de matriculados que tienen faltas en el mdulo de id igual
a 3. Es como si el resultado de la subconsulta fuese una lista de id's. La siguiente subconsulta obtiene la lista
de nif's correspondientes a las matrculas que tienen faltas. La consulta principal evala que nif's de alumnos
pertenecen a dicha lista, y stos son precisamente los que tienen una falta en el mdulo 3.
Anlogamente se puede utilizar NOT IN para recuperar nicamente aquellos registros de la consulta principal
para los que no hay ningn registro de la subconsulta que contenga un valor igual.
8.3. Subconsultas correlacionadas.
Al utilizar subconsultas debe estudiarse si la bsqueda es correlacionada o no. Diremos que la bsqueda en
subconsultas es correlacionada si el resultado de la subconsulta depende de un resultado de la consulta
principal.
En el ejemplo de la seccin anterior, el resultado de las subconsultas es independiente de la consulta principal
(se obtienen id's de matricula que cumplen una condicin particular independiente de los valores obtenidos
en la consulta principal).
Un ejemplo de subconsulta correlacionada es el siguiente: obtener el id de matrculas pertenecientes a
alumnos que tienen ms de una falta.
SELECT DISTINCT F1.idMatricula
FROM Falta F1
WHERE F1.idMatricula IN ( SELECT F2.idMatricula
FROM Falta F2
WHERE NOT (F2.idMatricula=F1.idMatricula AND F2.fecha=F1.fecha) );
La estrategia en esta subconsulta es obtener el listado de registros de la tabla Falta excluyendo el registro
evaluado en la consulta principal. Si este listado incluye un registro con el id evaluado en la consulta principal,
quiere decir que el alumno correspondiente a ese id posee ms de una falta.
En la consulta principal, por cada registro de F1 se ejecuta la subconsulta recorriendo los registros de F2 cada
vez. Es decir, la subconsulta se ejecuta tantas veces como registros contenga la tabla Falta.
En las subconsultas no correlacionadas el nmero de accesos viene dado por la suma de los accesos en cada
SELECT. En las subconsultas correlacionadas el nmero de accesos es producto de la multiplicacin, pues
debe evaluarse la SELECT interior para cada registro de la SELECT exterior.
Por ejemplo, obtener el nif y los apellidos de alumnos que se hayan matriculado en ms de un ciclo.
SELECT DISTINCT Alumno.nif , Alumno.apellidos
FROM Alumno JOIN Matricula M1 USING (nif)
WHERE M1.nif IN ( SELECT M2.nifFROM Matricula M2WHERE M2.idMatricula<> M1.idMatricula )
8.4. Subconsultas con operador de comparacin distinto de IN.
Podemos usar una subconsulta para obtener un nico valor y entonces compararlo con los operadores de
comparacin (=, <>, > , >=, <, <=).
Por ejemplo, la siguiente consulta obtiene el nombre y apellidos de los alumnos que residen en la misma
localidad que el alumno de nif '11111111A'.
SELECT nombre , apellidos
FROM Alumno
WHERE localidad = ( SELECT localidad FROM Alumno WHERE nif = '11111111A' )
Si la subconsulta retornase ms de un valor, entonces se producira un error en la ejecucin de la consulta
externa.

Oracle /85
8.5. Funciones de agregado en subconsultas.
Se suelen utilizar funciones de agregado en subconsultas para obtener un valor de grupo que podamos
comparar con valores individuales en cada registro.
En este ejemplo, se obtiene el nif de los alumnos que tienen una nota en el mdulo 4 superior a su nota
media. El clculo de la nota media se realiza mediante la subconsulta.
SELECT n1.nif
FROM Nota n1
WHERE n1.idModulo = 4
AND n1.valor > ( SELECT AVG(*) FROM Nota n2WHERE n1.nif = n2.nif );
En este ejemplo, se obtienen los nif's de alumnos matriculados en 2004 cuya nota media es superior a la nota
media de todos los alumnos.
SELECT A.nif
FROM Matricula M JOIN Alumno AON M.nif=A.nif JOIN Nota N ON A.nif=N.nif
WHERE M.ao = 2004
GROUP BY A.nif
HAVING AVG (valor) > ( SELECT AVG(valor)FROM Nota );
8.6. Subconsultas con EXISTS.
EXISTS es el cuantificador existencial y puede aplicarse sobre subconsultas. La expresin EXISTS (SELECT
FROM ) da como resultado un valor verdadero si y solo si el resultado de evaluar la subconsulta no es el
conjunto vaco; en otras palabras, si existe al menos un registro en el resultado.
Por ejemplo, la siguiente consulta obtiene el id de matrcula de alumnos del curso 2004-05 que tienen alguna
falta en el mdulo 5.
SELECT idMatricula
FROM Matricula
WHERE ao = 2004
AND EXISTS ( SELECT 1 FROM Falta WHERE Falta.idMatricula AND Falta.idModulo=5 )

Nota. En una subconsulta evaluada mediante el operador EXISTS la lista de columnas que devuelve
el comando SELECT carece de importancia. Por ello es habitual que este tipo de consultas retornen
una nica columna con una expresin literal.
La forma negada, NOT EXISTS, es importante en cierto tipo de consultas complejas.
Como primer ejemplo obtendremos el id de matrcula de alumnos del curso 2004-05 que no tienen ninguna
falta en los mdulos 4 y 5.
SELECT idMatricula
FROM Matricula
WHERE ao = 2004
AND NOT EXISTS ( SELECT 1 FROM Falta WHERE Falta.idMatricula AND Falta.idModulo IN (4, 5 ) )
El siguiente ejemplo es ms complejo, y obtiene los id de matrcula de alumnos del curso 2004-05 que tienen
faltas en todos los mdulos.
SELECT Matricula.idMatricula
FROM Matricula
WHERE Matricula.ao = 2004
ANDNOT EXISTS ( SELECT 1FROM Modulo
WHERE NOT EXISTS ( SELECT 1FROM Falta
WHERE Falta.idMatricula = Matricula.idMatricula AND Falta.idModulo = Modulo.idModulo )) ;
Para comprender la consulta, podramos enunciarla como: obtener los id de matricula de alumnos del curso
2004-05 que no tengan mdulos en los que no tengan faltas.
8.7. Expresiones de columna con subconsultas
Es tambin posible usar una subconsulta en una de las expresiones de columna de una SELECT siempre y
cuando la subconsulta retorne un nico registro con un valor simple.
Un primer ejemplo sencillo es obtener los id's de matrcula, los apellidos de alumnos y el ao de curso.
SELECT M.idMatricula, (SELECT apellidos FROM Alumno A WHERE A.nif=M.nif), M.ao
FROM Matricula M;
Como alternativa al uso de la clusula GROUP BY, podemos obtener el nif de alumnos y el nmero de mdulos
que han cursado.

Oracle /86
SELECT nif , (SELECT COUNT(*) FROM Nota WHERE Nota.nif=Alumno.nif)
FROM Alumno;
8.8. Subconsultas como origen de registros para FROM.
En la clusula FROM se pueden usar como orgenes de datos:
- Una tabla
- Una vista
- Una funcin que devuelva una tabla
- Una subconsulta
Por ejemplo, podemos obtener en una subconsulta registros con el nif de un alumno, el nombre de un
mdulo y la nota. Podemos utilizar dicha subconsulta como origen de datos para obtener la media de notas
por mdulo.
SELECT nombre AS "Mdulo" , AVG (valor) AS "Nota media"
FROM (SELECT N.nif, M.nombre, N.valor FROM Nota N JOIN Modulo M USING (idModulo))
GROUP BY nombre;
Algo ms complejo es obtener un valor de nota (entre 1 y 10) y el nmero de alumnos que han conseguido
dicha nota en el mdulo 1. Para la consulta se debe forzar un registro por cada una de las notas, de forma que
si ningn alumno obtuvo esa nota se muestre el valor 0.
Podemos obtener el nmero de alumnos por nota registrada en la tabla Nota:
SELECT valor, COUNT(*)
FROM Nota
GROUP BY valor;
Pero esta consulta no garantiza que se genere necesariamente un registro por cada valor de nota posible (por
ejemplo, si ningn alumno tiene la nota 7, no se generar un registro con la nota 7). Para forzar esto
necesitamos una subconsulta con todos los valores de nota y forzar un JOIN externo:
SELECT valor, NVL(num, 0)
FROM
(SELECT 1 valor FROM DUAL UNION SELECT 2 valor FROM DUAL UNION SELECT 3 valor FROM DUAL
UNION SELECT 4 valor FROM DUAL UNION SELECT 5 valor FROM DUAL UNION SELECT 6 valor FROM
DUAL UNION SELECT 7 valor FROM DUAL UNION SELECT 8 valor FROM DUAL UNION
SELECT 9 valor FROM DUAL UNION SELECT 10 valor FROM DUAL) T1
LEFT JOIN
(SELECT valor, COUNT(*) num FROM Nota GROUP BY valor) T2
ON T1.valor = T2.valor;
Aquellos valores de nota no incluidos en la tabla Nota no combinarn en el LEFT JOIN y por tanto producirn
un registro con las columnas combinadas (valor y num) a valor NULL. Por ello se utiliza la funcin NVL(), que
verifica si el campo num tiene valor NULL y en ese caso lo sustituye por un cero.
9. Vistas
9.1. Introduccin.
Una vista no es ms que una consulta almacenada que puede ser reutilizada tantas veces como se desee. Una
vista no contiene datos sino la instruccin SELECT necesaria para generarla; eso asegura que los resultados de
la vista sean siempre coherentes con los datos actuales almacenados en las tablas. Por todo ello, las vistas
gastan muy poco espacio de disco.
Las vistas se emplean para:
- Realizar consultas complejas ms fcilmente, ya que permiten dividir la consulta en varias partes.
- Proporcionar el contenido de tablas con datos completos.
- Utilizar visiones especiales de los datos.
- Ser utilizadas como tablas que resumen todos los datos.
- Ser utilizadas como cursores de datos en los lenguajes procedimentales (como PL/SQL).
Hay dos tipos de vistas:
Simples. Las forma una sola tabla y no contienen funciones de agrupacin. Su ventaja es que permiten
siempre realizar operaciones DML sobre ellas.
Complejas. Obtienen datos de varias tablas, y pueden utilizar funciones de agrupacin. No siempre
permiten operaciones DML.
Podemos usar la clusula ORDER BY al crear una vista, pero esto puede influir en un rendimiento negativo,

Oracle /87
porque obliga a operaciones adicionales.
9.2. Crear y consultar vistas.
Las sintaxis para crear una vista es la siguiente:
CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW nombre_vista [(alias[, alias2...]]
AS consultaSelect
[WITH CHECK OPTION [CONSTRAINT restriccin]]
[WITH READ ONLY [CONSTRAINT restriccin]]
Donde:
OR REPLACE, indica que si la vista ya exista se cambie por la actual.
FORCE, crea la vista aunque los datos de la consulta SELECT no existan.
alias, es la lista de alias que se establecen para las columnas devueltas por
la consulta SELECT en la que se
basa esta vista. El nmero de alias debe coincidir con el nmero de columnas devueltas por SELECT.
WITH CHECK OPTION, hace que slo las filas que se muestran en la vista puedan ser aadidas (INSERT) o
modificadas (UPDATE). La restriccin que sigue a esta seccin es el nombre que se le da a esta restriccin
de tipo CHECK OPTION.
WITH READ ONLY, hace que la vista sea de slo lectura. Permite grabar un nombre para esta restriccin.
Lo bueno de las vistas es que tras su creacin se utilizan como si fueran una tabla virtual. Por ejemplo, la
siguiente vista recupera el nmero de faltas de cada alumno en cada mdulo de cada ao:
CREATE VIEW ResumenFaltas (nif, modulo, faltas)
AS
( SELECT M.nif, Mo.nombre, COUNT(*) FROM
Matricula M JOIN Falta F ON M.idMatricula=F.idMatricula JOIN Modulo Mo ON F.idModulo=Mo.idModulo
);
/
SELECT DISTINCT nif, modulo FROM ResumenFaltas;
9.3. Ejecucin de comandos DML sobre vistas.
Las instrucciones DML (INSERT, UPDATE y DELETE) ejecutadas sobre las vistas permiten aadir o modificar
los datos de las tablas relacionadas en la consulta subyacente de la vista. Ahora bien, no es posible ejecutar
instrucciones DML sobre vistas que:
- Utilicen funciones de grupo (SUM, AVG, etc.)
- Usen GROUP BY o DISTINCT.
- Posean columnas con clculos.
Adems no se pueden aadir datos a una vista si en las tablas referenciadas en la consulta SELECT hay campos
NOT NULL que no aparecen en la consulta (es lgico ya que al aadir el dato se tendra que aadir el registro
colocando el valor NULL en el campo ausente).
Por ejemplo, podemos utilizar la siguiente vista para hacer inserciones de matrculas:
CREATE VIEW MatriculaAmpliada
AS
SELECT idMatricula, nif, apellidos || ', ' || nombre AS alumno, ao
FROM Matricula LEFT JOIN Alumno USING (nif);
/
INSERT INTO MatriculaAmpliada (idMatricula, nif, ao) VALUES (67, '77777777J', 2008);
Podremos tambin hacer inserciones sobre una vista basada en varias tablas si Oracle puede determinar los
registros apropiados a insertar. En vistas multitabla Oracle determina qu tablas proporcionan su clave. Si una
vista contiene muchas columnas de una tabla para identificar la clave primaria de esta tabla, se conserva la
clave y Oracle puede ser capaz de insertar filas en la tabla a travs de la vista.
9.4. Estabilidad de una vista.
Recurdese que los resultados de una vista son construidos al instante sobre la tabla (o tablas) subyacente
cuando ejecutamos la vista. Como consecuencia, si la tabla subyacente es eliminada la validez de la vista
desaparece. Intentar una consulta sobre una vista cuya tabla subyacente ha sido eliminada produce un mensaje
de error.
Nota. La nica excepcin a esta regla es usar vistas materializadas. Una vista materializada es una
tabla que almacena datos que se obtendran normalmente a travs de una vista.

Oracle /88
Crear vistas basadas en una consulta que usa el asterisco para recuperar las columnas presenta un caso
especial. Por ejemplo, si creamos una vista sobre la tabla Alumno:
CREATE OR REPLACE VIEW Alumno_View AS
SELECT * FROM Alumno;
Y entonces alteramos la tabla subyacente:
ALTER TABLE Alumno ADD (pais VARCHAR2(30));
Ocurre que, a pesar del cambio de la tabla subyacente la vista es todava vlida; pero la columna pais no ser
visible a travs de la vista. Si despus de alterar la tabla, volvemos a compilar la vista, la nueva columna se
ver a travs de la vista.
9.5. Mostrar la lista de vistas.
La vista del diccionario de datos de Oracle USER_VIEWS permite mostrar una lista de todas las vistas que
posee el usuario actual. Es decir, para saber qu vistas hay disponibles se usa:
SELECT * FROM USER_VIEWS;
La columna TEXT de esa vista contiene la sentencia SQL que se utiliz para crear la vista (sentencia que es
ejecutada cada vez que se invoca a la vista).
9.6. Borrar vistas.
Se utiliza el comando DROP VIEW para eliminar una vista, como por ejemplo:
DROP VIEW nombreDeVista;

10. Comandos internos en SQL*PLUS e iSQL*Plus


Lo que se comenta en este apartado son comandos y operaciones que no pertenecen al lenguaje SQL, sino
que son comandos que sirven para dar instrucciones al programa SQL*Plus o iSQL*Plus.
Las operaciones que se comentan aqu son interpretadas por el cliente SQL*Plus y no por Oracle. Estas
operaciones sirven sobre todo para variar la forma en la que se muestran los resultados de las consultas SQL.
Hay que tener en cuenta que hay cierta diferencia entre los comandos SQL*Plus e iSQL*Plus.
10.1. Variables de sustitucin.
Se utilizan variables de sustitucin para poder pasar parmetros a una consulta. Por ejemplo, si a menudo se
realiza un listado de clientes en el que queremos mostrar los datos de un cliente identificado por su DNI,
entonces se puede utilizar una variable de sustitucin para el DNI, de modo que cada vez que se ejecute esa
consulta se pedir el nuevo valor de la variable.
10.1.1. Operador &.
La primera forma de utilizar variables de sustitucin es mediante el comando &. Este smbolo, utilizado en
cualquier parte de la consulta, permite rellenar el contenido de una variable de sustitucin. Por ejemplo:
SELECT * FROM Piezas WHERE modelo=&mod;
Al ejecutar esa sentencia, desde el cliente SQL*Plus se nos pedir rellenar el valor de la variable mod. Esa
variable no se puede volver a usar, si se usa se nos invitar a indicar el valor que le damos. La ventaja de esta
tcnica est en que cada vez que ejecutemos podremos dar un valor a la variable, lo que nos permite reutilizar
consultas una y otra vez para distintos valores, sin tener que rescribirla.
En el caso de que la variable sea de texto, hay que colocar el smbolo & dentro de las comillas que delimitan el
texto. Ejemplo:
SELECT * FROM Piezas WHERE tipo='&tip';
Es decir, se trata de una macro-sustitucin en la que el contenido de la variable se sustituye por su contenido
antes de pasar la instruccin a Oracle, de ah que sea necesario colocar las comillas, de otro modo Oracle
indicara que la instruccin es errnea.
10.1.2. Comando DEFINE.
Se pueden utilizar variables de sustitucin que se definan como variables de usuario mediante el comando
DEFINE. La sintaxis de este comando es:
DEFINE variable=valor;
La variable se sobreentiende que es de tipo texto. El valor es el contenido inicial de la variable. La variable as
creada tiene vigencia durante toda la sesin de usuario. Se elimina en el cierre de la sesin o si se usa el
comando UNDEFINE indicando el nombre de la variable a eliminar.
Para cambiar el valor de la variable se debe utilizar otra vez el comando DEFINE. La ventaja respecto al
mtodo anterior est en que la misma variable de sustitucin se puede utilizar para varios SELECT. La
desventaja est en que requiere tocar el cdigo para cambiar el valor de la variable. Ejemplo:

Oracle /89
DEFINE tip='TU';
SELECT * FROM piezas WHERE tipo='&tip';
SELECT * FROM existencias WHERE tipo='&tip';
En el ejemplo, los dos SELECT muestran piezas cuyo tipo sea TU. SQL*Plus no preguntar por el valor de la
variable tip.
El comando DEFINE sin nada ms permite mostrar una lista de todas las variables definidas en ese momento.
10.1.3. Operador &&.
Se trata de una mezcla entre las opciones anteriores. Cuando en una consulta se utiliza una variable de
sustitucin mediante dos smbolos ampersand, entonces al ejecutar la consulta se nos preguntar el valor.
Pero luego ya no, la variable queda definida como si se hubiera declarado con DEFINE.
El resto de veces que se utilice la variable, se usa con un solo &. El cambio de valor de la variable habr que
realizarle con DEFINE.
10.2. Comando SET.
Este comando permite cambiar el valor de las variables de entorno del programa. Su uso es:
SET nombreVariable valor
Las variables ms interesantes a utilizar son:
Variable Posibles valoresExplicacin
ECHO ON y OFF Repite el comando SQL antes de mostrar su resultado.
TIMING ON y OFF Permite mostrar estadsticas sobre el tiempo de ejecucin en
cada consulta SQL que se ejecute (interesante para
estadsticas).
HEADING ON y OFF Hace que el encabezado con los alias de las columnas se active
o no.
WRAP ON y OFF Activado, trunca un texto si sobrepasa la anchura mxima.
COMPATIBILITY V7, V8, NATIVE Permite indicar la versin con la que se comprueba la
compatibilidad de los comandos. NATIVE indica que el propio
servidor Oracle decide la compatibilidad.
DEFINE &, caracter, ON y OFF Permite activar y desactivar la posibilidad de usar variables de
sustitucin. Permite indicar el carcter utilizado para la
sustitucin de variables.
PAGESIZE n Indica el nmero de filas que se muestran antes de repetir el
encabezado de la consulta
LINESIZE n Indica la anchura mxima de la lnea de la consulta. Si una lnea
de la consulta sobrepasa este valor, los datos pasan a la
siguiente. Tambin influye sobre los tamaos y posiciones de
los encabezados y pies de los informes.
NULL valor Indica qu valor se muestra cuando hay nulos.
NUMFORMAT formato Permite especificar un formato que se aplicar a todos los
nmeros. (Vase formato de columnas, ms adelante).
NUMWIDTH valor Indica la anchura mxima utilizada para mostrar nmeros. Si
un nmero sobrepasa esta anchura, es redondeado.
FEEDBACK n, ON y OFF Hace que se muestren el nmero total de registros de la
consulta cuando el resultado supera los n registros.
LONG ancho Anchura mxima para los campos de tipo LONG.
El comando SHOW seguido del nombre de uno de los parmetros de la tabla anterior, permite mostrar el
estado actual del parmetro indicado. Si se usa SHOW ALL, entonces se muestran todos.
10.3. Encabezado y pie de informe.
Los parmetros BTITLE y TTITLE permiten, respectivamente, indicar un texto de pie y de encabezado para la
consulta. El formato es
{B|T}TITLE {texto|ON|OFF}
El texto es lo que se desea en el encabezado o pie. Ese texto puede incluir las palabras LEFT, RIGHT o CENTER
para hacer que el texto vaya a izquierda, centro o derecha respectivamente.
Se pueden indicar incluso las tres cosas a la vez:
TTITLE LEFT 'informe1' RIGHT 'estudio de clientes';
Se puede tambin usar la palabra COL seguida del nmero de columna en el que se desea el texto:

Oracle /90
TTITLE COL 50 'informe1';
Tambin se puede indicar la palabra TAB seguida de un nmero que representar tabulaciones, haciendo que
SQL*Plus deje ese espacio en los encabezados o pies.
10.4. Comando COLUMN.
Permite especificar un formato de columna. Si se usa sin modificador (slo COLUMNS o su abreviatura COL) se
muestran las configuraciones de formato de columnas actualmente en uso. Si se aade el nombre de una
columna, se indica el formato actual (si lo hay) para esa columna.
10.4.1. Aadir formato de columna.
Si se usa COLUMN (o COL) con el parmetro HEADING seguido de un texto, el texto se convierte en la cabecera
de la columna (sustituyendo al alias de la columna). Ese texto slo sirve para ser mostrado, no puede formar
parte de una sentencia SQL.
COLUMN precio_venta HEADING 'Precio de|venta';
SELECT tipo, modelo, precio_venta FROM piezas;
En el ejemplo, la barra vertical provoca un salto de lnea en el texto.
El parmetro FORMAT permite indicar una mscara de formato para el texto. Se usan cdigos especiales para
ello.
A los textos se les puede colocar una anchura mxima de columna. Eso se hace con una A seguida del
nmero que indica esa anchura.
COLUMN tipo FORMAT 'A10';
SELECT tipo, modelo, precio_venta FROM piezas;
Para los nmeros se usan cdigos de posicin:
Cdigo Significado
9 Posicin para un nmero. Si el valor es 0 o vaco, entonces no se muestra nada
0 Posicin para un nmero. Si el valor es 0 o vaco, entonces se muestra 0
$ Posicin para el signo de dlar
MI Muestra un signo menos tras el nmero, si el nmero es negativo (ejemplo: '999MI')
S Muestra el signo del nmero (+ -) en la posicin en la que se coloca el signo
PR Muestra los nmeros negativos entre < y >
D Muestra el signo decimal en esa posicin
G Muestra el signo de grupo en esa posicin
. Muestra el punto (separador decimal)
, Muestra la coma (separador de miles)
L Muestra el smbolo de moneda nacional en esa posicin
RN Muestra el nmero en romano (maysculas)
rn Muestra el nmero en romano (minsculas)
Las fechas deben ser formateadas desde la propia instruccin SQL mediante la funcin TO_CHAR (vista en un
tema anterior)
10.4.2. Parmetro LIKE.
Permite copiar atributos de una columna a otra:
COLUMN precio_venta FORMAT '9G990D00L';
COLUMN precio_compra LIKE precio_venta;
Las dos columnas tendrn el mismo formato (separador de miles, decimales y moneda tras los dos decimales)
10.4.3. Parmetro NULL.
Indica un texto que sustituir a los valores nulos.
10.4.4. Parmetro CLEAR.
Elimina el formato de la columna.
Lgicamente se pueden combinar varias acciones a la vez.
10.5. Comando BREAK.
Es uno de los comandos ms poderosos. Permite realizar agrupaciones en las consultas, consiguiendo
verdaderos informes (en especial si se combina con COMPUTE).
Permite dividir la vista en secciones en base al valor de un campo al que se le pueden incluso quitar los
duplicados. El comando:
BREAK ON tipo;
Hace que las columnas con alias tipo no muestren los duplicados, mostrando una vez cada valor duplicado.

Oracle /91
Para el buen funcionamiento de la orden, el resultado debe de estar ordenado por esa columna.
Se pueden hacer varios grupos a la vez:
BREAK ON tipo ON modelo;
La orden CLEAR BREAK elimina todos los BREAK anteriormente colocados.
10.5.1. Parmetro SKIP.
A la instruccin anterior se le puede aadir la palabra SKIP seguida de un nmero. Ese nmero indica las
lneas que se dejan tras el valor del grupo al imprimir. Si se indica SKIP PAGE, significa que se salta una pgina
completa cada vez que cambie el valor del grupo.
10.5.2. Parmetro ON REPORT.
Permite (en unin con COMPUTE) realizar clculos de totales sobre el informe completo.
10.5.3. Parmetros DUPLICATES y NODUPLICATES.
Permiten mostrar o no los duplicados de cada seccin. La opcin inicial es NODUPLICATES.
10.6. Comando COMPUTE.
Permite en unin con BREAK realizar clculos para las secciones de una consulta. Todo COMPUTE est
asociado a un apartado ON de una instruccin BREAK previa. Sintaxis:
COM[PUTE] [funcin [LAB[EL] texto] OF columna_o_Alias ON {columna_o_Alias|REPORT}
Donde:
funcin, es el nombre de la funcin de clculo que se usa ( SUM, AVG, MIN, MAX, NUM, STD o VAR).
LABEL, permite indicar un texto previo al resultado del clculo, si no se utiliza se pone el nombre de la
funcin utilizada.
OF, indica el nombre de columna o alias utilizado en la instruccin SELECT a partir de la que se realiza el
clculo.
ON, indica el nombre de columna o alias que define la seccin sobre la que se realizar el clculo. Este
nombre debe haber sido indicado en un BREAK anterior.
REPORT, indica que el clculo se calcular para toda la consulta.
Por ejemplo:
CLEAR BREAK;
COLUMN TIPO FORMAT A20;
BREAK ON tipo SKIP PAGE ON modelo ON REPORT;
COMPUTE SUM LABEL 'Total' MAX LABEL 'Mximo' OF cantidad ON tipo;
COMPUTE SUM LABEL 'Total' OF cantidad ON modelo;
COMPUTE SUM LABEL 'Total absoluto' OF cantidad ON REPORT;
SELECT tipo, modelo, n_almacen, cantidad FROM existencias
WHERE tipo='AR' OR tipo='TU' ORDER BY tipo, modelo;
Producir el siguiente resultado:

Oracle /92
10.7. Guardar consultas en ficheros.
Podemos guardar consulta en un fichero de texto y despus ejecutarlo desde SQL*Plus. Debemos guardar el
archivo con extensin .sql para que sea reconocido sin problemas.
Para ejecutar el archivo se utiliza el comando START o la sintaxis @archivo desde la lnea de comandos de
SQL*Plus.
Como ejemplo, supongamos el archivo siguiente:
Archivo comandos.sql
SET PAGESIZE 40
SET LINESIZE 80
SELECT IdObra, Nombre, Precio
FROM Obra
/
Ahora podemos ejecutarlo desde SQL*Plus mediante el comando:
SQL> @comandos.sql
O bien:
SQL> START comandos.sql
10.8. Redirigir la salida de SQL*Plus con SPOOL.
Oracle permite redirigir la salida de los comandos en SQL*Plus a un fichero de texto. Esto se consigue
mediante el comando SPOOL.
SQL> SPOOL /tmp/mi_fichero_de_texto.lst
Deberemos tener en cuenta que:
Los datos de salida no se materializarn en el fichero de texto hasta que se ejecute el comando SPOOL
OFF.
Si vamos a redirigir muchos datos tendremos que modificar la variable de entorno SERVEROUTPUT para
darle un tamao mayor.
El siguiente sera un ejemplo de utilizacin de SPOOL donde se desea un listado en un fichero de texto con la
ruta "d:\tmp\listado.lst":
SQL> SET SERVEROUTPUT ON SIZE 10000

Oracle /93
SQL> SPOOL d:\tmp\listado.lst
SQL> PROMPT TEST
SQL> SPOOL OFF
Si ahora leemos el contenido del archivo listado.lst veremos que contiene lo mismo que se mostr por
pantalla.
11. Consultas avanzadas
11.1. Consultas con ROWNUM.
La pseudo-columna ROWNUM devuelve un nmero para cada fila de salida de un SELECT, que se corresponde
con el orden en que son generadas las filas a partir de los registros de origen. Por ejemplo, la consulta
siguiente:
SELECT ROWNUM AS "Orden", nif, apellidos FROM Alumno WHERE localidad = 'Madrid';
Produce un resultado como ste:
ORDEN NIF APELLIDOS
1 44444444L Lpez Martn
2 55555555V Senn Rivas
3 33333333H Garca Gmez
Si aplicamos una ordenacin por nif:
SELECT ROWNUM AS "Orden", nif, apellidos FROM Alumno WHERE localidad = 'Madrid' ORDER BY nif;
Se producir el siguiente resultado:
ORDEN NIF APELLIDOS
3 33333333H Garca Gmez
1 44444444L Lpez Martn
2 55555555V Senn Rivas

Como vemos, ROWNUM no se corresponde con la ordenacin establecida, sino con el orden en que fueron
generadas las filas antes de su ordenacin. Si deseamos establecer una secuencia desde 1 sobre el resultado de
la ordenacin deberemos aplicar ROWNUM sobre una subconsulta:
SELECT ROWNUM AS "Orden", nif, apellidos
FROM (SELECT nif, apellidos FROM Alumno WHERE localidad = 'Madrid' ORDER BY nif);
Puesto que la subconsulta obtiene una lista de los alumnos ordenada por nif, el SELECT superior obtendr esa
lista pero mostrando el orden de las filas en esa consulta. Eso permite hacer consultas del tipo top-n (los n
ms...).
Por ejemplo, para sacar el top-10 de los alumnos con mejor nota media:
SELECT nif AS "Alumno"
FROM (SELECT nif, AVG(valor) FROM Nota GROUP BY nif ORDER BY AVG(valor))
WHERE ROWNUM<=10;
Cuando se usa ROWNUM para filtrar registros hay que tener en cuenta las siguientes normas:
- Se puede comparar por igualdad ROWNUM con el valor 1, pero no con cualquier otro valor.
- Se puede comparar ROWNUM mediante el operador menor que (o menor o igual que) con un nmero,
pero no se puede comparar con el operador mayor que (o mayor o igual que).
Por ejemplo, la siguiente consulta no retornara ningn registro:
SELECT * FROM Alumno WHERE ROWNUM > 1
Este comportamiento se produce por el siguiente motivo: el valor de ROWNUM es asignado a cada fila luego
de que pasa la fase de predicado de la consulta pero antes que la consulta pase por algn ordenamiento o
agregacin; adems, cada valor de ROWNUM es incrementado solamente luego de ser asignado, lo que explica
por qu la consulta no devuelve ninguna fila. Debido a que ROWNUM > 1 no es verdadero para la primera fila,
ROWNUM nunca avanza al valor 2.
11.2. Consultas con ROWID.
El tipo de dato ROWID permite almacenar la direccin que tiene una fila dentro de su tabla. Cada vez que se
inserta un registro en la base de datos Oracle genera un valor hexadecimal de tipo ROWID para el nuevo
registro con el formato siguiente:
OOOOOOFFFBBBBBBRRR
Donde:

Oracle /94
OOOOOO: es el segmento de la base de datos. Todos los objetos que estn en el mismo esquema y en el
mismo segmento tendrn el mismo valor.
FFF: es el nmero de fichero del tablespace relativo que contiene la fila.
BBBBBB: es el bloque de datos que contiene a la fila. El nmero de bloque es relativo a su fichero de datos,
no al tablespace. Por lo tanto, dos filas con nmeros de bloque iguales podran residir en diferentes
ficheros de datos del mismo tablespace.
RRR: es el nmero de fila en el bloque.
Por tanto no existen dos filas en la base de datos con el mismo ROWID. Este valor es slo accesible mediante
la pseudo-columna ROWID, por ejemplo:
SELECT ROWID, nombre, apellidos FROM Alumno;
Siempre que queramos obtener una fila de la forma ms rpida posible, debemos hacerlo a travs de su
ROWID. Un uso tpico suele ser obtener un listado de ROWID's con un SELECT, y despus acceder a cada una
de las filas directamente con la condicin del ROWID.
Esta pseudo-columna tambin puede ser til para consultar ciertos aspectos fsicos sobre las tablas de nuestra
base de datos. Por ejemplo, una forma de saber en cuntos ficheros de datos est alojada una tabla sera
consultando la parte de ROWID correspondiente.
SELECT COUNT(DISTINCT SUBSTR(ROWID,7,3)) "Nmero ficheros" FROM Alumno;
11.3. Consultas con RANK.
Podemos crear vistas sobre consultas de agrupacin para realizar informes de resumen complejos sobre los
datos. Las vistas de una agrupacin simplifican la representacin de los datos para varios niveles de
agrupacin dentro de nuestra aplicacin. Esto hace que sea ms sencillo usar funcionalidades analticas
avanzadas.
Consideremos la tabla NOTA para crear un vista que proporcione la nota media de cada alumno.
CREATE VIEW NOTAS_AVG AS (nif, notaMedia)
SELECT nif, AVG(valor) FROM Nota GROUP BY nif;
Podemos obtener un listado de los alumnos, ordenados de mayor a menor, por los que tienen mejor nota
media:
SELECT * FROM NOTAS_AVG ORDER BY notaMedia DESC;
Siendo un posible resultado el siguiente:
NIF NOTAMEDIA
---------------- -----------------
00000000A 9,8
22222222B 8
33333333C 8
44444444D 6,5
55555555E 5,3
Este resultado muestra la clasificacin de los alumnos por su nota media; el alumno de nif '00000000A' es el
primero en cuanto a mejores notas. Sin mostrar esta lista, es posible determinar dnde debera estar un valor
determinado de nota media en esta clasificacin. Para hacer esto se usa la funcin RANK; la cual toma un valor
como entrada y usa clusulas adicionales (WITHIN GROUP y ORDER BY) para decirle a Oracle cmo crear la
clasificacin. Por ejemplo, para saber en que posicin de la clasificacin debera estar la nota media 7
podemos efectuar la siguiente consulta:
SELECT RANK(7) WITHIN GROUP (ORDER BY notaMedia DESC) "Ranking"
FROM NOTAS_AVG;
Siendo el resultado:
RANKING
----------------
4
El valor 4 indica la posicin en el resultado de la clasificacin que debera ocupar un registro con el valor 7 en
la columna NOTAMEDIA.
Desde una perspectiva de porcentaje, podemos aplicar la funcin PERCENT_RANK para obtener la clasificacin
de la nota media 7:
SELECT PERCENT_RANK(7) WITHIN GROUP (ORDER BY notaMedia DESC) "Ranking"
FROM NOTAS_AVG;
Siendo el resultado:

Oracle /95
RANKING
----------------
,6
Es decir, estara en una posicin casi intermedia (con el 60%).
Con esta tcnica de usar vistas de resumen y funciones analticas podemos crear vistas e informes que
incluyan medias ponderadas, produccin eficaz, porcentajes de totales, porcentajes de subtotales, y muchos
clculos similares.
11.4. Consultas sobre estructuras jerrquicas.
Imaginemos una tabla de empleados definida por un cdigo de empleado, nombre del mismo y el cdigo del
jefe:
CREATE TABLE Empleado (
codigo NUMBER PRIMARY KEY,
nombre NVARCHAR2(100),
codigoJefe NUMBER REFERENCES Empleado(codigo));
E insertamos los siguientes registros:
CODIGO NOMBRE CODIGOJEFE
------------ ------------ ------------------
1 ngel
2 Eva 1
3 Andrs 2
4 Antonio 1
5 Carmen 2
6 Carmelo 3
Este ltimo cdigo est relacionado con el cdigo de empleado que posee el jefe en cuestin. As definido,
una consulta que muestre el nombre de un empleado y el nombre de su jefe directo, sera:
SELECT E.nombre AS empleado, J.nombre AS jefe
FROM Empleado EJOIN Empleado J ON (E.codigoJefe=J.codigo);
Obtendramos por ejemplo:
EMPLEADO JEFE
-------------- ----------
Antonio ngel
ngel
Eva ngel
Carmen Eva
Andrs Eva
Carmelo Andrs
En el ejemplo se observa como un jefe puede tener otro jefe, generando una estructura jerrquica:

En este tipo de estructuras a veces se requieren consultas que muestren todos los empleados de un jefe,
mostrando los mandos intermedios. Se trata de una consulta que recorre ese rbol. Este tipo de consultas
posee esta sintaxis:
SELECT [LEVEL,] listaDeColumnasYExpresiones
FROM tabla(s)...
[WHERE condiciones...]
[START WITH condiciones]
CONNECT BY [PRIOR] expresion1=[PRIOR] expresion2
El apartado CONNECT permite indicar qu relacin hay que seguir para recorrer el rbol. La palabra PRIOR
indica hacia dnde se dirige el recorrido. Finalmente el apartado START indica la condicin de inicio del
recorrido (normalmente la condicin que permita buscar el nodo del rbol por el que comenzamos el
recorrido); es decir, sirve para indicar desde dnde comenzamos.

Oracle /96
El siguiente ejemplo obtiene los jefes jerrquicos del empleado 'Andrs':
SELECT nombre
FROM Empleado
START WITH nombre='Andrs'
CONNECT BY PRIOR codigoJefe = codigo;
Y el resultado es:
NOMBRE
------------
Andrs
Eva
ngel
Sin embargo, la siguiente consulta:
SELECT nombre
FROM Empleado
START WITH nombre='Andrs'
CONNECT BY codigoJefe= PRIOR codigo;
Devuelve los subordinados de 'Andrs':
NOMBRE
------------
Andrs
Carmelo
El modificador LEVEL permite mostrar el nivel en el rbol jerrquico de cada elemento:
SELECT LEVEL, nombre
FROM Empleado
START WITH nombre='ngel'
CONNECT BY codigoJefe= PRIOR codigo;
Y el resultado es:
LEVEL NOMBRE
-------- ------------
1 ngel
2 Antonio
2 Eva
3 Carmen
3 Andrs
4 Carmelo
Para eliminar recorridos se utilizan condiciones en WHERE o en el propio CONNECT. De modo que:
SELECT LEVEL, nombre
FROM Empleado
WHERE nombre<>'Eva'
START WITH nombre='ngel'
CONNECT BY codigoJefe= PRIOR codigo;
En este ejemplo, Eva no sale en los resultados. En este otro:
SELECT LEVEL, nombre
FROM Empleado
START WITH nombre='ngel'
CONNECT BY codigoJefe= PRIOR codigo AND nombre<>'Eva';
No sale ni Eva ni sus empleados (se corta la rama entera).
Usar CONNECT BY y START WITH para crear informes no es difcil, pero deben seguirse ciertas reglas bsicas:
El orden de las clusulas debe ser siempre como sigue:
1. SELECT
2. FROM
3. WHERE
4. START WITH
5. CONNECT BY
6. ORDER BY
PRIOR fuerza que los informes vayan desde la raz hacia las hojas (si la columna previa es el padre) o de
una hoja hacia la raz (si la columna previa es el hijo).

Oracle /97
Una clusula WHERE elimina nodos del rbol, pero no as a sus descendientes (o ancestros).
Una cualificacin en CONNECT BY (particularmente un no igual) elimina nodos y sus descendientes (o
ancestros).
CONNECT BY no puede ser usado con una tabla enlazada en la clusula WHERE.
11.5. Consultas de agrupacin avanzada.
La expresin ROLLUP en una consulta de agrupacin (GROUP BY) permite obtener los resmenes parciales o
totales sobre las funciones de agregado utilizadas en las columnas de la consulta.
Por ejemplo, la siguiente consulta obtiene la nota de cada alumno en cada mdulo:
SELECT N.nif, M.nombre, AVG(valor) AS "Nota"
FROM Nota N JOIN Modulo M ON N.idModulo=M.idModulo
GROUP BY N.nif, M.nombre;
Como cada alumno tiene una nica nota en cada mdulo, el resultado de la funcin AVG(valor) es el mismo
que valor. Pero si ahora aadimos:
SELECT N.nif, M.nombre, AVG(valor) AS "Nota media"
FROM Nota N JOIN Modulo M ON N.idModulo=M.idModulo
GROUP BY ROLLUP (N.nif, M.nombre);
Entonces nos aade un registro para cada alumno en el que aparece la media para ese alumno, y al final
mostrar un registro con la media global de todos los alumnos. Es decir, el resultado de esa consulta podra
ser algo como:
NIF NOMBRE NOTA MEDIA
11111111A Modulo1 5
11111111A Modulo2 6
11111111A 5,5
22222222B Modulo1 4
22222222B Modulo2 7
22222222B 5,5
33333333C Modulo1 8
33333333C Modulo2 9
33333333C 8,5
6,5
En ROLLUP se pueden unir varias columnas entre parntesis para tratarlas como si fueran una unidad:
SELECT N.nif, M.nombre, AVG(valor) AS "Nota media"
FROM Nota N JOIN Modulo M ON N.idModulo=M.idModulo
GROUP BY ROLLUP ( (N.nif, M.nombre) );
La diferencia respecto a la anterior es que slo muestra un resumen global para alumno y mdulo. Es decir,
slo una fila resumen donde todos los campos involucrados quedan a nulo.
NIF NOMBRE NOTA MEDIA
11111111A Modulo1 5
11111111A Modulo2 6
22222222B Modulo1 4
22222222B Modulo2 7
33333333C Modulo1 8
33333333C Modulo2 9
6,5
O se puede aplicar el ROLLUP sobre una nica expresin del GROUP BY:
SELECT N.nif, M.nombre, AVG(valor) AS "Nota media"
FROM Nota N JOIN Modulo M ON N.idModulo=M.idModulo
GROUP BY ROLLUP (N.nif), M.nombre;
Con lo cual se obtiene filas de resumen donde slo los campos incluidos en ROLLUP estarn a nulo:
NIF NOMBRE NOTA MEDIA
11111111A Modulo1 5
22222222B Modulo1 4
33333333C Modulo1 8
Modulo1 5,6

Oracle /98
11111111A Modulo2 6
22222222B Modulo2 7
33333333C Modulo2 9
Modulo2 7,3
La expresin CUBE es muy similar a ROLLUP, slo que sta calcula todos los resmenes relativos a los campos
involucrados. Ejemplo:
SELECT N.nif, M.nombre, AVG(valor) AS "Nota media"
FROM Nota N JOIN Modulo M ON N.idModulo=M.idModulo
GROUP BY CUBE (N.nif, M.nombre);
Y el resultado es:
NIF NOMBRE NOTA MEDIA
11111111A Modulo1 5
11111111A Modulo2 6
11111111A 5,5
22222222B Modulo1 4
22222222B Modulo2 7
22222222B 5,5
33333333C Modulo1 8
33333333C Modulo2 9
33333333C 8,5
Modulo1 5,6
Modulo2 7,3
6,5
Es decir, calcula medias por alumno, medias por mdulo, y la media total. (Obsrvese que las filas de
resumen se generan para cada combinacin de campos incluidos en CUBE a nulo.)
GROUPING es una funcin que se combina con ROLLUP o CUBE y que recibe uno o ms campos, e indica si la
fila muestra un resumen referido a los campos en cuestin (filas de resumen con esos campos a nulo). Si la
fila es un resumen de esos campos lo marca con 1, sino lo marca con 0. Por ejemplo:
SELECT N.nif, M.nombre, AVG(valor), GROUPING(N.nif) AS "SW_NIF", GROUPING(M.nombre) AS "SW_MOD"
FROM Nota N JOIN Modulo M ON N.idModulo=M.idModulo
GROUP BY CUBE (N.nif, M.nombre);
Genera el siguiente resultado:
NIF NOMBRE NOTA MEDIA SW_NIF SW_MOD
11111111A Modulo1 5 0 0
11111111A Modulo2 6 0 0
11111111A 5,5 0 1
22222222B Modulo1 4 0 0
22222222B Modulo2 7 0 0
22222222B 5,5 0 1
33333333C Modulo1 8 0 0
33333333C Modulo2 9 0 0
33333333C 8,5 0 1
Modulo1 5,6 1 0
Modulo2 7,3 1 0
6,5 1 1
Se utiliza sobre todo para preparar una consulta en la creacin de informes.
GROUPING SETS se trata de una mejora de Oracle 9i que permite realizar varias agrupaciones para la misma
consulta. Sintaxis:
SELECT...
...
GROUP BY GROUPING SETS (listaDeCampos1) [, (lista2)...]
Las listas indican los campos por los que se realiza la agrupacin. Por ejemplo, para obtener resmenes que
cuenten las faltas por alumno, mdulo y ao:
SELECT M.nif, F.idModulo, EXTRACT(year FROM fecha) AS "Ao", COUNT(*) AS "N faltas"
FROM Matricula M JOIN Falta F ON M.idMatricula=F.idMatricula

Oracle /99
GROUP BY GROUPING SETS ((M.nif, F.idModulo), (EXTRACT(year FROM fecha)));
Se pueden combinar agrupaciones de diversas formas creando consultas como:
SELECT M.nif, F.idModulo, EXTRACT(year FROM fecha) AS "Ao", COUNT(*) AS "N faltas"
FROM Matricula M JOIN Falta F ON M.idMatricula=F.idMatricula
GROUP BY M.nif, ROLLUP(F.idModulo) , CUBE(EXTRACT(year FROM fecha)) ;
Que mostrara un informe espectacular sobre las tablas anteriores. As como:
SELECT M.nif, F.idModulo, EXTRACT(year FROM fecha) AS "Ao", COUNT(*) AS "N faltas"
FROM Matricula M JOIN Falta F ON M.idMatricula=F.idMatricula
GROUP BY GROUPING SETS ( M.nif, EXTRACT(year FROM fecha) ) ,
GROUPING SETS ( F.idModulo, EXTRACT(year FROM fecha) );

Oracle /100
III. PL/SQL
PL/SQL amplia SQL con los elementos caractersticos de los lenguajes de programacin: variables,
sentencias de control de flujo, bucles, etc.
1. Estructura del lenguaje PL/SQL
Con PL/SQL vamos a poder programar las unidades procedimentales de la base de datos Oracle; stas son:
- Procedimientos almacenados
- Funciones
- Triggers
- Scripts
Pero adems, PL/SQL nos permite realizar programas sobre las siguientes herramientas de Oracle:
- Oracle Forms
- Oracle Reports
- Oracle Graphics
- Oracle Aplication Server
1.1. Fundamentos de PL/SQL.
Para programar en PL/SQL es necesario conocer sus fundamentos.
PL/SQL no es "case-sensitive", es decir, no diferencia maysculas de minsculas como otros lenguajes de
programacin como C o Java. Sin embargo, debemos recordar que Oracle es "case-sensitive" en la bsqueda
de texto.
1.1.1. Tipos de datos.
Los tipos de datos escalares que soporta PL/SQL se muestran a continuacin:
BINARY_DOUBLE* FLOAT NUMBER SMALLINT
BINARY_FLOAT* INT NUMERIC STRING
BINARY_INTEGER INTEGER NVARCHAR2 TIMESTAMP
BOOLEAN INTERVAL DAY PLS_INTEGER TIMESTAMP WITH
TO SECOND LOCAL TIME ZONE
CHAR INTERVAL YEAR POSITIVE TIMESTAMP WITH
TO MONTH TIME ZONE
CHARACTER LONG POSITIVEN UROWID
DATE LONG RAW RAW VARCHAR
DEC NATURAL REAL VARCHAR2
DECIMAL NATURALN ROWID
DOUBLE PRECISION NCHAR SIGNTYPE

* Desde Oracle Database 10g, los nuevos tipos de datos BINARY_FLOAT y BINARY_DOUBLE pueden
mejorar el rendimiento en aplicaciones que trabajan con nmero intensivamente, como en procesos de
datos cientficos.
Los tipos de datos compuestos que soporta PL/SQL se muestran a continuacin:
RECORD TABLE VARRAY
Los tipos de datos por referencia que soporta PL/SQL se muestran a continuacin:
REF CURSOR REF tipo_objeto
Los tipos de datos largos (LOB) que soporta PL/SQL se muestran a continuacin:
BFILE BLOB CLOB** NCLOB**

** Podemos convertir implcitamente de CLOB a NCLOB o de NCLOB a CLOB. Sin embargo, ya que puede
ser una operacin expansiva, podemos ayudarnos de las funciones TO_CLOB y TO_NCLOB.
1.1.2. Comentarios.
PL/SQL soporta varios estilos de comentarios, el de lnea simple y de multilnea, para lo cual son empleados
ciertos caracteres especiales como son:
-- Lnea simple

Oracle /101
REM Lnea simple

/*
Conjunto de Lneas
*/
1.2. Estructuras de control en PL/SQL.
Dentro de las rdenes de un bloque PL/SQL tambin existen sentencias de control del flujo del programa.
1.2.1. Bloque condicional IF.
El mandato IF tiene la siguiente sintaxis:
IF condicin THEN
-- hacer algo;
[ELSE
-- hacer algo;]
ENDIF;
Si queremos encadenar varios bloques IF debemos hacerlo de la siguiente manera:
IFV=1 THEN
-- hacer algo;
ELSE
IFV=2THEN
-- hacer algo;
ELSE
-- hacer algo;
END IF;
END IF;
1.2.2. Bloque CASE.
El mandato CASE permite seleccionar entre una secuencia de condiciones, y ejecutar una instruccin
correspondiente. El comando CASE evala una expresin y la compara con varios valores, o evala varias
expresiones lgicas y elige la primera verdadera.
Un ejemplo del primer caso es el siguiente:
n := 1;
CASE n
WHEN 1 THEN
-- hacer algo;
WHEN 2 THEN
-- hacer algo;
WHEN 3 THEN
-- hacer algo;
ELSE
-- hacer algo;
END CASE;
Un ejemplo del segunda caso es el siguiente:
n := 1;
CASE
WHEN n=1 THEN
-- hacer algo;
WHEN n>=2 AND n<4 THEN
-- hacer algo;
WHEN n>=4 THEN
-- hacer algo;
END CASE;
1.2.3. Bucles.
Otro tipo de sentencias de control del flujo de ejecucin son los bucles, dentro de los cuales podemos
encontrar bucles tales como LOOP, FOR y WHILE. La sintaxis de estos bloques de cdigo es la siguiente:
LOOP
sentencias;
...
EXIT [WHEN condicin];

Oracle /102
END LOOP;
Y para la orden WHILE tenemos la siguiente sintaxis:
WHILE condicin LOOP
sentencias;
...
END LOOP;
Podemos finalizar cualquiera de los bucles con la instruccin EXIT o bien EXIT WHEN condicin.
1.2.4. Bucle FOR.
El bucle FOR permite iterar sobre un rango de valores o sobre el resultado de una consulta.
El siguiente ejemplo itera sobre los valores del 10 al 1 inclusive en orden decreciente:
FOR contador IN REVERSE 1..10 LOOP
DBMS_OUTPUT.PUT_LINE( contador ); -- se imprime el valor
END LOOP;
El siguiente ejemplo accede al campo nombre de la tabla Producto y los imprime:
FOR p IN (SELECT nombre FROM Producto) LOOP
DBMS_OUTPUT.PUT_LINE( p.nombre ); -- se imprime el nombre
END LOOP;
1.2.5. Instruccin NULL.
Algunas clusulas de PL/SQL, como un bloque IF y otros, deben contener al menos una instruccin
ejecutable. Se puede utilizar la instruccin NULL para completar estos bloques sin que hagan nada.
Por ejemplo:
IF unaCondicin THEN
-- hacer algo;
ELSE
NULL; -- no se hace nada
END IF;
La instruccin NULL simplemente pasa el control a la siguiente instruccin.
2. Bloques PL/SQL.
2.1. Introduccin.
Un programa de PL/SQL est compuesto por bloques, teniendo al menos que estar compuesto por un
bloque.
Los bloques de PL/SQL pueden ser de los siguientes tipos:
- Bloques annimos: aquellos que no tienen un nombre.
- Subprogramas: aquellos que se crean como funciones o procedimientos con un nombre.
2.2. Estructura de un Bloque.
Los bloques PL/SQL presentan una estructura especfica compuesta de tres partes bien diferenciadas:
- La seccin declarativa, en donde se declaran todas los tipos de datos, constantes y variables que se van a
utilizar en la ejecucin del bloque.
- La seccin de ejecucin, que incluye las instrucciones a ejecutar en el bloque PL/SQL.
- La seccin de excepciones, en donde se definen los manejadores de errores que soportar el bloque.
Cada una de las partes anteriores se delimita por una palabra reservada, de modo que un bloque PL/SQL se
puede representar como sigue:
DECLARE | IS | AS
/*Parte declarativa*/
BEGIN
/*Parte de ejecucin*/
EXCEPTION
/*Parte de excepciones*/
END;
De las anteriores partes, nicamente la seccin de ejecucin es obligatoria, quedando delimitada entre las
clusulas BEGIN y END. Veamos un ejemplo de bloque PL/SQL muy genrico. Se trata de un bloque
annimo, es decir, no lo identifica ningn nombre. Los bloques annimos identifican su parte declarativa con
la palabra reservada DECLARE.
DECLARE

Oracle /103
/*Parte declarativa*/
nombre_variable DATE;
BEGIN
/*Parte de ejecucin
*Este cdigo asigna la fecha actual a la variable identificada por "nombre_variable"
*/
SELECT SYSDATEINTO nombre_variable FROM DUAL;
EXCEPTION
/*Parte de excepciones*/
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Se ha producido un error');
END;
2.3. Seccin de declaracin de variables.
En esta parte se declaran las variables que va a necesitar nuestro programa. Una variable se declara
asignndole un nombre o "identificador" seguido del tipo de valor que puede contener. Tambin se declaran
cursores, de gran utilidad para la consulta de datos, y excepciones definidas por el usuario. Tambin podemos
especificar si una variable ser constante, si puede contener valores nulos y asignarle un valor inicial.
La sintaxis genrica para la declaracin de constantes y variables es:
nombre_variable [CONSTANT] tipo_de_dato [NOT NULL] [:=valor_inicial]
Donde:
tipo_de_dato es el tipo de dato que va a poder almacenar la variable, ste puede ser cualquiera de los tipos
soportados por Oracle.
CONSTANT indica la definicin de una constante, cuyo valor no puede ser modificado. Se debe incluir la
inicializacin de la constante en su declaracin.
NOT NULL impide que a una variable se le asigne el valor nulo, y por tanto debe inicializarse a un valor
diferente de NULL.
La inicializacin puede incluir cualquier expresin legal de PL/SQL, que lgicamente debe corresponderse
con el tipo del identificador definido.
Los tipos escalares incluyen los definidos en SQL, ms los tipos VARCHAR y BOOLEAN. Este ltimo puede
tomar los valores TRUE, FALSE y NULL, y se suele utilizar para almacenar el resultado de alguna operacin
lgica.
Tambin es posible definir el tipo de una variable o constante, dependiendo del tipo de otro identificador,
mediante la utilizacin de las clusulas %TYPE y %ROWTYPE. Mediante la primera opcin se define una variable
o constante escalar, y con la segunda se define una variable de tipo registro, donde el identificador puede ser
otra variable de tipo registro o una tabla. Habitualmente se utiliza %TYPE para definir la variable del mismo
tipo que tenga definido un campo en una tabla de la base de datos, mientras que %ROWTYPE se utiliza para
declarar variables utilizando cursores.
Ejemplos de estructura de un bloque annimo.
DECLARE
/* Se declara la variable de tipo VARCHAR2(15) identificada por v_location y se le asigna el valor "Granada"*/
v_location VARCHAR2(15) := 'Granada';
/*Se declara la constante de tipo NUMBER identificada por PI y se le asigna el valor 3,1416*/
PI CONSTANT NUMBER := 3.1416;
/*Se declara la variable del mismo tipo que tenga el campo nombre de la tabla tabla_empleados
* identificada por v_nombre y no se le asigna ningn valor */
v_nombre tabla_empleados.nombre%TYPE;
/*Se declara la variable del tipo registro correspondiente a un supuesto cursor, llamado
* micursor, identificada por reg_datos */
reg_datos micursor%ROWTYPE;
BEGIN
/*Parte de ejecucin*/
EXCEPTION
/*Parte de excepciones*/
END;
Ejemplo de estructura de un subprograma:
CREATE PROCEDURE simple_procedure IS

Oracle /104
/* Se declaran variables */
BEGIN
/*Parte de ejecucin*/
EXCEPTION
/*Parte de excepciones*/
END;
2.4. El paquete DBMS_OUTPUT.
El paquete DBMS_OUTPUT permite enviar mensajes desde un bloque PL (procedimiento, funcin, paquete o
trigger) de la base de datos.
Los procedimientos PUT y PUT_LINE de este paquete permiten colocar datos en un bfer que puede ser ledo
por otro bloque PL, que emplear el procedimiento GET_LINE para recuperar la informacin.
Si no se gestiona la recuperacin y presentacin de los datos incluidos en el bfer y si la ejecucin no se
realiza bajo SQL*Plus, los datos son ignorados. El principal inters de este paquete es facilitar la depuracin
de los programas.
Los procedimientos incluidos en este paquete son los siguientes:
DBMS_OUTPUT.DISABLE
Desactiva DBMS_OUTPUT y reinicializa el tamao del bfer al valor por defecto.
DBMS_OUTPUT.ENABLE(buffer_size IN INTEGER DEFAULT 20000)
Activa DBMS_OUTPUT y asigna el tamao del bfer, que puede ser entre 1 y 1000000.
DBMS_OUTPUT.GET_LINE(line OUT VARCHAR2, status OUT INTEGER);
Retorna una nica lnea del bfer. El siguiente ejemplo muestra como usar este procedimiento:
DECLARE
bufer VARCHAR2(100);
estado INTEGER;
BEGIN
DBMS_OUTPUT.PUT_LINE('Esto es');
DBMS_OUTPUT.PUT_LINE('una prueba.');
DBMS_OUTPUT.GET_LINE(bufer, estado);
DBMS_OUTPUT.PUT_LINE('Bfer: ' || bufer); -- Bfer: Esto es
DBMS_OUTPUT.PUT_LINE('Estado: ' || TO_CHAR(estado)); -- Estado: 0
END;
/
DBMS_OUTPUT.GET_LINES(lines OUT CHARARR, numlines IN OUT INTEGER);
Recupera un array de lneas desde el bfer. El siguiente ejemplo muestra cmo usar este procedimiento:
DECLARE
outtab DBMS_OUTPUT.CHARARR; -- un array de lneas de texto
fetchln INTEGER := 15;
BEGIN
outtab(1) := 'Esto es una prueba';
outtab(12) := 'de DBMS_OUTPUT.GET_LINES';
DBMS_OUTPUT.PUT_LINE('A: ' || outtab(1));
DBMS_OUTPUT.PUT_LINE('A: ' || outtab(12));
DBMS_OUTPUT.GET_LINES(outtab, fetchln);
DBMS_OUTPUT.PUT_LINE(TO_CHAR(fetchln)); -- 2
FOR i IN 1 .. fetchln LOOP
DBMS_OUTPUT.PUT_LINE('B: ' || outtab(i)); -- B: A: Esto es una prueba
END LOOP; -- B: A: de DBMS_OUTPUT.GET_LINES
END;
/
DBMS_OUTPUT.GET_LINES( linesOUT DBMSOUTPUT_LINESARRAY,numlines IN OUT INTEGER);
Recupera un array de lneas desde el bfer. El siguiente ejemplo muestra cmo usar este procedimiento:
DECLARE
lo DBMSOUTPUT_LINESARRAY := DBMSOUTPUT_LINESARRAY(10);
fetchln INTEGER := 15;
BEGIN
lo(1) := 'ABC';
lo.EXTEND;

Oracle /105
lo(2) := 'DEF';
lo.EXTEND;
lo(3) := 'GHI';
lo.EXTEND;
lo(4) := 'JKL';
lo.EXTEND;
lo(5) := 'MNO';
DBMS_OUTPUT.PUT_LINE('A: ' || lo(1));
DBMS_OUTPUT.PUT_LINE('A: ' || lo(2));
DBMS_OUTPUT.PUT_LINE('A: ' || lo(3));
DBMS_OUTPUT.PUT_LINE('A: ' || lo(4));
DBMS_OUTPUT.PUT_LINE('A: ' || lo(5));
DBMS_OUTPUT.GET_LINES(lo, fetchln);
DBMS_OUTPUT.PUT_LINE(TO_CHAR(fetchln)); -- 5
END;
/
DBMS_OUTPUT.NEW_LINE;
Inserta una marca de fin de lnea en el bfer.
DBMS_OUTPUT.PUT_LINE(a IN VARCHAR2);
Escribe una lnea de texto al bfer.
Con el procedimiento GET_LINE se puede leer una lnea de datos del bfer y con el procedimiento GET_LINES
se puede extraer una tabla de filas. Despus de leer el bfer, todas las lneas que no se han ledo al hacer otra
llamada a los procedimientos PUT, PUT_LINE o NEW_LINE se eliminan, con el fin de evitar cualquier posible
confusin acerca de los datos.
Tambin podemos generar un mensaje hacia consola mediante DBMS_OUTPUT. En consolas de SQL*Plus,
previamente debemos activar el depurador activando la variable SERVEROUTPUT. Por ejemplo:
SET SERVEROUTPUT ON;
BEGIN
DBMS_OUTPUT.PUT_LINE ('Hola');
END;
2.5. Asignacin de variables.
Dentro de un bloque podemos asignar valores a las variables de varias formas:
Directamente mediante el operador de asignacin (:=). Por ejemplo:
DECLARE
Valor NUMBER(38,2);
BEGIN
Valor := 213.23;
END;
A travs de una consulta mediante el operador INTO. Por ejemplo:
DECLARE
Nota_minima NUMBER(2,0);
Nota_maxima NUMBER(2,0)
BEGIN
SELECT MIN(valor), MAX(valor) INTO Nota_minima, Nota_maxima FROM Nota;
END;
Debemos tener en cuenta que si la consulta no retorna registros o retorna ms de un registro se generar
una excepcin.
A travs de una instruccin de borrado mediante RETURNING...INTO. Por ejemplo:
DECLARE
nota_V NUMBER(2,0);
BEGIN
DELETE FROM Nota WHERE idNota=9
RETURNING valor INTO nota_V;
END;
Si queremos recuperar todos los valores de un registro podemos asignarlos a una variable de tipo registro
de la siguiente forma:
DECLARE

Oracle /106
fila_notaNota%ROWTYPE;
BEGIN
SELECT * INTO fila_nota FROM Nota WHERE idNota = 34;
DBMS_OUTPUT.PUT_LINE (fila_nota.valor); -- Imprime el valor de nota del registro recuperado
END;

3. Excepciones en PL/SQL.
3.1. Manejo de excepciones.
En PL/SQL una advertencia o condicin de error es llamada una excepcin. Las excepciones se controlan
dentro de su propio bloque.
Cuando ocurre un error se ejecuta la porcin del programa marcada por el bloque EXCEPTION, transfirindose
el control a ese bloque de sentencias.
El siguiente ejemplo muestra un bloque de excepciones que captura las excepciones NO_DATA_FOUND y
ZERO_DIVIDE. Cualquier otra excepcin ser capturada en el bloque WHEN OTHERS THEN.
DECLARE
-- Declaraciones
BEGIN
-- Ejecucin
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Se ejecuta cuando ocurre una excepcin de tipo NO_DATA_FOUND
WHEN ZERO_DIVIDE THEN
-- Se ejecuta cuando ocurre una excepcin de tipo ZERO_DIVIDE
WHEN OTHERS THEN
-- Se ejecuta cuando ocurre una excepcin de un tipo no tratado en los bloques anteriores
END;
Si existe un bloque de excepcin apropiado para el tipo de excepcin se ejecuta dicho bloque. Si no existe un
bloque de control de excepciones adecuado al tipo de excepcin se ejecutar el bloque de excepcin WHEN
OTHERS THEN (si existe!). WHEN OTHERS debe ser el ltimo manejador de excepciones.
Las excepciones pueden ser definidas en forma interna o explcitamente por el usuario. Ejemplos de
excepciones definidas en forma interna son la divisin por cero y la falta de memoria en tiempo de ejecucin.
Estas mismas condiciones excepcionales tienen sus propio tipos y pueden ser referenciadas por ellos:
ZERO_DIVIDE y STORAGE_ERROR.
Las excepciones definidas por el usuario deben ser lanzadas explcitamente utilizando la sentencia RAISE.
3.2. Excepciones predefinidas.
PL/SQL proporciona un gran nmero de excepciones predefinidas que permiten controlar las condiciones de
error ms habituales.
Las excepciones predefinidas no necesitan ser declaradas. Simplemente se utilizan cuando stas son lanzadas
por algn error determinado. La siguiente es la lista de las excepciones predeterminadas por PL/SQL y una
breve descripcin de cundo son accionadas:
Excepcin Se ejecuta ... SQLCODE
ACCESS_INTO_NULL El programa intent asignar valores a los atributos de un objeto -6530
no inicializado
COLLECTION_IS_NULL El programa intent asignar valores a una tabla anidada an no -6531
inicializada
CURSOR_ALREADY_OPEN El programa intent abrir un cursor que ya se encontraba -6511
abierto. Recuerde que un cursor de ciclo FOR automticamente
lo abre y ello no se debe especificar con la sentencia OPEN
DUP_VAL_ON_INDEX El programa intent almacenar valores duplicados en una -1
columna que se mantiene con restriccin de integridad de un
ndice de unicidad
INVALID_CURSOR El programa intent efectuar una operacin no vlida sobre un -1001
cursor
INVALID_NUMBER En una sentencia SQL, la conversin de una cadena de -1722
caracteres hacia un nmero falla cuando esa cadena no
representa un nmero vlido

Oracle /107
LOGIN_DENIED El programa intent conectarse a Oracle con un nombre de -1017
usuario o contrasea invlido
NO_DATA_FOUND Una sentencia SELECT INTO no devolvi valores o el 100
programa referenci un elemento no inicializado en una tabla
indexada
NOT_LOGGED_ON El programa efectu una llamada a Oracle sin estar conectado -1012
PROGRAM_ERROR PL/SQL tiene un problema interno -6501
ROWTYPE_MISMATCH Los elementos de una asignacin (el valor a asignar y la variable -6504
que lo contendr) tienen tipos incompatibles. Tambin se
presenta este error cuando un parmetro pasado a un
subprograma no es del tipo esperado
SELF_IS_NULL El parmetro SELF (el primero que es pasado a un mtodo -30625
MEMBER) es nulo
STORAGE_ERROR La memoria se termin o est corrupta -6500
SUBSCRIPT_BEYOND_COUNT El programa est tratando de referenciar un elemento de un -6533
arreglo indexado que se encuentra en una posicin ms grande
que el nmero real de elementos de la coleccin
SUBSCRIPT_OUTSIDE_LIMIT El programa est referenciando un elemento de un arreglo -6532
utilizando un nmero fuera del rango permitido (por ejemplo, el
elemento "-1")
SYS_INVALID_ROWID La conversin de una cadena de caracteres hacia un tipo ROWID -1410
fall porque la cadena no representa un nmero
TIMEOUT_ON_RESOURCE Se excedi el tiempo mximo de espera por un recurso en -51
Oracle
TOO_MANY_ROWS Una sentencia SELECT INTO devuelve ms de una fila -1422
VALUE_ERROR Ocurri un error aritmtico, de conversin o truncamiento. Por -6502
ejemplo, sucede cuando se intenta calzar un valor muy grande
dentro de una variable ms pequea
ZERO_DIVIDE El programa intent efectuar una divisin por cero -1476

3.3. Excepciones definidas por el usuario.


PL/SQL permite al usuario definir sus propias excepciones, las que debern ser declaradas y lanzadas
explcitamente utilizando la sentencia RAISE.
Las excepciones deben ser declaradas en el segmento de declaracin de un bloque, subprograma o paquete.
Se declara una excepcin como cualquier otra variable, asignndole el tipo EXCEPTION. Las mismas reglas de
alcance que se aplican a las variables tambin se aplican sobre las excepciones.
DECLARE
MyExcepcion EXCEPTION;
BEGIN
-- Algn cdigo que lanza la excepcin personalizada
EXCEPTION
WHEN MyExcepcion THEN
-- Se ha capturado la excepcin personalizada
END;
3.3.1. Reglas de alcance.
Una excepcin es vlida dentro de su mbito de alcance, es decir, el bloque o programa donde ha sido
declarada. Las excepciones predefinidas son siempre vlidas.
Como las variables, una excepcin declarada en un bloque es local a ese bloque y global a todos los sub-
bloques que comprende.
3.3.2. La sentencia RAISE.
La sentencia RAISE permite lanzar una excepcin en forma explcita. Es posible utilizar esta sentencia en
cualquier lugar que se encuentre dentro del alcance de la excepcin.
DECLARE
-- Declaramos una excepcin identificada por VALOR_NEGATIVO
VALOR_NEGATIVO EXCEPTION;
valor NUMBER;
BEGIN

Oracle /108
valor := -1;
IF valor < 0 THEN
RAISE VALOR_NEGATIVO;
END IF;
EXCEPTION
WHEN VALOR_NEGATIVO THEN
DBMS_OUTPUT.PUT_LINE('El valor no puede ser negativo');
END;
Con la sentencia RAISE podemos lanzar una excepcin definida por el usuario o predefinida, siendo el
comportamiento habitual lanzar excepciones definidas por el usuario.
3.4. Uso de SQLCODE y SQLERRM.
Al manejar una excepcin es posible usar las funciones predefinidas SQLCODE y SQLERRM para aclarar al
usuario la situacin de error acontecida.
SQLCODE devuelve el nmero del error de Oracle y un 0 (cero) en caso de xito al ejecutarse una sentencia
SQL. Por otra parte, SQLERRM devuelve el correspondiente mensaje de error.
El siguiente ejemplo muestra el uso de estas dos funciones:
DECLARE
err_num NUMBER;
err_msg VARCHAR2(255);
result NUMBER;
BEGIN
SELECT 1/0 INTO result FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SQLERRM;
DBMS_OUTPUT.PUT_LINE('Error:'||TO_CHAR(err_num));
DBMS_OUTPUT.PUT_LINE(err_msg);
END;
Tambin es posible entregarle a la funcin SQLERRM un nmero negativo que represente un error de Oracle y
sta devolver el mensaje asociado.
DECLARE
msg VARCHAR2(255);
BEGIN
msg := SQLERRM(-1403);
DBMS_OUTPUT.PUT_LINE(MSG);
END;
3.5. Excepciones personalizadas en PL/SQL.
En ocasiones queremos enviar un mensaje de error personalizado al producirse una excepcin PL/SQL. Para
ello es necesario utilizar la instruccin RAISE_APPLICATION_ERROR.
La sintaxis general es la siguiente:
RAISE_APPLICATION_ERROR ( error_num , mensaje );
Siendo error_num es un entero negativo comprendido entre -20001 y -20999, y mensaje la descripcin del
error.
3.6. Propagacin de excepciones en PL/SQL.
Una de las caractersticas ms interesantes de las excepciones es la propagacin de las mismas. Cuando se
lanza una excepcin, el control se transfiere hasta la seccin EXCEPTION del bloque donde se ha producido la
excepcin. Entonces se busca un manejador vlido de la excepcin ( WHEN excepcin THEN, WHEN OTHERS
THEN) dentro del bloque actual.
En el caso de que no se encuentre ningn manejador vlido el control del programa se desplaza hasta el
bloque EXCEPTION del bloque que ha realizado la llamada PL/SQL.
4. Cursores
PL/SQL utiliza habitualmente cursores para gestionar las instrucciones SELECT. Un cursor es un objeto que
gestiona el conjunto de registros afectados por una instruccin SQL. Tcnicamente, los cursores son

Oracle /109
fragmentos de memoria reservados para procesar los resultados de una consulta SELECT.
Podemos distinguir dos tipos de cursores:
Cursores implcitos. Este tipo de cursores se utiliza para operaciones SELECT INTO. Normalmente se
usan cuando la consulta devuelve un nico registro.
Cursores explcitos. Son los cursores que son declarados y controlados por el programador. Se utilizan
cuando la consulta devuelve un conjunto de registros. Ocasionalmente tambin se utilizan en consultas
que devuelven un nico registro por razones de eficiencia, ya que son ms rpidos.
4.1. Cursores implcitos.
Los cursores implcitos se referencian con el identificador SQL, y poseen los siguientes atributos:
SQL%ROWCOUNT: cuenta el nmero de filas que fueron accedidas en la ltima operacin.
SQL%FOUND: Posee el valor TRUE si el atributo SQL%ROWCOUNT es igual o mayor que uno; es decir, que
se asigna a valor TRUE si se ha accedido a alguna fila.
SQL%NOTFOUND: Poseer el valor TRUE si el atributo SQL%FOUND tiene el valor FALSE; es decir, este
atributo toma el valor TRUE si en la ltima operacin no se accedi a ninguna fila.
SQL%ISOPEN: este atributo indica si el cursor est abierto. Posee siempre el valor FALSE, porque
PL/SQL cierra los cursores implcitos inmediatamente despus de ser ejecutados.
Como ejemplo de uso de un cursor implcito, el siguiente boque PL/SQL imprime el nmero de columnas
que han sido borradas:
DECLARE
v_id NUMBER:=605;
BEGIN
DELETE FROM Nota WHERE idModulo =v_id;
DBMS_OUTPUT.PUT_LINE( SQL%ROWCOUNT );
END;
Para operaciones de tipo SELECT, los cursores implcitos slo pueden devolver una fila, por lo que pueden
producirse determinadas excepciones. Las ms comunes que se pueden encontrar son NO_DATA_FOUND y
TOO_MANY_ROWS.
4.2. Cursores explcitos.
Los cursores explcitos son definidos por el usuario, y a la zona de memoria del cursor se le asigna una
sentencia SELECT. Para controlar un cursor explcito debemos seguir los siguientes pasos:
1) Declarar el cursor en el bloque declarativo.
2) Abrir el cursor con el comando OPEN. Con ello se cursor se sita sobre el primer resultado del comando
asociado.
3) Leer la primera fila con el comando FETCH.
4) Comprobar si se ha ledo algo, y si es necesario seguir leyendo con FETCH.
5) Cerrar el cursor con el comando CLOSE.
La sintaxis de declaracin de un cursor, es la siguiente:
CURSOR nombreCursor IS sentencia_Select;
Donde sentencia_Select es una sentencia SELECT cualquiera, que puede incluir cualquier tipo de restriccin.
La sintaxis ms bsica de los comandos OPEN y CLOSE es:
OPEN nombreCursor;
CLOSE nombreCursor;
Cuando queramos recuperar informacin del cursor, deberemos utilizar el comando FETCH con la siguiente
sintaxis:
FETCH nombreCursor INTO variable1, variable2, ...;
Este comando devolver la fila actual cada vez que sea ejecutado, y avanzar a la siguiente posicin dentro del
conjunto de filas que devuelve la consulta especificada en la declaracin del cursor.
El funcionamiento de los atributos de los cursores vistos anteriormente (%ROWCOUNT, %FOUND,
%NOTFOUND, %ISOPEN) es similar en los cursores explcitos, solo que el valor de %ISOPEN puede ser TRUE en
este caso si el cursor esta abierto.
Existe un tipo de bucle especfico para cursores, que ejecuta automticamente las rdenes OPEN, CLOSE y
FETCH. Se trata de una variante del bucle FOR, cuya sintaxis es la siguiente:
FOR fila IN nombreCursor LOOP
-- La variable "fila" es definida automticamente del tipo de registro del cursor
-- y contiene los datos del registro actual

Oracle /110
...
END LOOP;
En caso de usar otro tipo de bucle, se debera especificar la condicin de salida del mismo (normalmente
cuando el cursor haya recorrido todas las filas); en ese caso la condicin de salida ser:
EXIT WHEN nombreCursor%NOTFOUND;
Por ejemplo, veamos dos formas de realizar la misma accin: una mediante el bucle FOR antes mencionado, y
otra mediante la forma clsica. As, mediante la forma clsica, podramos crear un cursor para mostrar el nif y
apellidos de todos los alumnos:
DECLARE
CURSOR c1 ISSELECT nif, apellidos FROM Alumno;
c1_record c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO c1_record;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( c1_record.nif );
DBMS_OUTPUT.PUT_LINE( c1_record.apellidos );
END LOOP;
CLOSE c1;
END;
Sin embargo, esto puede realizarse de forma mucho ms sencilla, utilizando el bucle LOOP de la siguiente
manera:
DECLARE
CURSOR c1 ISSELECT nif, apellidos FROM Alumno;
BEGIN
FOR fila IN c1 LOOP
DBMS_OUTPUT.PUT_LINE( fila.nif );
DBMS_OUTPUT.PUT_LINE( fila.apellidos );
END LOOP;
END;
Esta misma operacin puede realizarse mediante un cursor implcito:
BEGIN
FOR fila IN (SELECT nif, apellidos FROM Alumno ) LOOP
DBMS_OUTPUT.PUT_LINE( fila.nif );
DBMS_OUTPUT.PUT_LINE( fila.apellidos );
END LOOP;
END;
4.3. Cursores con parmetros.
Los cursores explcitos pueden incluir parmetros para poder trabajar con datos que son establecidos despus
de la declaracin del cursor. Por ejemplo, el siguiente cdigo crea un cursor para recorrer los registros de
alumnos de una localidad determinada:
DECLARE
CURSOR c1 (p_localidadVARCHAR2) IS SELECT nif, apellidos FROM Alumno WHERE localidad=p_localidad;
BEGIN
FOR fila IN c1 ('Madrid')LOOP
DBMS_OUTPUT.PUT_LINE( fila.nif );
DBMS_OUTPUT.PUT_LINE( fila.apellidos );
END LOOP;
END;
El valor del parmetro es pasado en este caso al referenciar el cursor en la instruccin FOR. En otros casos se
pasar el parmetro al abrir el cursor con la instruccin OPEN:
OPEN c1('Madrid');
4.4. Cursores de actualizacin.
Se utilizan los cursores de actualizacin para determinar los registros afectados por una operacin UPDATE.
Para ello, tanto el cursor como el comando UPDATE deben utilizar la misma tabla base.

Oracle /111
Los cursores de actualizacin se declaran igual que los cursores explcitos, aadiendo FOR UPDATE al final de
la sentencia SELECT.
CURSOR nombre_cursor IS
instruccin_SELECT
FOR UPDATE
Para utilizar este tipo de cursor hay que ejecutar una sentencia UPDATE especificando la clusula WHERE
CURRENT OF nombre_cursor. La sintaxis es:
UPDATE nombre_tabla SET
campo_1 = valor_1
[, campo_2 = valor_2]
WHERE CURRENT OF nombre_cursor
El siguiente ejemplo muestra el uso de un cursor de actualizacin para actualizar las notas de los alumnos de
Madrid, incrementndolas en una unidad:
DECLARE
CURSOR c1 IS SELECT idNota FROM Nota WHERE nif IN
(SELECT nif FROM Alumno WHERE localidad='Madrid') FOR UPDATE;
v_idNota.idNota%TYPE;
BEGIN
OPEN c1;
FETCH c1 INTO v_id;
WHILE c1%FOUND LOOP
UPDATE NotaSET valor = valor + 1 WHERE CURRENT OF c1;
FETCH c1 INTO v_id;
END LOOP;
CLOSE c1;
COMMIT;
END;
Cuando trabajamos con cursores de actualizacin debemos tener en cuenta que generan bloqueos en la base
de datos.
5. Subprogramas en PL/SQL
Las reglas del negocio sofisticadas y la lgica de la aplicacin pueden ser almacenadas como procedimientos y
funciones dentro de Oracle. Los procedimientos almacenados (grupos de SQL, PL/SQL y comandos Java)
permiten mover cdigo que fuerza las reglas del negocio de nuestras aplicaciones a la base de datos. Como
resultado, el cdigo ser guardado una vez para ser usado por varias aplicaciones. Con este soporte de
subprogramas almacenados por parte de Oracle, el cdigo dentro de nuestras aplicaciones puede ser ms
consistente y fcil de mantener. Adems, podemos agrupar subprogramas, variables y tipos personalizados de
PL/SQL dentro de paquetes.
Podemos experimentar beneficios de rendimiento usando procedimientos, por dos razones:
El procesamiento de reglas del negocio complejas puede ser realizadas dentro de la base de datos (y por
tanto por el servidor). En el servidor cliente o en las aplicaciones de la capa intermedia, al mover
procesamientos complejos desde la aplicacin a la base de datos, se puede mejorar significativamente el
rendimiento.
Ya que el cdigo del procedimiento es almacenado dentro de la base de datos y es limpiamente esttico,
podemos beneficiarnos de reutilizar las mismas consultas dentro de la base de datos. El rea compartida en
el SGA almacenar las versiones parseadas de los comandos ejecutados. Por lo tanto, la segunda vez que
un comando es ejecutado, se puede tomar la ventaja de que ha sido parseado previamente, aumentando as
el rendimiento de la ejecucin del procedimiento.
Adems de estas dos ventajas, nuestro esfuerzo de desarrollo puede tambin beneficiarse. Las reglas del
negocio consolidadas dentro de la base de datos no necesitan ser escritas en cada aplicacin, con lo cual se
ahorra tiempo en la creacin de la aplicacin y se simplifica su proceso de mantenimiento.
5.1. Permisos requeridos.
Para crear un objeto procedimental debemos tener el permiso de sistema CREATE PROCEDURE. Si el objeto
procedimental es usado en otro esquema entonces debemos tener el permiso de sistema CREATE ANY
PROCEDURE.

Oracle /112
5.1.1. Ejecucin de procedimientos.
Una vez que el objeto procedimental ha sido creado podemos ejecutarlo. Cuando un procedimiento es
ejecutado podemos confiar en los permisos sobre tablas de sus propietarios o podemos confiar en los
permisos del usuario que lo est ejecutando. Cuando un procedimiento es creado usando los permisos de su
definidor, un usuario que ejecute el procedimiento no necesita que le concedan permisos sobre las tablas a las
que accede el procedimiento. Si un procedimiento confa en los derechos del invocador, el usuario debe tener
acceso a todos los objetos accedidos por el procedimiento.
Para permitir a otros usuarios ejecutar nuestros objetos procedimentales, debemos concederles el permiso
EXECUTE sobre el objeto, tal como se muestra a continuacin:
GRANT EXECUTE ON un_precedimiento TO un_usuario;
Si no concedemos el permiso EXECUTE al usuario, debe tener el permiso de sistema EXECUTE ANY PROCEDURE
para poder ejecutar el procedimiento.
5.1.2. Permisos requeridos sobre tablas.
Los objetos procedimentales pueden referenciar tablas. Para que estos objetos se ejecuten apropiadamente, el
propietario del procedimiento, paquete o funcin debe tener permisos sobre las tablas que usa. A menos que
estemos usando derechos de invocador, el usuario que est ejecutando el objeto procedimental no necesita
permisos sobre las tablas subyacentes.
Nota. Los permisos necesarios para procedimientos, paquetes y funciones no pueden venir de roles;
deben concederse directamente por el propietario del objeto.
5.2. Procedimientos, funciones y paquetes.
Los procedimientos no retornan un valor en su llamada. Las funciones pueden retornar un valor en su
llamada y pueden ser usadas directamente en consultas. El valor de una funcin es retornado a travs del uso
de la palabra clave RETURN dentro de la funcin.
Los paquetes son grupos de procedimientos, funciones, variables y comandos SQL agrupados dentro de una
simple unidad. Para ejecutar un procedimiento dentro de un paquete debemos primero identificar el nombre
del paquete y despus el nombre del procedimiento, tal como se muestra a continuacin:
EXECUTE PAQUETE_LIBRO.NUEVO_LIBRO('Un libro');
Aqu, el procedimiento NUEVO_LIBRO dentro del paquete PAQUETE_LIBRO es ejecutado.
Los paquetes permiten varios procedimientos que usan las mismas variables y cursores. Los procedimientos
dentro de los paquetes pueden ser pblicos o privados, en cuyo caso slo son accesibles dentro del cdigo del
paquete.
5.3. Procedimientos almacenados.
Un procedimiento es un subprograma que ejecuta una accin especfica y que no devuelve ningn valor en su
llamada. Un procedimiento tiene un nombre, un conjunto de parmetros (opcional) y un bloque de cdigo.
La sintaxis de un procedimiento almacenado es la siguiente:
CREATE [OR REPLACE]PROCEDURE
nombre_procedimiento [(parametro1 [IN|OUT|IN OUT] tipo, parametro2 [IN|OUT|IN OUT] tipo, ...)]
IS
-- Declaracin de variables locales
BEGIN
-- Sentencias
[EXCEPTION]
-- Sentencias de control de excepcin
END [nombre_procedimiento];
Eluso de OR REPLACE permite sobrescribir un procedimiento existente. Si se omite, y el procedimiento existe,
se producir un error al ejecutar el comando CREATE PROCEDURE.
La sintaxis es muy parecida a la de un bloque annimo, salvo porque se reemplaza la seccin DECLARE por la
secuencia PROCEDURE ... IS en la especificacin del procedimiento.
Debemos especificar el tipo de datos de cada parmetro. Al especificar el tipo de dato del parmetro no
debemos especificar la longitud del tipo.
Los parmetros pueden ser de entrada ( IN), de salida (OUT) o de entrada salida (IN OUT). El valor por defecto
es IN, y se toma ese valor en caso de que no especifiquemos nada.
Por ejemplo, el siguiente procedimiento actualiza una nota para un alumno y mdulo determinados:
CREATE OR REPLACEPROCEDURE

Oracle /113
Actualiza_Nota(pNif IN VARCHAR2, pIdModulo NUMBER, pNota NUMBER)
IS
-- Declaracin de variables locales
BEGIN
UPDATE Nota SET valor = pNota WHERE nif=pNif AND idModulo=pIdModulo;
END Actualiza_Nota;
Tambin podemos asignar un valor por defecto a los parmetros, utilizando la clusula DEFAULT o el
operador de asignacin (:=) .
CREATE PROCEDURE Actualiza_Nota(pNif IN VARCHAR2, pIdModulo NUMBER, pNota NUMBER DEFAULT 5)
...
Los parmetros con valores por defecto deben situarse al final de la lista de parmetros.
Una vez creado y compilado el procedimiento almacenado podemos ejecutarlo. Si el sistema nos indica que el
procedimiento se ha creado con errores de compilacin podemos ver estos errores de compilacin con la
orden SHOW ERRORS en SQL *Plus.
Existen dos formas de pasar argumentos a un procedimiento almacenado a la hora de ejecutarlo (en realidad
es vlido para cualquier subprograma). stas son:
Notacin posicional: Se pasan los valores de los parmetros en el mismo orden en que el PROCEDURE los
define.
BEGIN
Actualiza_Nota('2222222B', 1,8);
COMMIT;
END;
Notacin nominal: Se pasan los valores en cualquier orden nombrando explcitamente el parmetro.
BEGIN
Actualiza_Nota(pNif =>'2222222B',pIdModulo => 1, pNota =>8);
COMMIT;
END;
5.4. Funciones en PL/SQL.
Una funcin es un subprograma que devuelve un valor. La sintaxis para construir funciones es la siguiente:
CREATE [OR REPLACE]FUNCTION
nombre_funcin [(parmetro1 IN tipo, parmetro2 IN tipo, ...)]
RETURN Tipo_de_retorno
IS
result Tipo_de_retorno;
BEGIN
RETURN result;
[EXCEPTION]
-- Sentencias de control de excepcin
END [nombre_funcin];
El uso de OR REPLACE permite sobrescribir una funcin existente. Si se omite, y la funcin existe, se producir
un error el ejecutar el comando CREATE FUNCTION.
La sintaxis de los parmetros es la misma que en los procedimientos almacenado.
Como ejemplo, la siguiente funcin retorna la nota media de un alumno:
CREATE OR REPLACEFUNCTION fn_NotaMedia (pNif VARCHAR2)RETURN NUMBER
IS
result NUMBER;
BEGIN
SELECT AVG(valor) INTO result FROM Nota WHERE nif = pNif;
RETURN result;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 0;
END ;
Si el sistema nos indica que la funcin se ha creado con errores de compilacin podemos ver estos errores de
compilacin con la orden SHOW ERRORS en SQL*Plus.
Una vez creada y compilada la funcin podemos ejecutarla de la siguiente forma:
DECLARE

Oracle /114
notaMedia NUMBER;
BEGIN
notaMedia := fn_NotaMedia ('2222222B');
END;
Las funciones pueden utilizarse en sentencias SQL de manipulacin de datos ( SELECT, UPDATE, INSERT y
DELETE) siempre y cuando no realicen operaciones de actualizacin en su cdigo:
SELECT nif, nombre, apellidos, fn_NotaMedia( nif )FROM Alumno;
5.5. Subprogramas en bloques procedimentales.
Dentro de la seccin declarativa de bloque annimo, un procedimiento o una funcin almacenada podemos
declarar subfunciones y subprocedimientos e invocarlos desde el bloque de ejecucin del script.
Este tipo de subprogramas son menos conocidos que los procedimientos almacenados, funciones y triggers,
pero son enormemente tiles.
El siguiente ejemplo declara y ejecuta utiliza una subfuncin (fn_multiplica_x2) en un bloque annimo
DECLARE
idx NUMBER;
/* Se declara la subfuncin */
FUNCTION fn_multiplica_x2(num NUMBER)
RETURN NUMBER
IS
result NUMBER;
BEGIN
result := num *2;
RETURN result;
END fn_multiplica_x2;
BEGIN
FOR idx IN 1..10
LOOP
DBMS_OUTPUT.PUT_LINE ('Llamada a la funcin ... '||TO_CHAR(fn_multiplica_x2(idx)));
END LOOP;
END;
Ntese que se utiliza la funcin TO_CHAR para convertir el resultado de la funcin fn_multiplica_x2 (numrico)
en alfanumrico y poder mostrar el resultado por pantalla.
5.6. Depurando procedimientos.
El comando SHOW ERRORS de SQL*Plus muestra todos los errores asociados con la ms reciente creacin de
objetos procedimentales. Este comando verifica la vista USER_ERRORS del diccionario de datos para mostrar
los errores asociados con la compilacin del procedimiento. SHOW ERRORS muestra la lnea y nmero de
columna de cada error, as como el texto del mensaje de error.
Para ver errores asociados con procedimientos creados previamente podemos consultar USER_ERRORS
directamente, tal como se muestra a continuacin. Este ejemplo consulta USER_ERRORS por mensajes de
error encontrados durante la creacin de una funcin Gastos_atrasados. Si un error es encontrado, las lneas en
el cdigo que provocan condiciones de error son retornadas por la consulta.
SELECT Line, /* Nmero de lnea del error. */
Position, /* Nmero de columna del error dentro de la lnea.*/
Text /* Texto del error.*/
FROM USER_ERRORS
WHERE Name = 'GASTOS_ATRASADOS'
AND TYPE = 'FUNCTION'
ORDER BY Sequence;
Valores vlidos para la columna Type son VIEW, PROCEDURE, PACKAGE, FUNCTION, y PACKAGE BODY. Los
otros dos niveles del diccionario de datos (ALL y DBA) pueden ser usados para recuperar informacin acerca
de errores involucrados con los objetos procedimiento.
5.7. Paquetes en PL/SQL.
Un paquete es una estructura que agrupa objetos de PL/SQL compilados (procedimientos, funciones,
variables, tipos, etc.) en la base de datos. Esto nos permite agrupar la funcionalidad de los procesos en
programas.

Oracle /115
Lo primero que debemos tener en cuenta es que los paquetes estn formados por dos partes: la especificacin
y el cuerpo. La especificacin del un paquete y su cuerpo se crean por separado.
5.7.1. Especificacin de un paquete.
La especificacin de un paquete es la interfaz pblica del paquete que ser usada por las aplicaciones. En ella
es posible declarar los tipos, variables, constantes, excepciones, cursores y subprogramas disponibles para su
uso posterior desde fuera del paquete. En la especificacin del paquete slo se declaran los objetos
(procedimientos, funciones, variables, ...), no se implementa el cdigo. Los objetos declarados en la
especificacin del paquete son accesibles desde fuera del paquete por otro script de PL/SQL o programa.
Haciendo una analoga con el mundo de C, la especificacin es como el archivo de cabecera de un programa
en C.
Para crear la especificacin de un paquete la sintaxis general es la siguiente:
CREATE [OR REPLACE] PACKAGE NombrePaquete
IS
-- Declaraciones de tipos y registros pblicas
TYPE NombreTipo IS TipoDeDato;
-- Declaraciones de variables y constantes pblicas
-- Tambin podemos declarar cursores
NombreConstante CONSTANT TipoDato := valor;
NombreVariable TipoDato;
-- Declaraciones de procedimientos y funciones pblicas
FUNCTION NombreFuncin (Parmetro TipoDato , ...) RETURN TipoDato;
PROCEDURE NombreProcedimiento (Parmetro TipoDato , ...);
END NombrePaquete;
5.7.2. Cuerpo de un paquete.
El cuerpo de un paquete es la implementacin privada del paquete. El cuerpo del paquete debe implementar
lo que se declar inicialmente en la especificacin. En el cuerpo de un paquete podemos declarar nuevos
subprogramas y tipos, pero estos sern privados para el propio paquete.
La sintaxis general para crear el cuerpo de un paquete es muy parecida al de la especificacin, tan solo se
aade la palabra clave BODY, y se implementa el cdigo de los subprogramas.
CREATE [OR REPLACE] PACKAGE BODY NombrePaquete
IS
-- Declaraciones de tipos y registros privados
TYPE NombreTipo IS TipoDato;
-- Declaraciones de variables y constantes privadas
-- Tambin podemos declarar cursores
NombreConstante CONSTANT TipoDato := valor;
NombreVariable TipoDato;
-- Implementacin de procedimientos y funciones
FUNCTION NombreFuncin(Parmetro TipoDato , ...)RETURN TipoDato
IS
-- Variables locales de la funcin
BEGIN
-- Implementacin de la funcin
END;
PROCEDURE NombreProcedimiento (Parmetro TipoDato , ...)
IS
-- Variables locales de la funcin
BEGIN
-- Implementacin de procedimiento
END;
END pkgName;
El siguiente ejemplo crea un paquete llamado PKG_ACADEMIA que incluye funciones y procedimientos para
procesar los datos de alumnos, matrculas, notas, etc. Para crear la especificacin del paquete:
CREATE OR REPLACE PACKAGE PKG_ACADEMIA
IS
-- Declaraciones de tipos y registros pblicas
TYPE Reg_ResumenNotas IS RECORD (

Oracle /116
minima NUMBER(2,0),
maxima NUMBER(2,0),
media NUMBER(2,2)
);
-- Declaraciones de variables y constantes pblicas
APROBADO CONSTANT INTEGER := 5;
SOBRESALIENTE CONSTANT INTEGER := 10;
ERROR_NO_EXISTE_ALUMNO EXCEPTION;
-- Declaraciones de procedimientos y funciones pblicas
PROCEDURE MatriculaAlumno (pNif VARCHAR2, pNombre VARCHAR2, pApellidos VARCHAR2,
pLocalidad VARCHAR2) ;
FUNCTION fn_Obtener_Resumen_Notas (pNif VARCHAR2) RETURN Reg_ResumeNotas;
END PKG_ACADEMIA;
Aqu slo hemos declarado las variables y constantes, y prototipado las funciones y procedimientos pblicos.
Es en el cuerpo del paquete donde debemos escribir el cdigo de los subprogramas MatriculaAlumno y
fn_Obtener_Resumen_Notas.
CREATE PACKAGE BODY PKG_ACADEMIA IS
-- Funcin privada para saber si existe un alumno
FUNCTION fn_Existe_Alumno (pNif VARCHAR2) RETURN INTEGER
IS
n INTEGER;
BEGIN
SELECT COUNT(*) INTO n FROM Alumno WHERE nif = pNif;
RETURN n;
END;
-- Funcin pblica
FUNCTION fn_Obtener_Resumen_Notas (pNif VARCHAR2) RETURN Reg_ResumeNotas
IS
result Reg_ResumenNotas;
BEGIN
IF fn_Existe_Alumno(pNif) THEN
SELECT MIN(valor), MAX(valor), AVG(valor) INTO result FROM Nota WHERE nif = pNif;
RETURN result;
ELSE
RAISE ERROR_NO_EXISTE_ALUMNO;
END IF;
END;
-- Procedimiento pblico
PROCEDURE MatriculaAlumno (pNif VARCHAR2, pNombre VARCHAR2, pApellidos VARCHAR2,
pLocalidad VARCHAR2)
IS
maxId INTEGER;
BEGIN
IF NOT fn_Existe_Alumno(pNif) THEN
INSERT INTO Alumno(nif,nombre,apellidos,localidad) VALUES (pNif,pNombre,pApellidos,pLocalidad);
END IF;
SELECT NVL(MAX(idMatricula, 0) INTO maxId FROM Matricula;
INSERT INTO Matricula(idMatricula,nif,ao) VALUES (maxId+1,pNif,EXTRACT(year FROM SYSDATE));
END;
END PKG_ACADEMIA;
Es posible modificar el cuerpo de un paquete sin necesidad de alterar por ello la especificacin del mismo.
Los paquetes pueden llegar a ser programas muy complejos y suelen almacenar gran parte de la lgica de
negocio.
5.7.3. Inicializacin de paquetes.
Los paquetes pueden incluir cdigo que puede ser ejecutado la primera vez que un usuario ejecuta una
funcin o procedimiento del paquete durante cada sesin. En el siguiente ejemplo, el paquete GESTOR_LIBRO
incluye en su cuerpo un comando SQL que registra el nombre del usuario y el tiempo de la primera vez que
ejecuta un componente del usuario dentro de la sesin. Se incluyen dos variables dentro del paquete para

Oracle /117
registrar estos valores. Al ser declaradas dentro del cuerpo del paquete no estn disponibles para el pblico.
El cdigo de inicializacin del paquete se muestra resaltado en el siguiente listado:
CREATE OR REPLACE PACKAGE BODY GESTOR_LIBRO
AS
Nombre_usuario VARCHAR2(30);
Fecha_entrada DATE;
/*
Definicin de otros componentes del paquete
*/
BEGIN
SELECT USER, SYSDATE INTO Nombre_Usuario, Fecha_Entrada
FROM DUAL;
END GESTOR_LIBRO;
/

Nota. El cdigo que ser ejecutado la primera vez que un componente del paquete es ejecutado es
almacenado en su propio bloque PL/SQL al final del cuerpo del paquete. No tiene su propia
clusula END, sino que usa la clusula END del paquete.
5.8. Viendo el cdigo fuente de objetos procedimentales.
El cdigo fuente de procedimientos, funciones y paquetes, y cuerpos de paquete puede ser consultado con las
siguientes vistas del diccionario de datos:
USER_SOURCE Para objetos propiedad del usuario.
ALL_SOURCE Para objetos propiedad del usuario o a los cuales el usuario tiene permisos de acceso.
DBA_SOURCE Para todos los objetos de la base de datos.
Se selecciona informacin desde la vista USER_SOURCE mediante una consulta similar a la mostrada a
continuacin. En este ejemplo se selecciona la columna Text y se ordena por el nmero de lnea. El nombre y
tipo del objeto se utilizan para indicar qu cdigo fuente ser mostrado. El siguiente ejemplo usa un
procedimiento llamado Nuevo_Libro.
SELECT Text
FROM USER_SOURCE
WHERE Name = 'NUEVO_LIBRO' AND Type = 'PROCEDURE'
ORDER BY Line;
TEXT
-------------------------------------------------------------------------------------------
PROCEDURE NUEVO_LIBRO (PTitulo IN VARCHAR2, PEditor IN VARCHAR2,
PCategoria IN VARCHAR2)
AS
BEGIN
INSERT INTO BOOKSHELF (Titulo, Editor, Categoria)
VALUES (PTitulo, PEditor, PCategoria);
DELETE FROM PEDIDO_LIBRO
WHERE Titulo = PTitulo;
END;
Como se ve en este ejemplo, la vista USER_SOURCE contiene un registro por cada lnea del procedimiento
NUEVO_LIBRO. La secuencia de la lnea es mantenida por la columna Line; por lo tanto, la columna Line
debera ser usada para ordenar el resultado.
Valores vlidos para la columna Type son PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY, JAVA SOURCE,
TYPE, y TYPE BODY.
5.9. Compilando procedimientos, funciones y paquetes.
Oracle compila los objetos procedimentales cuando son creados. Sin embargo, los objetos procedimentales
pueden ser invlidos si los objetos de la base de datos que referencian cambian. La siguiente vez que los
objetos procedimentales sean ejecutados sern recompilados por la base de datos.
Podemos evitar esta compilacin en tiempo de ejecucin (y la degradacin de rendimiento que esto puede
causar) recompilando explcitamente los procedimientos, funciones y paquetes. Para recompilar un
procedimiento se usa el comando ALTER PROCEDURE, tal como se muestra a continuacin. La clusula

Oracle /118
COMPILE es una opcin slo vlida par este comando.
ALTER PROCEDURE Nuevo_Libro COMPILE;
Para recompilar un procedimiento debemos ser el propietario o tener el permiso de sistema ALTER ANY
PROCEDURE.
Para recompilar una funcin se usa el comando ALTER FUNCTION con la clusula COMPILE:
ALTER FUNCTION Libros_Cambiados COMPILE;
Para recompilar una funcin debemos ser el propietario o tener el permiso de sistema ALTER ANY PROCEDURE.
Cuando recompilamos paquetes podemos recompilar tanto la especificacin del paquete como su cuerpo, o
bien slo el cuerpo del paquete. Por defecto se recompilan tanto la especificacin del paquete como su
cuerpo. No podemos usar los comandos ALTER FUNCTION o ALTER PROCEDURE para recompilar las funciones
y procedimientos dentro del paquete. Si slo ha cambiado el cdigo de alguna funcin o procedimiento
dentro del paquete slo es necesario recompilar el cuerpo del paquete. Para ello se utiliza la siguiente sintaxis:
ALTER PACKAGE [usuario.]nombre_del_paquete COMPILE [DEBUG] [PACKAGE | BODY | SPECIFICATION];
Para recompilar un paquete se usa el comando precedente con la clusula COMPILE, tal como sigue:
ALTER PACKAGE GESTOR_LIBRO COMPILE;
Para recompilar un paquete debemos ser su propietario o debemos tener el permiso de sistema ALTER ANY
PROCEDURE. Ya que no se especific PACKAGE ni BODY en el ejemplo precedente, se us por defecto PACKAGE,
con lo cual se recompil tanto la especificacin como el cuerpo del paquete.
6. Transacciones
No todas las operaciones SQL son transaccionales. Slo son transaccionales las operaciones correspondientes
al DML, es decir, sentencias SELECT, INSERT, UPDATE y DELETE. Una transaccin comienza con la primera
instruccin DML que se ejecute y finaliza con alguna de estas circunstancias:
- Una operacin COMMIT o ROLLBACK.
- Una instruccin DDL (como ALTER TABLE, por ejemplo).
- Una instruccin DCL (como GRANT).
- El usuario abandona la sesin.
- Se produce una cada del sistema.
Hay que tener en cuenta que cualquier instruccin DDL o DCL da lugar a un COMMIT implcito; es decir,
todas las instrucciones DML ejecutadas hasta ese instante pasan a ser definitivas.
6.1. Estado de los datos durante la transaccin.
Si se inicia una transaccin usando comandos DML hay que tener en cuenta que:
- Se puede volver a la instruccin anterior a la transaccin cuando se desee.
- Las instrucciones de consulta SELECT realizadas por el usuario que inici la transaccin muestran los
datos ya modificados por las instrucciones DML.
- El resto de usuarios ven los datos tal cual estaban antes de la transaccin; de hecho, los registros
afectados por la transaccin aparecen bloqueados hasta que la transaccin finalice. Esos usuarios no
podrn modificar los valores de dichos registros.
Tras la transaccin todos los usuarios ven los datos tal cual quedan tras el fin de la transaccin. Los bloqueos
son liberados y los puntos de ruptura borrados.
6.2. Control de transacciones en PL/SQL.
Para confirmar una transaccin se utiliza la sentencia COMMIT. Cuando realizamos un COMMIT los cambios se
escriben en la base de datos.
Para deshacer una transaccin se utiliza la sentencia ROLLBACK. Cuando realizamos un ROLLBACK se deshacen
todas las modificaciones realizadas por la transaccin en la base de datos que todava no han sido
confirmadas, quedando la base de datos en el mismo estado que antes de iniciarse la transaccin.
En una transaccin los datos modificados no son visibles por el resto de usuarios hasta que se confirme la
transaccin.
Un abandono de sesin incorrecto o un problema de comunicacin o de cada del sistema dan lugar a un
ROLLBACK implcito.
El siguiente ejemplo muestra una supuesta transaccin bancaria:
DECLARE
importe NUMBER;
ctaOrigen VARCHAR2(23);

Oracle /119
ctaDestino VARCHAR2(23);
BEGIN
importe := 100;
ctaOrigen:= '2530 10 2000 1234567890';
ctaDestino := '2532 10 2010 0987654321';
UPDATE CUENTAS SET SALDO = SALDO importe WHERE CUENTA = ctaOrigen;
UPDATE CUENTAS SET SALDO = SALDO + importe WHERE CUENTA = ctaDestino;
INSERT INTO MOVIMIENTOS (CUENTA_ORIGEN, CUENTA_DESTINO,IMPORTE, FECHA_MOVIMIENTO)
VALUES (ctaOrigen, ctaDestino, importe*(-1), SYSDATE);
INSERT INTO MOVIMIENTOS (CUENTA_ORIGEN, CUENTA_DESTINO,IMPORTE, FECHA_MOVIMIENTO)
VALUES (ctaDestino,ctaOrigen, importe, SYSDATE);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error en la transaccin:'||SQLERRM);
DBMS_OUTPUT.PUT_LINE('Se deshacen las modificaciones);
ROLLBACK;
END;
Si alguna de las tablas afectadas por la transaccin tiene triggers, las operaciones que realiza el trigger estn
dentro del mbito de la transaccin, y son confirmadas o deshechas conjuntamente con la transaccin.
Durante la ejecucin de una transaccin, una segunda transaccin no podr ver los cambios realizados por la
primera transaccin hasta que stos se confirmen.
Oracle es completamente transaccional. Siempre debemos especificar si queremos deshacer o confirmar la
transaccin.
6.3. Puntos de ruptura.
La instruccin SAVEPOINT permite establecer un punto de ruptura en una transaccin. El problema de la
combinacin ROLLBACK/COMMIT es que un COMMIT acepta todo y un ROLLBACK anula todo. SAVEPOINT
permite sealar un punto intermedio entre el inicio de la transaccin y la situacin actual. Su sintaxis es:
...instrucciones DML...
SAVEPOINT nombreSavepoint;
....instrucciones DML...
Para regresar a un punto de ruptura concreto se utiliza el comando:
ROLLBACK TO SAVEPOINT nombreSavepoint;
Cuando se vuelve a un punto marcado, las instrucciones que siguieron a esa marca se anulan definitivamente.
Debemos tener en cuenta que si realizamos un ROOLBACK TO SAVEPOINT a un punto de ruptura al cual se ha
aplicado un COMMIT, se producir una excepcin. Por ejemplo, el siguiente cdigo producir una excepcin:
BEGIN
SAVEPOINT SP1;
DELETE FROM Alumno;
COMMIT;
ROLLBACK TO SAVEPOINT SP1; -- Se lanza una excepcin.
END;
6.4. Transacciones autnomas
En ocasiones es necesario que los datos escritos por parte de una transaccin sean persistentes, pero sin
afectar a la persistencia del resto de la transaccin.
PL/SQL permite marcar un bloque con PRAGMA AUTONOMOUS_TRANSACTION. Con esta directiva
marcamos un subprograma para que se comporte como una transaccin diferente a la del proceso principal,
llevando el control de COMMIT o ROLLBACK independientemente.
Obsrvese el siguiente ejemplo. Primero creamos un procedimiento y lo marcamos con PRAGMA
AUTONOMOUS_TRANSACTION.
CREATE OR REPLACE PROCEDURE Grabar_Log(descripcion VARCHAR2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO LOG_APLICACION (CO_ERROR, DESCRIPICION, FX_ERROR)
VALUES (SQ_ERROR.NEXTVAL, descripcion, SYSDATE);

Oracle /120
COMMIT; -- Este commit solo afecta a la transaccin autnoma
END ;
Cualquier COMMIT o ROLLBACK realizado dentro un subprograma autnomo slo afectar a las operaciones
realizadas dentro del subrpograma, y nunca a cualquier operacin previa pendiente de confirmar o rechazar.
A continuacin utilizamos el procedimiento desde un bloque de PL/SQL:
DECLARE
v_idModulo.idModulo%TYPE;
BEGIN
v_id := 99;
INSERT INTO Modulo (idModulo, nombre) VALUES (v_id, 'Modulo ' || v_id);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
Grabar_Log(SQLERRM);
ROLLBACK;
/* Los datos grabados por "Grabar_Log" se escriben en la base de datos a pesar del ROLLBACK,
* ya que el procedimiento autnomo contiene un COMMIT.
* Sin embargo, dicho COMMIT no confirma la operacin INSERT previa.
*/
END;
Es muy comn que, por ejemplo, en caso de que se produzca algn tipo de error queramos insertar un
registro en una tabla de log con el error que se ha producido y hacer ROLLBACK de la transaccin. Pero si
hacemos ROLLBACK de la transaccin tambin lo hacemos de la insercin del log.
7. Triggers
Un trigger define una accin que la base de datos debe realizar cuando ocurre algn evento. Se pueden usar
los triggers para aplicar integridad referencial adicional, forzar reglas del negocio complejas, o auditar cambios
en los datos. El cdigo dentro de un trigger, llamado el cuerpo del trigger, se escribe con un bloque PL/SQL.
La ejecucin del trigger es transparente para el usuario. Los triggers son ejecutados por la base de datos
cuando determinados tipos de comandos se ejecutan desde aplicaciones clientes. Estos comandos pueden
incluir inserciones, actualizaciones y borrados, operaciones DDL y operaciones DCL. La actualizacin de
columnas especficas puede tambin ser usada como eventos para lanzar triggers, as como inicios de sesin y
paradas en la base de datos.
7.1. Permisos requeridos.
Para crear un trigger sobre una tabla debemos ser capaces de modificar dicha tabla. Por lo tanto, debemos o
bien ser propietarios de la tabla o tener el permiso ALTER para la tabla, o tener el permiso de sistema ALTER
ANY TABLE. Adems, debemos tener el permiso de sistema CREATE TRIGGER; para crear triggers en otros
esquemas debemos tener el permiso de sistema CREATE ANY TRIGGER. El permiso CREATE TRIGGER es parte
del rol RESOURCE proporcionado con Oracle.
Para modificar un trigger debemos ser propietarios del mismo o tener el permiso de sistema ALTER ANY
TRIGGER. Podemos tambin habilitar o deshabilitar triggers modificando las tablas en las que est basado, lo
cual requiere que tengamos el permiso ALTER para la tabla o el permiso de sistema ALTER ANY TABLE.
Para crear un trigger sobre un evento del nivel de base de datos debemos tener el permiso de sistema
ADMINISTER DATABASETRIGGER.
Los triggers pueden referenciar otras tablas adems de la que produce el evento. Por ejemplo, si usamos
triggers para auditar cambios de datos en la tabla LIBRO, entonces podemos insertar un registro dentro de una
tabla diferente (como LIBRO_AUDIT) cada vez que un registro es cambiado en LIBRO. Para hacer esto
necesitamos tener el permiso para insertar dentro de LIBRO_AUDIT.
Nota. Los permisos necesarios para desencadenar transacciones no pueden venir de roles; deben
concederse directamente por el creador del trigger.
7.2. Tipos de triggers.
Se determina el tipo de un trigger por el tipo de transaccin desencadenada y por el nivel en el cual el trigger
es ejecutado.

Oracle /121
7.2.1. Triggers al nivel de fila.
Los triggers al nivel de fila se ejecutan para cada fila afectada por un comando DML. Para el ejemplo de
auditoria de la tabla LIBRO, cada fila que es cambiada en la tabla LIBRO puede ser procesada por el trigger. Los
triggers a nivel de fila son los ms comunes; se usan normalmente en aplicaciones de auditora de datos.
Tambin son normalmente usados para sincronizacin de datos. Las vistas materializadas usan internamente
triggers a nivel de fila para estos propsitos.
Los triggers a nivel de fila se crean usando la clusula FOR EACH ROW en el comando CREATE TRIGGER.
7.2.2. Triggers a nivel de comando.
Los triggers a nivel de comando se ejecutan una vez por cada comando DML. Por ejemplo, si un nico
comando INSERT inserta 500 filas dentro de la tabla LIBRO, se lanza un trigger a nivel de fila por cada registro
insertado, pero un nico trigger a nivel de comando para toda la tabla. Por lo tanto, los triggers a nivel de
comando no son normalmente usados para actividades relativas a los datos; son normalmente usados para
forzar medidas adicionales de seguridad sobre los tipos de acciones que podemos realizar sobre una tabla.
Los triggers a nivel de comando son el tipo de trigger por defecto creados mediante el comando CREATE
TRIGGER.
7.2.3. Triggers BEFORE y AFTER.
Ya que los triggers son ejecutados por eventos, pueden ocurrir inmediatamente antes o despus de estos
eventos. Ya que los eventos que ejecutan los triggers incluyen comandos DML de base de datos, pueden ser
ejecutados inmediatamente antes o despus de inserciones, actualizaciones o borrados. Para eventos al nivel
de base de datos, podemos aplicar restricciones adicionales; no podemos desencadenar un evento para que
ocurra antes de un inicio de sesin o un inicio de la base de datos.
Dentro del trigger podemos referenciar los antiguos y nuevos valores involucrados en un comando DML. El
acceso requerido por los datos antiguos y nuevos puede determinar qu tipo de trigger necesitamos.
Si necesitamos asignar un valor de columna en un registro insertado mediante nuestro trigger, entonces
podemos necesitar usar un trigger BEFORE INSERT para acceder a los nuevos valores. Usando un trigger
AFTER INSERT no podemos modificar los valores a insertar, ya que la fila ha sido realmente insertada dentro
de la tabla.
Los triggers AFTER del nivel de fila son usados frecuentemente en aplicaciones de auditora, ya que no se
lanzan hasta que la fila ha sido modificada. Las modificaciones sucedidas en la fila implican que han pasado
las restricciones de integridad referencial definidas para la tabla.
7.2.4. Triggers de sustitucin (INSTEAD OF).
Podemos usar triggers INSTEAD OF para decirle a Oracle qu hacer en vez de las acciones que invoca el
trigger. Por ejemplo, podemos usar un trigger INSTEAD OF sobre una vista para redirigir inserciones dentro de
una tabla o para actualizar varias tablas que son parte de una vista. Podemos usar triggers INSTEAD OF sobre
vistas de objetos o vistas relacionales.
Por ejemplo, si una vista involucra un join entre dos tablas, nuestra habilidad para usar el comando UPDATE
sobre los registros en la vista es limitada. Sin embargo, si usamos un trigger INSTEAD OF, podemos decirle a
Oracle cmo actualizar, borrar o insertar registros en las tablas subyacentes de la vista cuando un usuario
intente cambiar valores a travs de la vista. El cdigo en el trigger INSTEAD OF es ejecutado en lugar de la
insercin, actualizacin o borrado que entremos.
Nota. Podemos acceder o cambiar datos LOB dentro de triggers BEFORE e INSTEAD OF.
7.2.5. Triggers de esquema.
Podemos crear triggers sobre operaciones a nivel de esquema como un CREATE TABLE, ALTER TABLE, DROP
TABLE, AUDIT, RENAME, TRUNCATE, y REVOKE. An podemos crear un trigger BEFORE DDL. Principalmente,
los triggers de nivel de esquema proporcionan dos capacidades: la prevencin de operaciones DDL y
proporcionar supervisin de seguridad adicional con operaciones DDL.
7.2.6. Triggers al nivel de base de datos.
Podemos crear triggers que sean lanzados por eventos de base de datos, incluyendo errores, registros,
desconexiones, paradas e inicios de base de datos. Podemos usar este tipo de triggers para automatizar el
mantenimiento de base de datos o acciones de auditora. Las bases de datos virtuales privadas ejecutan
triggers a nivel de base de datos para establecer valores de variables del contexto de sesin.
7.3. Triggers asociados a tablas.
Normalmente se habla de un trigger asociado a una tabla como un bloque PL/SQL que se ejecuta como

Oracle /122
consecuencia de una determinada instruccin SQL (INSERT, UPDATE o DELETE) sobre dicha tabla.
7.3.1. Declaracin de los triggers.
La sintaxis para crear estos triggers es la siguiente:
CREATE [OR REPLACE] TRIGGER nombre_trigger
{BEFORE|AFTER|INSTEAD OF}
{DELETE|INSERT|UPDATE [OF col1, col2, ..., colN]
[OR {DELETE|INSERT|UPDATE [OF col1, col2, ..., colN]...]}
ON nombre_tabla
[FOR EACH ROW [WHEN (<condicin>)]]
DECLARE
-- variables locales
BEGIN
-- Sentencias
[EXCEPTION]
-- Sentencias de control de excepcin
END nombre_trigger;
El uso de OR REPLACE permite sobrescribir un trigger existente. Si se omite, y el trigger existe, se producir un
error al ejecutar el comando CREATE TRIGGER.
Los triggers pueden definirse para las operaciones INSERT, UPDATE o DELETE, y pueden ejecutarse antes o
despus de la operacin. Los modificadores BEFORE y AFTER indican que el trigger se lanzar antes o despus
de ejecutarse la sentencia SQL. Si incluimos el modificador OF, el trigger solo se ejecutar cuando la sentencia
SQL afecte a los campos incluidos en la lista.
El alcance de estos triggers puede ser a nivel de fila o de comando. El modificador FOR EACH ROW indica que
el trigger se disparar cada vez que se realizan operaciones sobre una fila de la tabla. Si se acompaa del
modificador WHEN, se puede establece una restriccin; el trigger solo actuar sobre las filas que satisfagan la
restriccin. (La clusula WHEN slo es vlida para los triggers con nivel de fila.)
7.3.2. Orden de ejecucin de los triggers.
Una misma tabla puede tener varios triggers asociados. En tal caso es necesario conocer el orden en el que se
van a ejecutar.
Los triggers se activan al ejecutarse la sentencia SQL:
Si existe, se ejecuta el disparador de tipo BEFORE (disparador previo) con nivel de comando.
Para cada fila a la que afecte el comando:
- Se ejecuta si existe, el disparador de tipo BEFORE con nivel de fila.
- Se ejecuta el propio comando.
- Se ejecuta si existe, el disparador de tipo AFTER (disparador posterior) con nivel de fila.
Se ejecuta, si existe, el disparador de tipo AFTER con nivel de comando.
7.3.3. Restricciones de los triggers.
El cuerpo de un trigger es un bloque PL/SQL. Cualquier comando que sea legal en un bloque PL/SQL, es
legal en el cuerpo de un trigger, con las siguientes restricciones:
- Un trigger no puede emitir ninguna orden de control de transacciones: COMMIT, ROLLBACK o
SAVEPOINT. El trigger se activa como parte de la ejecucin del comando que provoc el disparo, y forma
parte de la misma transaccin que dicho comando. Cuando el comando que provoca el disparo es
confirmado o cancelado, se confirma o cancela tambin el trabajo realizado por el trigger.
- Por razones idnticas, ningn procedimiento o funcin llamado por el trigger puede emitir rdenes de
control de transacciones.
- El cuerpo del trigger no puede contener ninguna declaracin de variables LONG o LONG RAW.
7.3.4. Utilizacin de las variables globales OLD y NEW.
Dentro del mbito de un trigger disponemos de las variables globales OLD y NEW. Estas variables se utilizan
del mismo modo que cualquier otra variable PL/SQL, con la salvedad de que no es necesario declararlas; son
del tipo %ROWTYPE de la tabla asociada al trigger y contienen una copia del registro antes ( OLD) y despus
(NEW) de la accin SQL que ha disparado el trigger. Utilizando estas variables podemos acceder a los datos
que se estn insertando, actualizando o borrando.
La siguiente tabla muestra los valores de OLD y NEW segn el comando que dispara el trigger.
Accin SQL OLD NEW
INSERT No definido; todos los campos toman Valores que sern insertados cuando se complete la

Oracle /123
valor NULL. orden.
UPDATE Valores originales de la fila, antes de la Nuevos valores que sern escritos cuando se
actualizacin. complete la orden.
DELETE Valores, antes del borrado de la fila. No definidos; todos los campos toman el valor NULL.

Nota. Los registros OLD y NEW son slo vlidos dentro de los triggers con nivel de fila (con la
especificacin FOR EACH ROW).
Por ejemplo, si queremos lanzar un trigger antes de que se actualice una nota, pero slo si el nuevo valor es
mayor que el antiguo valor, podramos utilizar el siguiente cdigo:
CREATE OR REPLACE TRIGGER TR_Nota_01
BEFORE UPDATE ON Nota
FOR EACH ROW WHEN (NEW.valor > OLD.valor)
BEGIN
-- Cdigo del Trigger
END ;
El siguiente ejemplo muestra un trigger que inserta automticamente un registro de matrcula con el ao
actual cada vez que insertamos un nuevo alumno en la base de datos (en este ejemplo se presupone creado un
objeto secuencia denominado SQ_IDMatricula):
CREATE OR REPLACE TRIGGER TR_Matricula_01
AFTER INSERT ON Alumno
FOR EACH ROW
BEGIN
INSERT INTO Matricula (idMatricula, nif, ao)
VALUES (SQ_IDMatricula.NEXT, :NEW.nif, EXTRACT(YEAR FROM SYSDATE));
END ;
El trigger se ejecutar automticamente cuando sobre la tabla Alumno se ejecute una sentencia INSERT como:
INSERT INTO Alumno (nif, nombre, apellidos, localidad)
VALUES ('66666666H', 'Juan' , 'Salgado Rey', 'Madrid');

Nota. Cuando se usa NEW y OLD en el cuerpo del trigger deben ir precedidos de dos punto (:); sin
embargo, cuando se usan en la clusula WHEN de FOR EACH ROW no deben ir precedidos de dos
puntos.
7.3.5. Utilizacin de las funciones INSERTING, UPDATING y DELETING.
Dentro de un trigger en el que se disparan distintos tipos de rdenes DML, hay tres funciones booleanas que
pueden emplearse para determinar de qu operacin se trata. Estas funciones son INSERTING, UPDATING y
DELETING.
Su comportamiento es el siguiente:
Funcin Retorna
INSERTING TRUE si el comando de disparo es INSERT; FALSE en otro caso.
UPDATING TRUE si el comando de disparo es UPDATE; FALSE en otro caso.
DELETING TRUE si el comando de disparo es DELETE; FALSE en otro caso.
Como ejemplo, el siguiente trigger normaliza el precio de un libro cuando se realizan inserciones o
actualizaciones en la tabla LIBRO. Si se inserta un nuevo registro redondea el precio, y se actualiza el precio
conserva el antiguo valor si es mayor que el nuevo.
CREATE OR REPLACE TRIGGER TR_Normaliza_Titulo
BEFORE INSERT OR UPDATE OF precio ON Libro
FOR EACH ROW
DECLARE
BEGIN
IF INSERTING THEN -- se est realizando una insercin
:NEW.precio := ROUND(:NEW.precio, 2);
END IF;
IF UPDATING AND :NEW.precio<ODL.precio THEN -- se est realizando una actualizacin
:NEW.precio := :OLD.precio;
END IF;
END;

Oracle /124
7.3.6. Uso de triggers para asignar claves automticamente.
Oracle no permite crear claves autonumricas, pero mediante el uso de secuenciadores y triggers podemos
simular esta funcionalidad.
Por ejemplo, si hemos creado la tabla Matricula con un campo clave idMatricula de tipo INTEGER, podemos
omitir la asignacin de este campo cada vez que hagamos una insercin de producto de la siguiente manera:
1) Creamos un secuenciador con el comando:
CREATE SEQUENCE SQ_IDMatricula;
2) Creamos un trigger como el siguiente:
CREATE TRIGGER TR_Pon_IDMatricula
BEFORE INSERT
ON Matricula
FOR EACH ROW
BEGIN
SELECT SQ_IDMatricula.NEXTVAL INTO :NEW.idMatricula FROM DUAL;
END;
Ahora, cada vez que se ejecute una instruccin INSERT sobre la tabla Matricula, tanto si pasamos un valor para
idMatricula como si no, se lanzar un trigger que asigne automticamente el valor.
7.4. Triggers para eventos DDL.
Podemos crear triggers que son ejecutados cuando ocurre un evento DDL. Si estamos planificando usar esta
funcionalidad para propsitos de seguridad, deberamos investigar usar el comando AUDIT en su lugar. Por
ejemplo, podemos usar un trigger DDL que se lance al ejecutar comandos CREATE, ALTER, y DROP sobre un
clster (cubo), funcin, ndice, paquete, procedimiento, rol, esquema, sinnimo, tabla, tablespace, trigger,
tipo, usuario o vista. Si usamos la clusula ON SCHEMA, el trigger se ejecutar para cada nuevo objeto del
diccionario de datos creado sobre nuestro esquema. El siguiente ejemplo ejecutar un procedimiento llamado
INSERT_AUDIT_RECORD si son creados objetos dentro de nuestro esquema:
CREATE OR REPLACE TRIGGER CREATE_DB_OBJECT_AUDIT
AFTER CREATE ON SCHEMA
BEGIN
CALL INSERT_AUDIT_RECORD (ORA_DICT_OBJ_NAME);
END;
/
Como muestra este ejemplo, podemos referenciar atributos del sistema (en el ejemplo,
ORA_DICT_OBJ_NAME, recupera el nombre del objeto creado). Los atributos disponibles se listan en la tabla
al final de esta seccin.
Para proteger los objetos dentro de un esquema podemos crear un trigger que sea ejecutado para cada intento
del comando DROP TABLE. Este trigger tendr que ser un trigger BEFORE DROP:
CREATE OR REPLACE TRIGGER PREVENT_DROP
BEFORE DROP ON Empleado.SCHEMA
BEGIN
IF ORA_DICT_OBJ_OWNER = 'Empleado' AND ORA_DICT_OBJ_NAME LIKE 'LIB%'
AND ORA_DICT_OBJ_TYPE = 'TABLE' THEN
RAISE_APPLICATION_ERROR (-20002, 'Operacin no permitida.');
END IF;
END;
/
Ntese que este trigger referencia los atributos de evento dentro cuerpo. Intentar borrar una tabla dentro del
esquema Empleado cuyo nombre comience por LIB resultar en lo siguiente:
DROP TABLE LIBRO_AUDIT_DUP;
DROP TABLE LIBRO_AUDIT_DUP
*
ERROR en lnea 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20002: Operacin no permitida.
ORA-06512: at line 6
Podemos usar el procedimiento RAISE_APPLICATION_ERROR para personalizar un mensaje de usuario que
queramos mostrar al usuario.

Oracle /125
La siguiente tabla describe los atributos de sistema que podemos usar en este tipo de triggers.
Atributo Tipo Descripcin y ejemplo
ora_client_ip_address VARCHAR2 Retorna la direccin IP del cliente en un evento
LOGON cuando el protocolo subyacente es
TCP/IP.
if (ora_sysevent='LOGON') then
addr:=ora_client_ip_address;
end if;
ora_database_name VARCHAR2(50) Nombre de la base de datos.
Declare
db_name VARCHAR2(50);
begin
db_name:=ora_database_name;
end;
ora_des_encrypted_password VARCHAR2 La contrasea con encriptacin DES del usuario
que est siendo creado o modificado.
if (ora_dict_obj_type='USER') then
insert into
event_table(ora_des_encrypted_password);
end if;
ora_dict_obj_name VARCHAR(30) Nombre del objeto en el diccionario sobre el cual
ocurre la operacin DDL.
insert into event_table (
'El objeto cambiado es ' ||
ora_dict_obj_name');
ora_dict_obj_name_list (name_list BINARY_INTEGER Retorna la lista de nombres de objetos que estn
OUT ora_name_list_t) siendo modificados en el evento.
if (ora_sysevent='associate statistics') then
number_modified :=
ora_dict_obj_name_list (name_list);
end if;
ora_dict_obj_owner VARCHAR(30) Propietario del objeto sobre el cual ocurre la
operacin.
insert into event_table ('el propietario del
objeto es ' || ora_dict_obj_owner');
ora_dict_obj_owner_list (owner_list BINARY_INTEGER Retorna la lista de propietarios de los objetos
OUT ora_name_list_t) modificados en el evento.
if (ora_sysevent='associate statistics') then
number_of_modified_objects :=
ora_dict_obj_owner_list(owner_list);
end if;
ora_dict_obj_type VARCHAR(20) Tipo de objeto sobre el cual ocurre la operacin
DDL.
insert into event_table ('Este objeto es
un ' || ora_dict_obj_type);
ora_grantee (user_list OUT BINARY_INTEGER Retorna los permisos de un evento GRANT
en el
ora_name_list_t) parmetro de salida; retorna el nmero de
concesiones.
if (ora_sysevent='GRANT') then
number_of_users:=ora_grantee(user_list);
end if;
ora_instance_num NUMBER Nmero de instancia.
if (ora_instance_num=1) then
insert into event_table('1');
end if;

Oracle /126
ora_is_alter_column (column_name BOOLEAN Retorna TRUE si la columna especificada es
IN VARCHAR2) modificada.
if (ora_sysevent='ALTER' and
ora_dict_obj_type='TABLE') then
alter_column:=ora_is_alter_column('FOO');
end if;
ora_is_creating_nested_table BOOLEAN Retorna TRUE si el evento actual es creando una
tabla anidada.
if (ora_sysevent='CREATE' and
ora_dict_obj_type='TABLE' and
ora_is_creating_nested_table) then
insert into event_tab
values ('Se cre una tabla anidada');
end if;
ora_is_drop_column (column_name BOOLEAN Retorna TRUE si la columna especificada es
IN VARCHAR2) borrada.
if (ora_sysevent='ALTER' and
ora_dict_obj_type='TABLE') then
drop_column:=ora_is_drop_column('FOO');
end if;
ora_is_servererror BOOLEAN Retorna TRUE si el error dado es sobre un error
de pila, FALSE en otro caso.
if (ora_is_servererror(error_number)) then
insert into event_table('Error de servidor!');
end if;
ora_login_user VARCHAR2(30) Nombre de usuario en un registro.
select ora_login_user from dual;
ora_partition_pos BINARY_INTEGER En un trigger INSTEAD OF para CREATE TABLE,
la posicin dentro del texto SQL donde
podramos insertar una clusula PARTITION.
-- Recupera ora_sql_txt dentro de la
-- variable sql_text primero.
n:=ora_partition_pos;
new_stmt:=substr(sql_text, 1, n-1) ||
'' || my_partition_clause ||
'' || substr(sql_text, n));
ora_privilege_list (privilege_list BINARY_INTEGER Retorna la lista de permisos que estn siendo
OUT ora_name_list_t) concedidos por el comando GRANT o la lista de
permisos revocados por el comando REVOKE, en
el parmetro de salida; retorna el nmero de
permisos.
if (ora_sysevent='GRANT' or
ora_sysevent = 'REVOKE') then
number_of_privileges:=
ora_privilege_list(priv_list);
end if;
ora_revokee (user_list OUT BINARY_INTEGER Retorna las revocaciones de un evento REVOKE
ora_name_list_t) en el parmetro de salida; retorna el nmero de
revocaciones.
if (ora_sysevent='REVOKE') then
number_of_users := ora_revokee(user_list);
end if;
ora_server_error NUMBER Dada una posicin (1 para el tope de la pila)
retorna el nmero de error en la pila de errores.
insert into event_table ('error en la pila ' ||
ora_server_error(1));

Oracle /127
ora_server_error_depth BINARY_INTEGER Retorna el nmero total de mensajes de error en
la pila de errores.
n := ora_server_error_depth;
ora_server_error_msg (position in VARCHAR2 Dada una posicin (1 para el tope de la pila),
binary_integer) retorna el mensaje de error en la pila de errores.
insert into event_table ('Mensaje de la pila: ' ||
ora_server_error_msg(1));
ora_server_error_num_params BINARY_INTEGER Dada una posicin (1 para el tope de la pila),
(position in binary_integer) retorna el nmero de strings que han sido
sustituidos dentro del mensaje de error usando
un formato como "%".
n:=ora_server_error_num_params(1);
ora_server_error_param (position in VARCHAR2 Dada una posicin (1 para el tope de la pila) y un
binary_integer, param in nmero de parmetro, retorna la coincidencia
binary_integer) "%s", "%d" y dems en valores de sustitucin en
el mensaje de error.
-- E.j. el 2 %s en un mensaje como
-- "Esperado %s, encontrado %s"
param:=ora_server_error_param(1,2);
ora_sql_txt (sql_text out BINARY_INTEGER Retorna el texto SQL del comando dentro del
ora_name_list_t) parmetro de salida. Si el comando es largo, se
rompe en varios elementos. La funcin retorna
un valor que especifica cuntos elementos hay.
sql_text ora_name_list_t;
stmt VARCHAR2(2000);
...
n := ora_sql_txt(sql_text);
for i in 1..n loop
stmt := stmt || sql_text(i);
end loop;
insert into event_table ('texto del comando: '
|| stmt);
ora_sysevent VARCHAR2(20) Evento del sistema que lanza el trigger. El
nombre del evento es el mismo que est en la
sintaxis.
insert into event_table (ora_sysevent);
ora_with_grant_option BOOLEAN Retorna TRUE si los permisos son concedidos
con la opcin GRANT.
if (ora_sysevent='GRANT' and
ora_with_grant_option=TRUE) then
insert into event_table('with grant option');
end if;
space_error_info (error_number BOOLEAN Retorna TRUE si el error es relativo a una
OUT NUMBER, error_type OUT condicin fuera-de-espacio, y rellena los
VARCHAR2, object_owner OUT parmetros de salida con informacin acerca del
VARCHAR2, table_space_name OUT objeto que caus el error.
VARCHAR2, object_name OUT if (space_error_info(eno, typ,
VARCHAR2, sub_object_name OUT owner, ts, obj, subobj) = TRUE) then
VARCHAR2) dbms_output.put_line('El objeto se ' ||
'ejecuta fuera de espacio.');
dbms_output.put_line('El objeto es ' ||
'propiedad de ' || owner);
end if;

7.5. Triggers para eventos del sistema.


Un trigger del sistema se dispara cuando se arranca o para la base de datos, un usuario inicia o para una
sesin, cuando se crea, modifica o elimina un objeto, etc. Cuando ocurre un evento de base de datos
podemos ejecutar un trigger que referencie los atributos del evento (como con los eventos DDL). Podemos

Oracle /128
usar un trigger de sistema para realizar funciones de mantenimiento del sistema inmediatamente despus de
cada inicio de la base de datos.
La sintaxis para este tipo de trigger es el siguiente:
CREATE [OR REPLACE] TRIGGER nombre_trigger
{ BEFORE|AFTER } { <lista eventos de definicin> | <lista eventos del sistema>}
ON { DATABASE | SCHEMA} [WHEN (condicin)]
<cuerpo del trigger (bloque PL/SQL)>
Donde la lista de eventos de definicin puede tener uno o ms eventos DDL separados por OR y la lista de
eventos del sistema igualmente separados por OR.
La siguiente tabla describe los diversos disparadores de sistema.
Evento Momento Se disparan:
STARTUP AFTER Despus de arrancar la instancia.
SHUTDOWN BEFORE Antes de apagar la instancia.
LOGON AFTER Despus de que el usuario se conecte a la base de datos.
LOGOFF BEFORE Antes de la desconexin de un usuario.
SERVERERROR AFTER Cuando ocurre un error en el servidor.
CREATE BEFORE|AFTER Antes o despus de crear un objeto en el esquema.
DROP BEFORE|AFTER Antes o despus de borrar un objeto en el esquema.
ALTER BEFORE|AFTER Antes o despus de cambiar un objeto en el esquema.
TRUNCATE BEFORE|AFTER Antes o despus de ejecutar un comando TRUNCATE.
GRANT BEFORE|AFTER Antes o despus de ejecutar un comando GRANT.
REVOKE BEFORE|AFTER Antes o despus de ejecutar un comando REVOKE.
DLL BEFORE|AFTER Antes o despus de ejecutar cualquier comando de definicin de datos.
Por ejemplo, el siguiente trigger fija paquetes en cada arranque de la base de datos. Fijar paquetes en un modo
efectivo de guardar objetos PL/SQL grandes en la memoria compartida, mejorando el rendimiento y la
escalabilidad de la base de datos. Este trigger, PIN_ON_STARTUP, se ejecutar cada vez que arranque la base de
datos. Debemos crear este trigger mientras nos conectamos como un usuario con permisos ADMINISTER
DATABASE TRIGGER.
-- Mientras nos conectamos como un usuario de tipo administrador:
CREATE OR REPLACE TRIGGER PIN_ON_STARTUP
AFTER STARTUP ON DATABASE
BEGIN
DBMS_SHARED_POOL.KEEP ('SYS.STANDARD', 'P');
END;
/
Este ejemplo muestra un simple trigger que ser ejecutado inmediatamente despus de que arranque la base
de datos. Podemos modificar la lista de paquetes en el cuerpo del trigger para incluir los ms usados por
nuestra aplicacin.
Al arrancar y parar, los triggers pueden acceder a los atributos ora_instance_num, ora_database_name,
ora_login_user, y ora_sysevent.
7.6. Triggers de sustitucin.
Si creamos una vista podemos usar un trigger INSTEAD OF para decirle a Oracle cmo actualizar las tablas
subyacentes que son parte de la vista. Podemos usar trigger INSTEAD OF sobre vistas de objeto o sobre vistas
relacionales estndar.
Por ejemplo, si una vista involucra un join entre dos tablas, nuestra habilidad para actualizar registros en la
vista es limitada. Sin embargo, usando un trigger INSTEAD OF podemos decirle a Oracle cmo actualizar,
borrar o insertar registros en tablas cuando un usuario intenta cambiar valores a travs de la vista. El cdigo
del trigger INSTEAD OF se ejecuta en lugar del comando INSERT, UPDATE o DELETE.
Por ejemplo, podemos tener una vista que combine la tabla LIBRO y AUTOR:
CREATE OR REPLACE VIEW AUTOR_LIBRO AS
SELECT A.NombreAutor, L.Titulo
FROM AUTOR A INNER JOIN LIBRO L USING (idAutor);
Podemos seleccionar valores de esta vista. Consideremos los siguientes registros:
SELECT NombreAutor, Titulo
FROM AUTOR_LIBRO

Oracle /129
WHERE NombreAutor = 'Emilio Salgari';
NombreAutor Titulo
------------------------- ---------------------------
Emilio Salgari Sandokn
Emilio Salgari El Corsario Negro
Si intentamos actualizar el valor del nombre del autor, la actualizacin fallar:
UPDATE AUTOR_LIBRO
SET NombreAutor = 'Emil Salgari'
WHERE NombreAutor = 'Emilio Salgari';
El problema es que Oracle no puede determinar qu registro de AUTOR se intenta actualizar en la vista, al no
disponer de la clave de AUTOR (IdAutor). Para realizar la actualizacin mediante la vista necesitamos usar un
trigger INSTEAD OF.
En el siguiente ejemplo se crea un trigger de tipo INSTEAD OF para la vista AUTOR_LIBRO:
CREATE OR REPLACE TRIGGER AUTOR_LIBRO_UPDATE
INSTEAD OF UPDATE ON AUTOR_LIBRO
FOR EACH ROW
BEGIN
IF :OLD.NombreAutor <> :NEW.NombreAutor THEN
UPDATE AUTOR SET NombreAutor = :NEW.NombreAutor
WHERE NombreAutor = :OLD.NombreAutor;
END IF;
IF :OLD.Titulo <> :NEW.Titulo THEN
UPDATE LIBRO SET Titulo = :NEW.Titulo
WHERE Titulo = :OLD.Titulo;
END IF;
END;
/
En la primera parte de este trigger se nombra el trigger, y su propsito es descrito en la clusula INSTEAD OF.
Se crea el trigger al nivel de registro (FOR EACH ROW), de forma que cada cambio del registro ser procesado.
La siguiente seccin del trigger le dice a Oracle cmo procesar la actualizacin. Si cambia el valor del nombre
de autor se actualiza la tabla AUTOR para reflejar ese cambio, y si cambia el valor del ttulo de libro se actualiza
la tabla LIBRO para reflejar ese cambio
As, la vista confa en dos tablas ( LIBRO y AUTOR), y una actualizacin sobre la vista puede actualizar ambas
tablas.
Ahora podemos actualizar la vista AUTOR_LIBRO directamente y tenemos un trigger que actualizar
apropiadamente ambas tablas subyacentes. Por ejemplo, el siguiente comando actualizar la tabla AUTOR:
UPDATE AUTOR_LIBRO
SET NombreAutor = 'Emil Salgari'
WHERE NombreAutor = 'Emilio Salgari';
2 filas actualizadas.
Los triggers INSTEAD OF son muy potentes. Como muestra el ejemplo anterior podemos usarlos para realizar
operaciones a travs de diferentes tablas de la base de datos, usando una lgica de control de flujo. En
relacin con vistas de objetos, podemos usar triggers INSTEAD OF para redirigir DML sobre la vista de objeto
a la tablas base de la vista.
7.7. Activar y desactivar triggers.
La sintaxis para desactivar un trigger es:
ALTER TRIGGER nombre_del_trigger DISABLE;
La sintaxis para desactivar todos los triggers sobre una tabla es:
ALTER TABLE nombre_de_tabla DISABLE ALL TRIGGERS;
La sintaxis para volver a activar un trigger es:
ALTER TRIGGER nombre_del_trigger ENABLE;
La sintaxis para volver a activar todos los triggers sobre una tabla es:
ALTER TABLE nombre_de_tabla ENABLE ALL TRIGGERS;

Oracle /130
8. Tipos de datos complejos y operaciones masivas.
Existen tres tipos de datos personalizados en PL/SQL:
RECORD (Registro): Es un tipo de datos definido por el usuario que contiene varios atributos en una sola
estructura.
TABLE (Array asociativo): Es una coleccin de elementos del mismo tipo que no tienen limitacin en
cuanto al nmero de elementos.
VARRAY (Array variable): Es una coleccin de elementos del mismo tipo que tienen una limitacin en
cuanto al nmero de elementos.
Pueden utilizarse estos tipos de datos personalizados para realizar operaciones masivas de recuperacin de
datos mediante el comando BULK.
Para trabajar con grandes cantidades de informacin, tanto en formato binario como en formato de texto, se
utilizan los tipos de datos LOB predefinidos.
8.1. Registros (RECORD).
Un registro es una estructura de datos de PL/SQL, almacenados en campos, cada uno de los cuales tiene su
propio nombre y tipo y que se tratan como una sola unidad lgica.
Los campos de un registro pueden ser inicializados y pueden ser definidos como NOT NULL. Aquellos campos
que no sean inicializados explcitamente, se inicializarn a NULL.
8.1.1. Declaracin de registros.
La sintaxis para definir un tipo de registro personalizado es:
TYPE Nombre_del_tipo IS RECORD
(nombreVariable1 tipoDeDato,
[nombreVariable2 tipoDeDato, ...]);
Y para declarar una variable del tipo de registro personalizado:
nombreRecord Nombre_del_tipo;
En ese momento ya podemos utilizar el RECORD mediante la inclusin de un punto, seguido del nombre de la
variable a la que deseamos acceder:
nombreRecord.nombreVariable1 := valor;
Los registros pueden estar anidados. Es decir, un campo de un registro puede ser de un tipo de dato de otro
registro. Slo pueden crearse tipos de registros personalizados en la parte declarativa de un objeto
procedimental, nunca como objetos de la base de datos.
Pueden asignarse todos los campos de un registro utilizando una sentencia SELECT. En este caso hay que
tener cuidado en especificar las columnas en el orden conveniente segn la declaracin de los campos del
registro. Para este tipo de asignacin es muy frecuente el uso del atributo %ROWTYPE que veremos ms
adelante.
DECLARE
TYPE RegAlumno IS RECORD ( nombre VARCHAR2(100), apellidos VARCHAR2(100) );
Alum1 RegAlumno;
BEGIN
SELECT nombre, apellidos INTO Alum1 FROM Alumno WHERE nif = '3333333D';
END;
Puede asignarse un registro a otro cuando sean del mismo tipo:
DECLARE
TYPE RegAlumno IS RECORD ( nombre VARCHAR2(100), apellidos VARCHAR2(100) );
Alum1 RegAlumno;
Alumn2 RegAlumno;
BEGIN
Alum1.nombre := 'Juan';
Alum1.apellidos := 'Senn Rey';
Alum2 := Alum1;
END;
8.1.2. Declaracin de registros con el atributo %ROWTYPE.
Se puede declarar un registro basndose en una coleccin de columnas de una tabla, vista o cursor de la base
de datos mediante el atributo %ROWTYPE.
Se puede declarar una variable del tipo de registros de la tabla Alumno con Alumno%ROWTYPE:
DECLARE

Oracle /131
Alum1Alumno%ROWTYPE;
BEGIN
Alumn1.nif := '2222222B';
END;
Lo cual significa que el registro alum1 tendr la siguiente estructura: ( nif VARCHAR2(9), nombre VARCHAR2(100),
apellidos VARCHAR2(50), localidad VARCHAR2(50) ).
De esta forma se crea el registro de forma dinmica y se podrn asignar valores a los campos de un registro a
travs de un SELECT sobre la tabla, vista o cursor a partir de la cual se cre el registro.
8.2. Arrays asociativos (TABLE).
Los arrays asociativos o tablas anidadas o tablas de PL/SQL son tipos de datos que nos permiten almacenar
varios valores del mismo tipo de datos. Una tabla PL/SQL:
- Es similar a un array sin lmite de elementos.
- Consta de dos componentes: un ndice del tipo BINARY_INTEGER o VARCHAR2 que permite acceder a los
elementos en la tabla y una columna de escalares, registros u objetos que contiene los valores de la tabla.
- Puede incrementar su tamao dinmicamente.
8.2.1. Declaracin de tablas de PL/SQL.
La sintaxis general para declarar una tabla de PL dentro de un bloque es la siguiente:
TYPE nombreTabla IS TABLE OF tipoDato [INDEX BY tipoIndice];
TYPE nombreTabla IS TABLE OF tipoRegistro [INDEX BY tipoIndice];
Sidefinimos la coleccin sin la clusula INDEX BY deberemos inicializar la coleccin antes de poder acceder a
sus elementos, y en ese caso los ndices sern de tipo entero comenzando por 1. Si se usa esta clusula, la
coleccin se comporta como un array asociativo y queda inicializada al rango de ndices establecido segn el
tipo BINARY_INTEGER o VARCHAR2.
Una vez que hemos definido la tabla, podemos declarar variables del tipo y asignarle valores.
DECLARE
-- Definimos el tipo Valores_Table como tabla PL/SQL
TYPE Valores_Table IS TABLE OF NUMBER;
-- Declaramos una variable del tipo Valores_Table con tres elementos
valores Valores_Table := Valores_Table(0, 0, 0);
BEGIN
valores (1) := 1;
valores (2) := 2;
valores (3) := 3;
END;
Hay que fijarse que, en la declaracin de la variable valores, debemosinicializar la tabla a un nmero de
elementos dado. El primer elemento est asociado al ndice 1. Posteriormente podr ampliarse la tabla con
ms elementos mediante la funcin EXTEND().
...
valores.EXTEND();
valores (4) := 4;
...
Si definimos la coleccin con INDEX BY no ser necesario inicializarla:
DECLARE
-- Definimos el tipo Valores_Table como tabla PL/SQL
TYPE Valores_Table IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
-- Declaramos una variable del tipo Valores_Table
valores Valores_Table;
BEGIN
valores (-100) := 1;
valores (-4) := 2;
valores (12) := 3;
END;
As tenemos un array al cual podemos acceder mediante un ndice entero (positivo o negativo) que se pone
entre parntesis. Tambin podemos definir ndices de tipo VARCHAR2:
DECLARE
-- Definimos el tipo Ordinal_Meses para almacenar los ordinales de mes,

Oracle /132
-- usando como ndices los nombres cortos de mes.
TYPE Ordinal_Meses IS TABLE OF NUMBER(1) INDEX BY VARCHAR2(3);
-- Declaramos una variable del tipo Ordinal_Meses
meses Ordinal_Meses;
BEGIN
meses ('ENE') := 1;
meses ('FEB') := 2;
meses ('MAR') := 3;
END;
Tambin se puede almacenar un tipo de tabla en la base de datos mediante la instruccin CREATE TYPE:
CREATE OR REPLACE TYPE Valores_Table AS TABLE OF NUMBER;
8.2.2. Tablas PL/SQL de registros.
Es posible declarar elementos de una tabla PL/SQL como de tipo registro.
DECLARE
TYPE RegAlumno IS RECORD ( nombre VARCHAR2(100), apellidos VARCHAR2(100) );
TYPE TAlumnos IS TABLE OF RegAlumno ;
ta TAlumnos := TAlumnos(NULL); -- Se crea la tabla con un elemento
BEGIN
ta(1).nombre := 'Juan';
ta(1).apellidos := 'Senn Rey';
END;
Si definimos la tabla con el comando CREATE TYPE no es posible que sus elementos sean de tipo RECORD. En
este caso debemos sustituir el tipo RECORD por un tipo OBJECT.
CREATE TYPE ObjAlumno AS OBJECT ( nombre VARCHAR2(100), apellidos VARCHAR2(100) );
CREATE TYPE TAlumnos AS TABLE OF ObjAlumno ;
8.2.3. Funciones para el manejo de tablas PL/SQL.
Tambin tenemos una serie de mtodos asociados a los tipos TABLE, que nos permiten realizar acciones
como:
EXISTS(n): devuelve verdadero si el valor del ndice que contenga no es nulo; es decir, tiene asignado
algn valor.
COUNT: devuelve el nmero de elementos que posee la TABLE.
FIRST y LAST: Devuelven el ndice inicial y final, respectivamente.
PRIOR(ndice): Devuelve ndice anterior del indicado.
NEXT(ndice): Devuelve el siguiente ndice del indicado.
EXTEND(): agrega un nuevo elemento con valor NULL a la coleccin.
EXTEND(n): agrega n elementos con valor NULL a la coleccin.
EXTEND(n, i): agrega n copias del elemento i-simo a la coleccin.
TRIM(n): Elimina los n ltimos elementos.
DELETE[(n, m)]: Si no lleva ndices, vaca la TABLE entera; si lleva un solo ndice borra el elemento
indicado; y si lleva los dos ndices, borra desde el ndice n hasta el ndice m inclusive.
El siguiente ejemplo muestra el uso de FIRST y LAST:
DECLARE
TYPE Arr_Ciudades IS TABLE OF VARCHAR2(50);
misCiudades ARR_CIUDADES := ARR_CIUDADES(NULL, NULL, NULL);
BEGIN
misCiudades(1) := 'MADRID';
misCiudades(2) := 'BILBAO';
misCiudades(3) := 'MALAGA';
FOR i IN misCiudades.FIRST..misCiudades.LAST LOOP
DBMS_OUTPUT.PUT_LINE(misCiudades(i));
END LOOP;
END;
8.3. Arrays variables (VARRAY).
Un VARRAY, o array variable, se manipula de forma muy similar a las tablas de PL, pero se implementa de
forma diferente. Los elementos en el VARRAY se almacenan comenzando en el ndice 1 hasta la longitud
mxima declarada en el tipo VARRAY.

Oracle /133
8.3.1. Declaracin de arrays variables.
La sintaxis general para declarar un array variable en un bloque es la siguiente:
TYPE nombreTipo IS VARRAY (tamaoMaximo) OF tipoElementos;
Una consideracin a tener en cuenta es que en la declaracin de un VARRAY el tipo de datos no puede ser de
los siguientes tipos: BOOLEAN, NCHAR, NCLOB, NVARCHAR(n), REF CURSOR, TABLE, VARRAY.
Sin embargo se puede especificar el tipo utilizando los atributos %TYPE y %ROWTYPE.
Los VARRAY deben estar inicializados antes de poder utilizarse. Para inicializar un VARRAY se utiliza un
constructor (podemos inicializar el VARRAY en la seccin DECLARE o bien dentro del cuerpo del bloque):
DECLARE
-- Declaramos el tipo VARRAY de cinco elementos VARCHAR2
TYPE T_Cadena IS VARRAY(5) OF VARCHAR2(50);
-- Asignamos los valores con un constructor
v_lista T_Cadena:= T_Cadena('Aitor', 'Alicia', 'Pedro', NULL);
BEGIN
v_lista(3) := 'Tita';
v_lista(4) := 'Ainhoa';
END;
Tambin se puede almacenar en la base de datos mediante la instruccin CREATE TYPE:
CREATE OR REPLACE TYPE T_Cadena AS VARRAY(5) OF VARCHAR2(50);
En este caso, el tipo de los elementos no puede ser RECORD, ni se puede utilizar los atributos %TYPE y
%ROWTYPE. En este caso debemos sustituir el tipo RECORD por un tipo OBJECT.
El tamao de un VARRAY se establece mediante el nmero de argumentos utilizados en el constructor, si
declaramos un VARRAY de cinco elementos pero al inicializarlo pasamos slo tres parmetros al constructor, el
tamao del VARRAY ser tres. Si se hacen asignaciones a elementos que queden fuera del rango se producir
un error.
El tamao de un VARRAY podr aumentarse utilizando la funcin EXTEND, pero nunca con mayor dimensin
que la definida en la declaracin del tipo. Por ejemplo, la variable v_lista anterior, que slo tiene 4 valores
definidos, se podra ampliar hasta cinco elementos pero no ms all.
Un VARRAY comparte varias de las funciones vlidas para tablas, aadiendo alguna ms:
EXISTS(n): devuelve verdadero si el valor del ndice que contenga no es nulo; es decir, tiene asignado
algn valor.
COUNT: devuelve el nmero de elementos que posee el VARRAY.
FIRST y LAST: Devuelven el ndice inicial y final, respectivamente.
PRIOR(ndice): Devuelve ndice anterior del indicado.
NEXT(ndice): Devuelve el siguiente ndice del indicado.
LIMIT, devuelve el nmero mximo de elementos que admite el VARRAY.
EXTEND, aade un elemento al VARRAY.
EXTEND(n), aade (n) elementos al VARRAY.
TRIM(n): Elimina los n ltimos valores.
DELETE, elimina todos los elementos de la coleccin. El VARRAY se queda vaco, pero es distinto de NULL.
8.3.2. Arrays variables en la base de datos.
Los VARRAY pueden almacenarse en columnas de tablas relacionales. Sin embargo, como campo, un VARRAY
slo puede manipularse en su integridad, no pudiendo modificarse directamente su contenido.
Para poder crear tablas con campos de tipo VARRAY debemos crearlo como un objeto de la base de datos.
La sintaxis general es:
CREATE [OR REPLACE]
TYPE nombre_tipo AS VARRAY (tamao_maximo) OF tipo_elementos;
Una vez que hayamos creado el tipo sobre la base de datos, podremos utilizarlo como un tipo de datos ms
en la creacin de tablas, declaracin de variables, ...
Vase el siguiente ejemplo:
CREATE OR REPLACETYPE Pack_Productos AS VARRAY(10) OF VARCHAR2(60);
/
CREATE TABLE Ofertas (
co_oferta NUMBER,
productos Pack_Productos,
precio NUMBER

Oracle /134
);
Para modificar un VARRAY almacenado, primero hay que seleccionarlo en una variable PL/SQL. Luego se
modifica la variable y se vuelve a almacenar en la tabla.
DECLARE
pack Pack_Productos;
BEGIN
-- Se recupera el campo de uno de los registros
SELECT productos INTO pack FROM Ofertas WHERE co_oferta = 2;
-- Se aade un nuevo elemento a la coleccin
pack.EXTEND(1);
pack(pack.LAST) := 'nuevo producto';
-- Se actualiza el campo
UPDATE Oferta SET productos = pack WHERE co_oferta = 2;
END;

8.4. Acceso masivo a los datos (BULK COLLECT).


PL/SQL nos permite leer varios registros en una coleccin de PL con un nico acceso a travs de la
instruccin BULK COLLECT. Esto nos permitir reducir el nmero de accesos a disco, por lo que
optimizaremos el rendimiento de nuestras aplicaciones. Como contrapartida el consumo de memoria ser
mayor.
Su uso ms bsico es el recuperar registros desde un cursor explcito mediante la instruccin FETCH:
DECLARE
TYPE T_Apellidos IS TABLE OF Alumno.apellidos%TYPE;
v_apellidos T_Apellidos;
CURSOR c1 IS SELECT apellidos FROM Alumno;
BEGIN
OPEN c1;
FETCH c1 BULK COLLECT INTO v_apellidos LIMIT 10; -- Lee como mximo 10 registros
CLOSE c1;
-- se procesa la coleccin 'v_apellidos'
END;
Su uso ms general es con cursores implcitos. El siguiente ejemplo recupera registros desde un SELECT:
DECLARE
TYPE T_Apellidos IS TABLE OF Alumno.apellidos%TYPE;
TYPE T_Localidades IS TABLE OF Alumno.localidad%TYPE;
v_apellidos T_Apellidos;
v_localidades T_Localidades;
BEGIN
SELECT apellidos, localidad BULK COLLECT INTO v_apellidos, v_localidades FROM Alumno;
FOR i IN v_apellidos.FIRST .. v_apellidos.LAST LOOP
DBMS_OUTPUT.PUT_LINE(v_apellidos(i) || ',' || v_localidades(i));
END LOOP;
END;
Podemos utilizar BULK COLLECT con arrays de registros de PL, pero no as con arrays de objetos.
DECLARE
TYPE T_Alumnos IS TABLE OF Alumno%ROWTYPE;
v_alumnos T_Alumnos;
BEGIN
SELECT* BULK COLLECT INTO v_alumnos FROM Alumno;
FOR i IN v_alumnos.FIRST .. v_alumnos.LAST LOOP
DBMS_OUTPUT.PUT_LINE(v_alumnos(i).apellidos || ', ' || v_alumnos(i).nombre);
END LOOP;
END;
Tambin podemos aplicarlo en una instruccin de borrado para acumular los datos de los registros borrados:
DECLARE
TYPE T_Alumnos IS TABLE OF Alumno%ROWTYPE;
v_alumnos T_Alumnos;
BEGIN

Oracle /135
DELETE FROM Alumno
RETURNING nif, nombre, apellidos, localidad BULK COLLECT INTO v_alumnos;
END;
8.5. Funciones en lnea.
Una funcin en lnea es aquella que retorna una tabla como valor, y que puede ser utilizada en la parte FROM
de una consulta.
Oracle proporciona dos formas para que una funcin retorne un conjunto de registros: funciones que
retornan un array de tipo TABLE, y funciones pipeline.
8.5.1. Funciones que retornan una tabla anidada.
Para que una funcin en lnea retorne un array deben cumplirse dos condiciones:
- El array (VARRAY o TABLE) debe ser definido con el comando CREATE TYPE.
- Los elementos del array deben pertenecer a un tipo base (como NUMBER, VARCHAR2, etc.) o a un tipo
OBJECT personalizado. (No funciona con tipos RECORD.)
Ilustraremos este captulo con un ejemplo. Crearemos la funcin OBTEN_ALUMNOS, que retornar un array
con el nif y nombre de los alumnos almacenados en la tabla Alumno.
Previamente se crea un tipo para contener los campos nif y nombre:
CREATE TYPE OAlumno AS OBJECT (nif VARCHAR2(9), nombre VARCHAR2(60));
Y ahora creamos el tipo del array:
CREATE TYPE TARR_Alumnos AS TABLE OF OAlumno;
Por ltimo, la funcin puede crearse dentro de un paquete o con CREATE FUNCTION:
CREATE OR REPLACE FUNCTION OBTEN_ALUMNOS RETURN TARR_Alumnos
IS
Tarr TARR_Alumnos := TARR_Alumnos();
BEGIN
FOR fila IN (SELECT nif, nombre FROM Alumno) LOOP
Tarr.Extend();
Tarr( Tarr.Last ) := OAlumno( fila.nif, fila.nombre );
END LOOP;
RETURN Tarr;
END;
Ahora podemos usar esta funcin con la clusula FROM aplicando la funcin TABLE de la siguiente forma:
SELECT * FROM TABLE( OBTEN_ALUMNOS() );
Un resultado posible de esta consulta puede ser el siguiente:
NIF NOMBRE
----------------- --------------------------
11111111A Juan
22222222B Marian
A veces puede ser necesario forzar el tipo devuelto por la funcin en lnea:
SELECT * FROM TABLE( CAST (OBTEN_ALUMNOS() AS TARR_Alumnos );
Si el tipo de array devuelve elementos de un tipo simple, la consulta retornar una nica columna con el
nombre COLUMN_VALUE. Por ejemplo, si hemos definido el siguiente tipo:
CREATE TYPE VARR_Ordinales AS VARRAY(10) OF NUMBER;
Y ejecutamos la siguiente consulta:
SELECT * FROM TABLE (VARR_Ordinales(3, 4, 7));
El resultado ser el siguiente:
COLUMN_VALUE
---------------------
3
4
7
8.5.2. Funciones pipeline de tabla.
Para que mejorar los tiempos de acceso a los registros devueltos por una funcin en lnea se debe utilizar la
tcnica de pipeline. Esta tcnica requiere que previamente creemos un tipo para la tabla que debe retornarse y
un tipo para los registros de dicha tabla. Por ejemplo, si queremos crear una funcin que retorne los alumnos
de una localidad determinada, primero debemos crear un objeto del tipo del registro:

Oracle /136
CREATE OR REPLACE TYPE Reg_Alumno AS OBJECT (nif VARCHAR2(9), apellidos VARCHAR2(100));
Ahora podemos crear el tipo de la tabla a retornar:
CREATE OR REPLACE TYPE Tabla_Alumnos AS TABLE OF Reg_Alumno;
Y ahora ya podemos crear la funcin:
CREATE OR REPLACE fn_AlumnosDeLocalidad (pLocalidad VARCHAR2)
RETURN Tabla_Alumnos PIPELINED
IS
CURSOR c1 IS (SELECT nif, apellidos FORM Alumno WHERE localidad = pLocalidad);
BEGIN
FOR fila IN c1 LOOP
PIPE ROW ( Reg_Alumno(fila.nif, fila.apellidos));
END LOOP;
RETURN;
END;
Al usar la palabra clave PIPELINED en la cabecera se mejoran los tiempos de respuesta de estas funciones, ya
que los datos son devueltos conforme se ejecuta la funcin. Cada llamada al comando PIPE ROW retorna una
registro del tipo de la tabla que queremos retornar, y Reg_Alumno() crea un objeto del tipo de registro.
Podemos usar la funcin de la siguiente manera:
SELECT * FROM TABLE ( fn_AlumnosDeLocalidad('Madrid') );
Este tipo de funciones no pueden usarse directamente en cdigo PL/SQL puesto que realmente no retornan
un valor. Por tanto, el siguiente cdigo sera errneo:
DECLARE
vTabla Tabla_Alumnos;
BEGIN
vTabla := AlumnosDeLocalidad('Madrid'); -- Sintaxis errnea
END;
8.6. Instruccin FORALL.
La instruccin FORALL permite realizar una serie de comandos INSERT, UPDATE, o DELETE de forma masiva
normalmente ms rpidamente que el bucle FOR equivalente.
Este comando admite varias sintaxis:
FORALL ndice IN rango [SAVE EXCEPTIONS] Comando_SQL;
FORALL ndice INDICES OF coleccin [BETWEEN inicio AND fin] [SAVE EXCEPTIONS] Comando_SQL;
FORALL ndice VALUES IF coleccin_de_ndices[SAVE EXCEPTIONS] Comando_SQL;
La clusula opcional SAVE EXCEPTIONS provoca que si falla una de las operaciones no se produzca una
excepcin inmediata, sino que se contina la ejecucin hasta que finaliza el bucle y entonces se genera una
nica excepcin. Los detalles de los errores estn disponibles despus del bucle en el atributo
SQL%BULK_EXCEPTIONS. El siguiente cdigo muestra cmo acceder a los errores en el boque EXCEPTIONS de
un bloque annimo:
DECLARE
Errores NUMBER;
BEGIN
-- Una instruccin FORALL que provoca excepciones
EXCEPTION
WHEN OTHERS THEN
errores := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.PUT_LINE('Nmero de instrucciones que han fallado: ' || errores);
FOR i IN 1..errores LOOP
DBMS_OUTPUT.PUT_LINE('Error #' || i || ' ocurri durante la iteracin # '||
SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
DBMS_OUTPUT.PUT_LINE('Mensaje de error: ' ||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
Como ejemplo de uso del comando FORALL podemos eliminar sucesivamente registros cuyos id's estn
asignados en una coleccin:
DECLARE
TYPE T_Lista_ids IS VARRAY(5) OF INTEGER; -- El tipo de una coleccin para 5 elementos enteros

Oracle /137
lista T_Lista_ids := T_Lista_ids(1,3,6,34,40); -- Una variable del tipo de coleccin con valores iniciales
BEGIN
FORALL i IN 1..5
DELETE FROM UnaTabla WHERE id = lista(i); -- Se toma el valor de la lista en el ndice 'i'
-- o de esta forma:
FORALL i IN INDICES OF lista BETWEEN lista.FIRST AND lista.LAST
DELETE FROM UnaTabla WHERE id = lista(i); -- Se toma el valor de la lista en el ndice 'i'
END;
Las siguientes restricciones se aplican al comando FORALL:
No podemos iterar a travs de elementos de un array asociativo que tenga un tipo string como clave.
Dentro del bucle FORALL, no podemos referenciar la misma coleccin en las clusulas SET y WHERE de
un comando UPDATE simultneamente. Puede ser necesario hacer una copia de la coleccin.
Podemos usar comandos FORALL slo en programas del lado servidor.
Los comandos INSERT, UPDATE o DELETE deben referenciar al menos una coleccin. Por ejemplo, un
comando FORALL que inserta un conjunto de valores constantes lanza una excepcin.
Cuando especificamos un rango explcito, todos los elementos de la coleccin en el rango deben existir.
Si un elemento falta o fue borrado se obtendr un error.
Cuando se usa las clusulas INDICES OF o VALUES OF, todas las colecciones referenciadas en el comando
DDL deben ser accedidas usando los valores de la variable ndice.
No se puede referenciar un campo de registro individual dentro del comando DML llamado por el
comando FORALL. En vez de eso hay que especificar todo el registro con la clusula SET ROW en el
comando UPDATE, o la clusula VALUES en el comando INSERT.
8.7. Objetos grandes (LOB).
Los objetos grandes (Large objects) son los nuevos tipos de datos nativos que Oracle soporta para almacenar
cantidades de datos muy grandes, de hasta 4 Gb. Existen cuatro tipos:
CLOB: Objeto grande de caracteres ASCII o cdigo ASCII extendido.
BLOB: Objeto grande de contenido binario.
BFILE: No es un objeto grande propiamente dicho, es un puntero a un elemento en el sistema de
ficheros. Su tamao mximo depender de las caractersticas del sistema de ficheros. El borrado del tipo
BFILE no implica el borrado del fichero sino de la referencia.
NCLOB: Objeto grande de caracteres multibyte.
Estos tipos permiten almacenar y manipular tipos de datos que requieren un gran volumen de
almacenamiento, como el contenido multimedia, por ejemplo.
El acceso a este tipo de datos es similar al del resto de los tipos nativos, pero el sistema permite algunas
bibliotecas adicionales para la manipulacin especial de estos datos, DBMS_LOB o las de manipulacin de
cadenas. Su inicializacin puede ser a NULL o bien haciendo uso de las funciones EMPTY_BLOB, EMPTY_CLOB y
BFILENAME.
8.7.1. Paquete DBMS_LOB.
El paquete DBMS_LOB proporciona funciones y procedimientos para manipular datos de tipo LOB. Todos los
subprogramas que usan DBMS_LOB trabajan sobre localizadores LOB. Un localizador LOB representa un LOB
que existe en una base de datos o en un archivo externo. Un LOB interno existe como un campo de una tabla
de la base de datos, un LOB externo existe en un archivo fsico externo, un LOB temporal existe como una
variable obtenida programticamente.
A continuacin se hace un resumen de las funciones y procedimientos de este paquete:
El procedimiento APPEND aade el contenido de un origen LOB(src_lob) a un destino LOB (dest_lob).
DBMS_LOB.APPEND (dest_lob IN OUT BLOB, src_lob IN BLOB);
DBMS_LOB.APPEND (dest_lob IN OUT CLOB,src_lob IN CLOB);
El procedimiento CLOSE cierra un LOB abierto previamente.
DBMS_LOB.CLOSE (lob_locIN OUT BLOB);
DBMS_LOB.CLOSE (lob_loc IN OUT CLOB);
DBMS_LOB.CLOSE (lob_loc IN OUT BFILE);
Las funciones COMPARE comparan dos LOB's enteros o parte de ellos. Retornan cero si son iguales y no
cero si son distintos.
DBMS_LOB.COMPARE (lob_1 IN BLOB, lob_2 IN BLOB, amount IN INTEGER:= 4294967295,
offset_1 IN INTEGER:=1, offset_2 IN INTEGER:=1) RETURN INTEGER;

Oracle /138
DBMS_LOB.COMPARE (lob_1 IN CLOB, lob_2 IN CLOB, amount IN INTEGER:= 4294967295,
offset_1 INTEGER:=1, offset_2 IN INTEGER:=1) RETURN INTEGER;
DBMS_LOB.COMPARE (lob_1 IN BFILE, lob_2 INBFILE, amount IN INTEGER,
offset_1 INTEGER:=1,offset_2 IN INTEGER:=1) RETURN INTEGER;
El procedimiento CONVERTTOBLOB lee caracteres desde un origen CLOB o NCLOB, los convierte y los
escribe a un BLOB destino en formato binario, retornando el nuevo desplazamiento.
DBMS_LOB.CONVERTTOBLOB(dest_lob IN OUT BLOB, src_lob IN CLOB, amount IN INTEGER,
dest_offset IN OUT INTEGER, src_offset IN OUT INTEGER, blob_csid IN NUMBER,
lang_ctx IN OUT INTEGER, warning OUT INTEGER);
El procedimiento CONVERTTOCLOB toma como origen un BLOB, convierte los datos binarios en
caracteres y escribe el resultado en un CLOB o NCLOB destino, y retorna el nuevo desplazamiento.
DBMS_LOB.CONVERTTOCLOB(dest_lob IN OUT CLOB, src_lobIN BLOB, amount IN INTEGER,
dest_offset IN OUT INTEGER, src_offset IN OUT INTEGER, blob_csid IN NUMBER,
lang_ctx IN OUT INTEGER, warning OUT INTEGER);
Los procedimientos COPY copian todo, o parte, de un origen LOB en un destino LOB.
DBMS_LOB.COPY (dest_lob IN OUT BLOB, src_lob IN BLOB, amount IN INTEGER,
dest_offset IN INTEGER:=1, src_offset IN INTEGER:=1);
DBMS_LOB.COPY (dest_lob IN OUT CLOB, src_lob IN CLOB, amount IN INTEGER,
dest_offset IN INTEGER:=1, src_offset IN INTEGER:=1);
El procedimiento CREATETEMPORARY crea un BLOB o CLOB temporal y su correspondiente ndice en el
espacio de tablas temporal por defecto.
DBMS_LOB.CREATETEMPORARY (lob_loc IN OUT BLOB, cache IN BOOLEAN, dur IN PLS_INTEGER := 10);
DBMS_LOB.CREATETEMPORARY (lob_loc IN OUT CLOB, cache BOOLEAN, dur PLS_INTEGER := 10);
El parmetro dur puede tomar los valores SESSION o CALL.
El procedimiento ERASE borra todo o parte de un LOB.
DBMS_LOB.ERASE (lob_loc IN OUT BLOB, amount IN OUT INTEGER, offset IN INTEGER:=1);
DBMS_LOB.ERASE (lob_loc IN OUT CLOB, amount IN OUT INTEGER, offset IN INTEGER:=1);
El procedimiento FILECLOSE cierra un archivo previamente abierto.
DBMS_LOB.FILECLOSE (file_loc IN OUT BFILE);
El procedimiento FILECLOSEALL cierra todos los archivos previamente abiertos.
DBMS_LOB.FILECLOSEALL;
La funcin FILEEXISTS indica si existe un archivo en el servidor. Retorna 1 si existe y cero si no existe.
DBMS_LOB.FILEEXISTS (file_loc IN BFILE) RETURN INTEGER;
El procedimiento FILEGETNAME obtiene el nombre de objeto directorio y el nombre de archivo.
DBMS_LOB.FILEGETNAME (file_loc IN BFILE, dir_alias OUTVARCHAR2, filename OUT VARCHAR2);
La funcin FILEISOPEN indica si un archivo, asociado a un BFILE, est abierto. Retorna cero si no est
abierto y 1 si lo est.
DBMS_LOB.FILEISOPEN (file_loc INBFILE) RETURN INTEGER;
El procedimiento FILEOPEN abre un archivo en un modo de apertura.
DBMS_LOB.FILEOPEN (file_loc IN OUT BFILE,open_mode IN BINARY_INTEGER := file_readonly);
El modo de apertura puede ser: file_readonly:=0, lob_readonly:=0, lob_readwrite:=1.
El procedimiento FREETEMPORARY libera los BLOB o CLOB temporales del espacio de tablas temporal por
defecto del usuario.
DBMS_LOB.FREETEMPORARY (lob_loc IN OUT BLOB);
DBMS_LOB.FREETEMPORARY (lob_loc IN OUT CLOB);
Las funciones GETCHUNKSIZE retornan la cantidad de espacio usado en un trozo LOB para guardar el
valor LOB.
DBMS_LOB.GETCHUNKSIZE (lob_loc IN BLOB) RETURN INTEGER;
DBMS_LOB.GETCHUNKSIZE (lob_loc IN CLOB) RETURN INTEGER;
Las funciones GETLENGTH retornan la longitud de un valor LOB.
DBMS_LOB.GETLENGTH (lob_loc IN BLOB) RETURN INTEGER;
DBMS_LOB.GETLENGTH (lob_loc IN CLOB) RETURN INTEGER;
DBMS_LOB.GETLENGTH (lob_loc IN BFILE) RETURN INTEGER;
La funcin GET_STORAGE_LIMIT retorna el lmite del almacn para guardar valores LOB's.
DBMS_LOB.GET_STORAGE_LIMIT;
Las funciones INSTR retornan la posicin de una ocurrencia de un patrn dentro de un dato LOB.
DBMS_LOB.INSTR (lob_loc IN BLOB, pattern IN RAW, offset IN INTEGER:=1,

Oracle /139
nth IN INTEGER:=1) RETURN INTEGER;
DBMS_LOB.INSTR (lob_loc IN CLOB, pattern IN VARCHAR2, offset IN INTEGER:=1,
nth IN INTEGER:=1) RETURN INTEGER;
DBMS_LOB.INSTR (lob_loc IN BFILE, pattern IN RAW, offset IN INTEGER:=1,
nth IN INTEGER:=1) RETURN INTEGER;
Las funciones ISOPEN indican si un LOB fue abierto usando un localizador.
DBMS_LOB.ISOPEN (lob_loc IN BLOB) RETURN INTEGER;
DBMS_LOB.ISOPEN (lob_loc IN CLOB) RETURN INTEGER;
DBMS_LOB.ISOPEN (lob_loc IN BFILE) RETURN INTEGER;
Las funciones ISTEMPORARY indican si un localizador apunta a un LOB temporal.
DBMS_LOB.ISTEMPORARY (lob_loc IN BLOB) RETURN INTEGER;
DBMS_LOB.ISTEMPORARY (lob_loc IN CLOB) RETURN INTEGER;
El procedimiento LOADBLOBFROMFILE lee un BFILE dentro de un BLOB interno.
DBMS_LOB.LOADBLOBFROMFILE (dest_lob IN OUT BLOB, src_lobIN BFILE, amount IN INTEGER,
dest_offset IN OUT INTEGER, src_offset IN OUT INTEGER);
El procedimiento LOADCLOBFROMFILE lee un BFILE dentro de un CLOB interno.
DBMS_LOB.LOADCLOBFROMFILE (dest_lob IN OUT CLOB, src_lob IN BFILE, amount IN INTEGER,
dest_offset IN OUT INTEGER, src_offset IN OUT INTEGER, bfile_csid NUMBER,
lang_ctx IN OUT INTEGER, warning OUT INTEGER);
El procedimiento LOADFROMFILE lee un BFILE dentro de un LOB interno.
DBMS_LOB.LOADFROMFILE (dest_lob IN OUT BLOB, src_lobIN BFILE, amount IN INTEGER,
dest_offset IN INTEGER:=1, src_offset IN INTEGER:=1);
DBMS_LOB.LOADFROMFILE (dest_lob IN OUT CLOB, src_lob IN BFILE, amount IN INTEGER,
dest_offset IN INTEGER:=1, src_offset IN INTEGER:=1);
El procedimiento OPEN abre un LOB (interno, externo o temporal) en el modo indicado.
DBMS_LOB.OPEN (lob_loc IN OUT BLOB, open_mode BINARY_INTEGER);
DBMS_LOB.OPEN (lob_loc IN OUT CLOB, open_mode BINARY_INTEGER);
DBMS_LOB.OPEN (lob_loc IN OUT BFILE, open_mode BINARY_INTEGER:=file_readonly);
El procedimiento READ lee datos de un LOB empezando en un desplazamiento especificado.
DBMS_LOB.READ (lob_loc IN BLOB, amount IN OUT BINARY_INTEGER,
offset IN INTEGER, buffer OUT RAW);
DBMS_LOB.READ (lob_loc IN CLOB, amount IN OUT BINARY_INTEGER,
offset IN INTEGER, buffer OUT VARCHAR2);
DBMS_LOB.READ (lob_loc IN BFILE, amount IN OUT BINARY_INTEGER,
offset IN INTEGER, buffer OUT RAW);
Las funciones SUBSTR retornan parte de un valor LOB.
DBMS_LOB.SUBSTR (lob_loc IN BLOB, amount IN INTEGER:=32767, offset IN INTEGER:=1)
RETURN RAW;
DBMS_LOB.SUBSTR (lob_loc IN CLOB, amount IN INTEGER:=32767, offset IN INTEGER:=1)
RETURN VARCHAR2;
DBMS_LOB.SUBSTR (lob_loc IN BFILE, amount IN INTEGER:=32767, offset IN INTEGER:=1)
RETURN RAW;
El procedimiento TRIM corta el contenido a un nuevo tamao.
DBMS_LOB.TRIM (lob_loc IN OUT BLOB, newlen INTEGER);
DBMS_LOB.TRIM (lob_loc IN OUT CLOB, newlen INTEGER);
El procedimiento WRITE escribe datos a un LOB a partir de un desplazamiento especificado.
DBMS_LOB.WRITE (lob_loc IN OUT BLOB, amount IN BINARY_INTEGER, offset IN INTEGER,
buffer IN RAW);
DBMS_LOB.WRITE (lob_loc IN OUT CLOB, amount IN BINARY_INTEGER, offset IN INTEGER,
buffer IN VARCHAR2);
El procedimiento WRITEAPPEND escribe datos al final de un LOB.
DBMS_LOB.WRITEAPPEND (lob_loc IN OUT BLOB, amount IN BINARY_INTEGER, buffer IN RAW);
DBMS_LOB.WRITEAPPEND (lob_loc IN OUT CLOB, amount IN BINARY_INTEGER, buffer IN VARCHAR2);
8.7.2. Cmo guardar un archivo binario en un campo BLOB.
Aunque casi siempre es preferible guardar la ruta de un archivo en la base de datos en lugar del propio
archivo en modo binario, existen ciertas circunstancias en las que no nos queda otra solucin.
Veremos cmo cargar un fichero existente en el servidor en un campo BLOB de una tabla.

Oracle /140
Si los ficheros se encuentran en el servidor de Oracle, lo primero que debemos hacer es crear un objeto
directorio, y debemos permitir explcitamente el acceso al directorio en cuestin al usuario que ejecutar el
cdigo PL de insercin.
El siguiente script SQL crea el directorio virtual asignndole el nombre lgico DirImagenes. Para poder crear el
directorio debemos haber iniciado sesin como DBA.
CREATE OR REPLACE DIRECTORY DirImagenes AS 'C:\Oracle\Blob\Imagenes';
Como se ha dicho, para crear objetos directorio debemos haber iniciado la sesin con permisos de DBA, y
para leer el contenido de un directorio debemos asignar permisos a los usuarios que lo necesiten.
-- Se concede el permiso se acceso a un usuario llamado APP1
GRANT READ ON DIRECTORY DirImagenes TO APP1;
-- Se concede el permiso a todo el mundo
GRANT READ ON DIRECTORY DirImagenes TO PUBLIC;
Lo siguiente que vamos a necesitar es una tabla con un campo BLOB para almacenar la imagen. En este caso
vamos a llamar a la tabla "NIF", y su estructura es la siguiente:
CREATE TABLE NIF (
Id INT PRIMARY KEY,
Nif NVARCHAR2(9) NOT NULL UNIQUE,
Foto BLOB NULL) ;
El siguiente bloque de cdigo PL nos va a permitir cargar una foto, llamada "imagen.gif" en la tabla. Es
importante tener claro que el archivo "imagen.gif" debe existir fsicamente en el directorio
C:\Oracle\Blob\Imagenes.
DECLARE
v_bfile BFILE;
v_blob BLOB;
BEGIN
-- Para insertar un nuevo registro con la foto
INSERT INTO NIF (Id, Nif, Foto)
VALUES(1, '1111111A', EMPTY_BLOB()) -- se asigna un valor vaco en el campo Foto
RETURNING Foto INTO v_blob; -- se guarda la referencia del campo Foto
-- O bien para actualizar un registro existente con la foto
UPDATE NIF SET Foto = EMPTY_BLOB() WHERE Id=1
RETURNING Foto INTO v_blob; -- se guarda la referencia del campo Foto
-- El cdigo para insertar o actualizar es el mismo
v_bfile := BFILENAME('DIRIMAGENES', 'imagen.gif'); -- lee la ruta del archivo fsico
DBMS_LOB.FILEOPEN(v_bfile, DBMS_LOB.FILE_READONLY); -- abre el archivo
DBMS_LOB.LOADFROMFILE(v_blob, v_bfile, DBMS_LOB.GETLENGTH(v_bfile)); -- lee el contenido
DBMS_LOB.FILECLOSE(v_bfile); -- cierra el archivo
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
Hay tres aspectos a comentar de este cdigo:
El uso de RETURNING en la sentencia INSERT y UPDATE. Nos permite establecer una referencia al campo
Foto que es insertada en la variable v_blob.
La funcin EMPTY_BLOB. Nos permite insertar un valor vaco en un campo BLOB.
La funcin BFILENAME. Esta funcin devuelve un objeto BFILE que representa la ruta del fichero
"imagen.gif" que queremos almacenar en la tabla.
El uso del paquete predefinido de Oracle DBMS_LOB. Es el paquete que proporciona Oracle para trabajar
con tipos largos. Utilizamos las siguientes funciones:
- FILEOPEN: Abre el archivo definido por BFILE (v_bfile) en el modo indicado (en nuestro caso solo
lectura).
- LOADFROMFILE: Lee un determinado nmero de bytes (en nuestro caso todos) del fichero definido por
BFILE(v_bfile) en un objeto de tipo BLOB (v_blob).
- GETLENGTH: Devuelve el tamao del archivo en bytes.
- FILECLOSE: Cierra el archivo

Oracle /141
El resultado de todo esto es que hemos conseguido almacenar la imagen en la base de datos.
De forma anloga se puede cargar el contenido de un archivo de texto en un campo de tipo CLOB.
8.7.3. Cmo usar CLOB para campos de texto de ms de 4000 caracteres.
El tipo de dato CLOB permite crear campos en tablas de Oracle de tipo texto que contenga ms de los 4000
caracteres permitidos por VARCHAR2. Como CLOB no es un tipo bsico y se comporta como un objeto, para
acceder a l se tienen que utilizar las funciones especificadas en DBMS_LOB.
Como ejemplo, la tabla "Documento" incluye un campo CLOB:
CREATE TABLE Documento (
Id INTEGER PRIMARY KEY,
Titulo NVARCHAR2(100),
Contenido CLOB);
Para insertar un contenido corto podemos utilizar la instruccin INSERT habitual:
INSERT INTO Documento VALUES (1, 'Primer documento', 'Documento de ejemplo');
Algunas de las funciones del paquete DBMS_LOB que podemos usar para manipular campos CLOB son:
SUBSTR(campo, longitud, posicionInicial): retorna una subcadena de tipo VARCHAR2 de un campo CLOB dado.
GETLENGTH(campo): retorna el tamao de un campo CLOB dado.
Por ejemplo, si queremos seleccionar registros por parte del contenido podemos realizar una consulta como
la que sigue:
SELECT * FROM Documento WHERE DBMS_LOB.SUBSTR(Contenido, 4000, 1) LIKE '%loquesea%';
Si el contenido es mayor de 4000 caracteres deberemos realizar consultas sucesivas modificando la posicin
inicial.
Si queremos modificar el campo Contenido en un registro podemos hacerlo de la siguiente manera:
DECLARE
c CLOB;
texto VARCHAR2(100);
BEGIN
SELECT Contenido INTO c FROM Documento WHERE Id=1 FOR UPDATE;
texto := 'Un texto al inicio del contenido';
DBMS_LOB.WRITE (c, LENGTH(texto), 1, texto);
COMMIT;
END;
El cdigo PL precedente modifica el campo Contenido del registro de Id 1 aadiendo un texto al principio del
contenido actual. Ntese el uso de la clusula FOR UPDATE en la consulta que recupera lareferencia del campo
CLOB. Este clusula es necesaria para bloquear el acceso al registro. Oracle no permite actualizar un campo
CLOB si no se aplica un bloqueo.
8.7.4. Cmo leer un documento de texto en una variable de tipo CLOB.
Supongamos creado un objeto DIRECTORY denominado DOCS que contiene el documento que queremos leer.
Un bloque de cdigo para copiar el contenido de un documento de texto dentro de una variable de tipo CLOB
sera el siguiente:
DECLARE
v_bfile BFILE;
v_clob CLOB;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_clob,TRUE); -- se inicializa el CLOB en el espacio de tablas temporal
v_bfile := BFILENAME('DOC', 'texto.txt'); -- lee la ruta del archivo fsico
DBMS_LOB.FILEOPEN(v_bfile, DBMS_LOB.FILE_READONLY);
DBMS_LOB.LOADFROMFILE(v_clob, v_bfile, DBMS_LOB.GETLENGTH(v_bfile));
DBMS_LOB.FILECLOSE(v_bfile);
-- Cdigo para procesar el contenido de la variable "v_clob"
--
END;

9. SQL Dinmico
Se habla de ejecucin dinmica cuando la sentencia SQL que va a ejecutar nuestro servidor no est escrita en
su totalidad previamente, sino que se crea cada vez que tenemos que ejecutarla. Frente a esta forma de
trabajar tenemos el SQL "normal", donde la sentencia SQL esta previamente escrita y lo nico que hay que

Oracle /142
hacer es decidir cundo la ejecutamos.
9.1. Sentencias DML con SQL dinmico.
PL/SQL ofrece la posibilidad de ejecutar sentencias SQL a partir de cadenas de caracteres. Para ello debemos
emplear la instruccin EXECUTE IMMEDIATE.
Podemos obtener informacin acerca del nmero de filas afectadas por la instruccin ejecutada por EXECUTE
IMMEDIATE utilizando SQL%ROWCOUNT.
El siguiente ejemplo muestra la ejecucin de un comando SQL dinmico.
DECLARE
ret NUMBER;
FUNCTION fn_Ejecuta RETURN NUMBER IS
sql_str VARCHAR2(1000);
BEGIN
sql_str := 'UPDATE Alumno SET nombre = ''Nuevo nombre'' WHERE nif=''22222222B''';
EXECUTE IMMEDIATE sql_str;
RETURN SQL%ROWCOUNT;
END fn_Ejecuta ;
BEGIN
ret := fn_Ejecuta;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(ret));
END;
Podemos adems parametrizar nuestras consultas a travs de variables host. Una variable host es una variable
que pertenece al programa que est ejecutando la sentencia SQL dinmica y que podemos asignar en el
interior de la sentencia SQL con la palabra clave USING. Las variables host van precedidas de dos puntos (:).
El siguiente ejemplo muestra el uso de variables host para parametrizar una sentencia SQL dinmica.
DECLARE
ret NUMBER;
FUNCTION fn_Ejecuta (pNombre VARCHAR2, pNif VARCHAR2) RETURN NUMBER
IS
sql_str VARCHAR2(1000);
BEGIN
sql_str := 'UPDATE Alumno SET nombre = :new_nombre WHERE nif = :nif';
EXECUTE IMMEDIATE sql_str USING pNombre, pNif;
RETURN SQL%ROWCOUNT;
END fn_Ejecuta ;
BEGIN
ret := fn_Ejecuta ('Nuevo nombre', '2222222B');
DBMS_OUTPUT.PUT_LINE(TO_CHAR(ret));
END;
9.2. Cursores con SQL dinmico.
Con SQL dinmico tambin podemos utilizar cursores dinmicos.
9.2.1. Cursores dinmicos implcitos.
Para utilizar un cursor implcito solo debemos construir nuestra sentencia SELECT en una variable de tipo
caracter y ejecutarla con EXECUTE IMMEDIATE utilizando la clusula INTO o BULK COLLECT INTO para
recuperar el resultado de la sentencia.
El siguiente ejemplo ejecuta dinmicamente una consulta que retorna el nmero de alumnos y asigna el valor
de retorno en la variable l_cnt.
DECLARE
str_sql VARCHAR2(255);
l_cntVARCHAR2(20);
BEGIN
str_sql := 'SELECT COUNT(*) FROM Alumno';
EXECUTE IMMEDIATE str_sql INTO l_cnt;
DBMS_OUTPUT.PUT_LINE('El nmero de alumnos es ' || l_cnt);
END;
Estos cursores dinmicos implcitos tambin admiten variables de host, como en el siguiente ejemplo, donde
se obtiene el nmero de alumnos de una localidad determinada (en este caso Madrid):

Oracle /143
DECLARE
str_sql VARCHAR2(255);
l_cntVARCHAR2(20);
BEGIN
str_sql := 'SELECT COUNT(*) FROM Alumno WHERE localidad = :local';
EXECUTE IMMEDIATE str_sql USING 'Madrid' INTO l_cnt;
DBMS_OUTPUT.PUT_LINE('El nmero de alumnos de Madrid es ' || l_cnt);
END;
Slo los comandos INSERT, UPDATE y DELETE pueden tener variables enlazadas de salida. Estas variables
pueden enlazarse con la clusula RETURNING BULK COLLECT INTO del comando EXECUTE IMMEDIATE. En el
siguiente ejemplo se muestra esto mediante una consulta de actualizacin dinmica que modifica las notas de
algunos alumnos y recupera los apellidos de los mismos.
DECLARE
TYPE ListaNifs IS TABLE OF VARCHAR2(9);
nifs ListaNifs;
nota_corte NUMBER := 5;
consulta VARCHAR(200);
BEGIN
consulta := 'UPDATE Nota SET valor = valor+1 WHERE valor < :1 RETURNING nif INTO :2';
EXECUTE IMMEDIATE consulta USING nota_corte RETURNING BULK COLLECT INTO nifs;
FOR nif IN 1..nifs.LAST LOOP -- Se muestran los nifs de alumnos
DBMS_OUTPUT.PUT_LINE(nif);
END LOOP;
END;
Para enlazar varias variables de entrada de un comando SQL, podemos usar el comando FORALL y la clusula
USING, tal como se muestra en el siguiente ejemplo. El comando SQL no puede ser una consulta.
DECLARE
TYPE ListaIds IS TABLE OF NUMBER(38);
TYPE ListaNifs IS TABLE OF VARCHAR2(9);
idModulos ListaIds;
nifs ListaNifs;
BEGIN
idModulos := ListaIds(1, 3, 8, 10);
FORALL i IN 1..4 EXECUTE IMMEDIATE
'UPDATE Nota SET valor = valor+1 WHERE idModulo = :1 RETURNING nif INTO :2'
USING idModulos(i) RETURNING BULK COLLECT INTO nifs;
END;
En este ejemplo, mediante el comando FORALL se actualiza la nota de alumnos en cada uno de los mdulos
establecidos en la coleccin idModulos, y se recupera el nif de los alumnos de los cuales se actualiz la nota
dentro de la coleccin nifs.
9.2.2. Cursores dinmicos explcitos.
Trabajar con cursores explcitos es tambin muy fcil. nicamente destacar el uso de REF CURSOR para
declarar un nuevo tipo del cursor generado con SQL dinmico.
DECLARE
TYPE CURSOR_DINAMICO IS REF CURSOR; -- Se crea un tipo de cursor dinmico
c_cursor CURSOR_DINAMICO; -- Se declara una variable del nuevo tipo
fila Alumno%ROWTYPE;
v_queryVARCHAR2(255);
BEGIN
v_query := 'SELECT * FROM Alumno';
OPEN c_cursor FOR v_query; -- Se abre el cursor dinmico
LOOP
FETCH c_cursor INTO fila;
EXIT WHEN c_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(fila.nif);
END LOOP;
CLOSE c_cursor;
END;

Oracle /144
Al contrario que los cursores estticos, los cursores dinmicos no pueden ser utilizados con el bucle FOR.
Las variables host tambin se pueden utilizar en los cursores mediante la palabra USING.
DECLARE
TYPE CURSOR_DINAMICO IS REF CURSOR; -- Se crea un tipo de cursor dinmico
c_cursor CURSOR_DINAMICO; -- Se declara una variable del nuevo tipo
v_queryVARCHAR2(255);
BEGIN
v_query := 'SELECT * FROM Alumno WHERE localidad = :1';
OPEN c_cursor FOR v_query USING 'Madrid'; -- Se abre el cursor dinmico
...
CLOSE c_cursor;
END;
9.2.3. El paquete DBMS_SQL.
Antes de Oracle9i el SQL dinmico requera del uso del paquete DBMS_SQL. Todava podemos seguir usando
las funciones y procedimientos de este paquete. Usando DBMS_SQL podemos tener un mayor control sobre el
flujo de proceso del SQL dinmico, pero es generalmente ms complejo de escribir que el SQL dinmico
nativo visto previamente.
El paquete DBMS_SQL incorpora las siguientes funciones para gestionar cursores dinmicos:
DBMS_SQL.OPEN_CURSOR, crea un cursor dinmico y retorna un valor entero que lo identifica.
DBMS_SQL.PARSE, asigna una consulta a un cursor y lo ejecuta. Tiene tres parmetros: el identificador del
cursor devuelto por DBMS_SQL.OPEN_CURSOR, el texto de la consulta, y la constante DBMS_SQL.NATIVE.
DBMS_SQL.CLOSE_CURSOR, cierra un cursor dinmico. Tiene un nico parmetro: el identificador del
cursor devuelto por DBMS_SQL.OPEN_CURSOR.
Antes de nada, como usuario SYS, necesitamos darle privilegios de ejecucin sobre DBMS_SQL al usuario que
va a ejecutar el procedimiento:
GRANT EXECUTE ON DBMS_SQL TO usuario;
Un ejemplo sencillo sera el siguiente:
CREATE OR REPLACE PROCEDURE DBMS_EJEMPLO
AS
ID INTEGER;
BEGIN
ID := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(ID, 'CREATE TABLE Prueba (c1 NUMBER(10)) ', DBMS_SQL.NATIVE);
DBMS_SQL.CLOSE_CURSOR(ID);
END;
Para que este procedimiento pueda crear la tabla, previamente necesitaremos darle al usuario permisos para
crear dicha tabla o crear cualquier tabla:
DBMS_SQL.PARSE(ID, 'GRANT CREATE ANY TABLE TO ' || USER );
Tambin podemos usar variables host del siguiente modo:
DECLARE
idc INTEGER;
v_id INTEGER;
v_nif VARCHAR2(9);
tmp INTEGER;
BEGIN
idc := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (idc,'SELECT idMatricula, nifFROM Matricula WHERE ao= :anho',DBMS_SQL.NATIVE);
-- Llenamos el parmetro que enviamos
DBMS_SQL.BIND_VARIABLE(idc, ':anho', 2008);
-- Definimos las columnas que recibiremos del Select. Declaramos que el tipo de dato de
-- las columnas deber ser del mismo tipo de dato que las variables resultado.
DBMS_SQL.DEFINE_COLUMN(idc, 1, v_id);
DBMS_SQL.DEFINE_COLUMN(idc, 2, v_nif, 9);
-- Ejecutamos el cursor.
TMP := DBMS_SQL.EXECUTE(idc);
-- La funcin FETCH_ROWS recupera filas y retorna el nmero de filas que quedan
WHILE DBMS_SQL.FETCH_ROWS(idc) > 0 LOOP

Oracle /145
-- Tomamos el valor de las columnas 1 y 2
DBMS_SQL.COLUMN_VALUE(idc, 1, v_id);
DBMS_SQL.COLUMN_VALUE(idc, 2, v_nif);
...
END LOOP;
-- Cerramos el cursor
DBMS_SQL.CLOSE_CURSOR(idc);
END;
9.3. Un ejemplo de cmo usar y cmo no usar SQL dinmico.
Para concluir vamos a ver un ejemplo donde podemos usar SQL dinmico.
A veces tenemos que crear una sentencia que ordene una tabla segn una columna que depender de algn
parmetro que nos pasa el usuario. Eso lo podemos resolver utilizando una funcin almacenada y una
sentencia como:
CREATE PROCEDURE OrdenarPor (pColumna VARCHAR2)
IS
v_SQL varchar2(50);
BEGIN
v_SQL := 'INSERT INTO UnaTabla SELECT * FROM OtraTabla ORDER BY ' || pColumna;
EXECUTE IMMEDIATE v_SQL;
END;
Esto est en la lnea de todo lo que hemos estado viendo. Es una solucin sencilla pero plantea varios
problemas de seguridad y rendimiento. Por ejemplo, si se invoca el procedimiento de la siguiente forma:
OrdenarPor('nombre; DROP TABLE OtraTabla;');
Estamos permitiendo inyeccin de cdigo perjudicial. As que intentaremos crear un procedimiento
almacenado con cdigo normal que haga lo mismo, pero con ms seguridad:
CREATE PROCEDURE OrdenarPor (pColumna VARCHAR2)
IS
V_SQL varchar2(50);
BEGIN
INSERT INTO UnaTabla
SELECT * FROM OtraTabla ORDER BY
CASE pColumna
WHEN 'columna1' THEN TO_CHAR(columna1)
WHEN 'columna2' THEN TO_CHAR(columna2)
ELSE TO_CHAR(columna3)
END;
END;
Cierto que es un poco ms complicado (se utiliza la funcin CASE), pero no hay inyeccin de cdigo posible y
una vez calculado el plan de ejecucin se utilizar sin recompilar una y otra vez.
Como conclusin nos queda que el SQL dinmico es una herramienta potente pero peligrosa si no se trata
con cuidado, y que la mayora de las veces no necesitamos recurrir a ella porque siempre podemos encontrar
otra solucin.
10. PL/SQL y Java
Otra de las virtudes de PL/SQL es que permite trabajar conjuntamente con Java.PL/SQL es un excelente
lenguaje para la gestin de informacin, pero en ocasiones podemos necesitar de un lenguaje de
programacin ms potente. Por ejemplo, podramos necesitar consumir un servicio Web, conectar a otro
servidor, trabajar con sockets, etc. Para estos casos podemos trabajar conjuntamente con PL/SQL y Java.
Para poder trabajar con Java y PL/SQL debemos realizar los siguientes pasos:
- Crear el programa Java y cargarlo en la base de datos.
- Crear un programa de recubrimiento (Wrapper) de PL/SQL.
10.1. Creacin de Objetos Java en la base de datos ORACLE.
Oracle incorpora su propia versin de la mquina virtual Java y del JRE. Esta versin de Java se instala
conjuntamente con Oracle.
Para crear objetos Java en la base de datos podemos utilizar la utilidad LoadJava de Oracle desde la lnea de

Oracle /146
comandos o bien crear objetos JAVA SOURCE en la propia base de datos.
La sintaxis para la creacin de objetos JAVA SOURCE en Oracle es la siguiente.
CREATE [OR REPLACE] AND COMPILE JAVA SOURCE
NAMED mombreOrigenJava
AS
public class NombreDeClase {
...
};
El siguiente ejemplo crea y compila una clase Java OracleJavaClass en el interior del objeto JAVA SOURCE
FuentesJava. Un aspecto muy a tener en cuenta es que los mtodos de la clase Java que queramos invocar
desde PL/SQL deben ser estticos.
CREATE OR REPLACE AND COMPILE JAVA SOURCE
NAMED FuentesJava
AS
public class OracleJavaClass {
public static String saluda(String nombre) {
return ("Hola desde Java " + nombre);
}
};
Un mismo objeto JAVA SOURCE puede contener varias clases de Java.
CREATE OR REPLACE AND COMPILE JAVA SOURCE
NAMED FuentesJava
AS
public class OracleJavaClass {
public static String saluda(String nombre) {
return ("Hola desde Java" + nombre);
}
}
public class OracleJavaMejorada{
public static String saludoMejorado(String nombre) {
return ("Saludo mejorado desde Java para " + nombre);
}
};
La otra opcin sera guardar nuestro cdigo java en el archivo OracleJavaClass.java, compilarlo y cargarlo en
Oracle con LoadJava.
A continuacin se muestran ejemplos del uso de la utilidad LoadJava.
loadJava -help
loadJava -userusuario/password@basedatos -v -f -r OracleJavaClass.class
loadJava -userusuario/password@basedatos -v -f -r OracleJavaClass.java
Tambin se proporciona el comando DropJava para descargar clases previamente cargadas.
10.2. Ejecucin de programas Java con PL/SQL
Una vez que tenemos listo el programa de Java debemos integrarlo con PL/SQL. Esto se realiza a travs de
subprogramas de recubrimiento llamados wrappers. No podemos crear un wrapper en un bloque annimo.
La sintaxis general es la siguiente:
CREATE [OR REPLACE] FUNCTION|PROCEDURE nombre [(parmetros)]
[RETURN tipo]
IS|AS
LANGUAGE JAVA NAME 'clase.metodo [ return tipo]' ;
El siguiente ejemplo muestra el wrapper para nuestra funcin Saludo.
CREATE OR REPLACE FUNCTION Saluda_wrap (nombre VARCHAR2)
RETURN VARCHAR2
AS
LANGUAGE JAVA NAME
'OracleJavaClass.saluda(java.lang.String) return java.lang.String';
Una vez creado el wrapper, podremos ejecutarlo como cualquier otra funcin o procedimiento de PL/SQL.
Debemos crear un wrapper por cada funcin java que queramos ejecutar desde PL/SQL.
Cuando ejecutemos el wrapper, es decir, la funcin "Saluda_wrap", internamente se ejecutar la clase java y se

Oracle /147
invocar el mtodo esttico "OracleJavaClass.saluda".
Un aspecto a tener en cuenta es que es necesario proporcionar el nombre del tipo java completo, es decir,
debemos especificar java.lang.String en lugar de nicamente String.
La ejecucin de este ejemplo en SQL*Plus:
SQL> SELECT SALUDA_WRAP('DEVJOKER') FROM DUAL;
Genera la siguiente salida:
SALUDA_WRAP('DEVJOKER')
--------------------------------------
Hola desde Java DEVJOKER
Una recomendacin de diseo sera agrupar todos los wrapper en un mismo paquete PL. En el caso de que
nuestro programa Java necesitase de paquetes Java adicionales, deberamos cargarlos en la base de datos con
la utilidad LoadJava.
10.3. Correspondencia de tipos entre Java y Oracle.
Cuando creamos un wrapper entre un procedimiento de Oracle y un mtodo de Java, que incluya parmetros,
debemos especificar un tipo de dato de Java que sea compatible con el tipo de dato de Oracle.
La siguiente tabla muestra la correspondencia de conversin de los tipos Java ms comunes a tipos Oracle:
Tipos de Java Tipos de Oracle
byte, short, int, long, float, double Number
Char, String Char, Varchar2, Nchar, Nvarchar2
java.sql.Date Date
java.sql.ResultSet Ref Cursor
La siguiente tabla muestra la correspondencia de conversin de los tipos Oracle a tipos Java:
Tipos de Oracle Tipos de Java
Number java.math.BigDecimal
Char, Varchar2, Nchar, Nvarchar2 String
Date oracle.sql.TIMESTAMP
Blob oracle.sql.BLOB
Clob oracle.sql.CLOB
VARRAY o TABLE oracle.sql.ARRAY
Tipo de objeto de Oracle oracle.sql.STRUCT

10.4. Paso de cursores Oracle a mtodos de Java.


Como ejemplo, veremos cmo utilizar un cursor de Oracle dentro del cdigo Java. Para ello se crea en Java
un mtodo llamado procesaConsulta que recibe como parmetro un objeto java.sql.ResultSet.
CREATE OR REPLACE AND COMPILE JAVA SOURCE
NAMED MiClaseJava AS
public class MiClase {
public static void procesaConsulta (java.sql.ResulSet rs) {
while (rs.next) {
// procesamos los registros
}
}
};
Para poder invocar el cdigo de mtodo Java se crea un wrapper dentro de un paquete, como el siguiente:
CREATE OR REPLACE PACKAGE MI_PAQUETE IS
TYPE Mi_Cursor IS REF CURSOR; -- Declaramos el tipo de cursor dinmico
PROCEDURE Procesa_Consulta ( mc Mi_Cursor) IS
LANGUAGE JAVA NAME 'MiClase.procesaConsulta(java.sql.ResultSet)' ;
END MI_PAQUETE;
Ahora podemos invocar el procedimiento, por ejemplo desde el siguiente bloque:
DECLARE
mc MI_PAQUETE.Mi_Cursor;
BEGIN
OPEN mc FOR 'SELECT ''Ejemplo de cursor'' AS texto FROM DUAL';
MI_PAQUETE.Procesa_Consulta(mc);

Oracle /148
CLOSE mc;
END;

10.5. Paso de objetos Oracle a mtodos de Java.


Como se ver en un captulo posterior, el modelo objeto-relacional de Oracle permite crear tipos de objetos
dentro de una base de datos. Por ejemplo, un objeto Oracle que almacene la informacin de un cliente se
creara con la siguiente instruccin:
CREATE OR REPLACE TYPE Cliente_t AS OBJECT (
codigo NUMBER(6,0); -- campo 0
nombre NVCHAR2(100); -- campo 1
apellidos NVACHAR2(200); -- campo 2
);
Los objetos Oracle pueden ser pasados a mtodos de Java encapsulados con el tipo oracle.sql.STRUCT. (Este
tipo est incluido con la librera del driver JDBC de Oracle para Java.)
Y ahora, creamos un mtodo de Java que reciba como parmetro un objeto Client_t y retorne el nombre
completo con el formato "apellidos, nombre":
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED MiClaseJava AS
public class MiClase {
public static String nombreCompleto (oracle.sql.STRUCT c) throws java.sql.SQLException {
// Se obtienen los campos de cliente como un array de objetos
Object[] campos = c.getAttributes();
// Para acceder a los campos debemos moldearlos al tipo apropiado
String nombre = (String) (campo[1]); // campo[1] == nombre
String apel = (String) (campo[2]); // campo[2] == apellidos
// Se retorna el valor
return apel + ', ' + nombre;
}
};
La funcin de Oracle que mapear la funcin de Java es:
CREATE OR REPLACE FUNCTION NombreCompleto(c Cliente_t)
RETURN NVARCHAR2 AS LANGUAGE JAVA NAME
"MiClase.nombreCompleto(oracle.sql.STRUCT) return java.lang.String";
10.5.1. Funcionalidades de la clase STRUCT.
Si compilamos cdigo con el estndar JDBC 2.0, entonces podemos crear instancias de java.sql.Struct, y usar
sus mtodos estndar siguientes:
getAttributes(map): Recupera el valor de los atributos, usando entradas en el mapa especificado para
determinar las clases Java que usar y materializar cualquier atributos perteneciente a la estructura del tipo
de objeto Oracle. Los tipos Java para cualquier otro valor de atributo debera ser el mismo que para las
llamadas al mtodo getObject() del tipo SQL subyacente.
getAttributes(): Similar al mtodo getAttributes(map), excepto que usa los tipos por defecto para los
atributos.
getSQLTypeName(): Retorna un string Java que representa el nombre completo cualificado
(esquema.nombreDelTipoSql) del tipo de objeto Oracle que representa esta estructura.
Si queremos tomar las ventajas de las funcionalidades extendidas ofrecidas por los mtodo definidos de
Oracle, entonces podemos crear instancias de oracle.sql.STRUCT.
La clase oracle.sql.STRUCT implementa la interfaz java.sql.Struct y proporciona funcionalidades ms all del
estndar JDBC 2.0. Los mtodos adicionales de esta clase son los siguientes:
getOracleAttributes(): Recupera los valores del array de valores como objetos oracle.sql.*.
getDescriptor(): Retorna el objeto StructDescriptor para el tipo SQL que se corresponde con el objeto
STRUCT.
getJavaSQLConnection(): Retorna la conexin actual (java.sql.Connection).
toJdbc(): Consulta el mapa de tipos por defecto de la conexin para determinar qu clases mapean, y
entonces usa toClass().
toJdbc(map): Consulta el mapa de tipos especificado para determinar que clases mapean, y entonces usa
toClass().

Oracle /149
10.5.2. Descriptores STRUCT.
Crear y usar un objeto STRUCT requiere un descriptor (una instancia de la clase oracle.sql.StructDescriptor) que
defina la correspondencia entre el tipo SQL (como Cliente_t) y su correspondiente objeto STRUCT.
Antes de crear un objeto STRUCT debe existir primero un StructDescriptor para el tipo de objeto Oracle. Si no
existe, podemos crearlo mediante el mtodo esttico StructDescriptor.createDescriptor(). Este mtodo requiere
que pasemos el nombre del tipo SQL y un objeto de conexin:
StructDescriptor structdesc = StructDescriptor.createDescriptor(nombre_tipo_sql, conexion);
Una vez que tenemos el objeto StructDescriptor para el tipo de objeto de Oracle, podemos crear el objeto
STRUCT. Para hacer esto necesitamos pasar en su constructor el StructDescriptor, el objeto de conexin y un
array de objetos Java que contenga los valores para los atributos.
STRUCT struct = new STRUCT(structdesc, conexion, atributos);
Donde atributos es un array del tipo java.lang.Object[].
Un StructDescriptor puede pasar a travs de un tipo de objeto. Esto significa que contiene informacin sobre
el tipo de objeto, incluyendo el cdigo de tipo, el nombre del tipo, y cmo convertirlo. La clase
StructDescriptor incluye los siguientes mtodos:
getName(): Retorna el nombre completo cualificado del tipo SQL (esto es, esquema y nombre del tipo
Oracle, como Empleado.Cliente_t).
getLength(): Retorna el nmero de campos del tipo de objeto.
getMetaData(): Retorna los metadatos del tipo (de forma similar al mtodo getMetaData() del un objeto
ResultSet). El objeto ResultSetMetaData retornado contiene el nombre de atributos, cdigo del tipo de
atributo, e informacin de precisin del tipo de atributos.
10.5.3. Funcionalidad de buffering automtico para los atributos.
El driver JDBC de Oracle proporciona mtodos pblicos para habilitar y deshabilitar el "buffering" de los
atributos de una estructura.
Los siguientes mtodos se incluyen dentro de la clase oracle.sql.STRUCT:
public void setAutoBuffering(boolean enable)
public boolean getAutoBuffering()
El mtodo setAutoBuffering(boolean) habilita o deshabilita el auto-buffering. El mtodo getAutoBuffering()
retorna el modo actual. Por defecto el auto-buffering est deshabilitado.
El auto-buffering es til en aplicaciones JDBC cuando los atributos de STRUCT son accedidos ms de una vez
mediante los mtodos getAttributes() y getArray().
Nota. El buffering puede causar que las aplicaciones JDBC consuman una significativa cantidad de
memoria.
10.6. Paso de arrays desde un programa Java a un procedimiento almacenado de Oracle.
En este apartado se explicar cmo pasar un array a un procedimiento de Oracle desde un programa de Java.
Previamente se crea en la base de datos un tipo de VARRAY y un procedimiento almacenado que recibe como
parmetro un VARRAY y lo retorna modificado:
-- Se crea el tipo de VARRAY de como mximo 10 nmeros
CREATE TYPE Tipo_Varray IS VARRAY(10) OF NUMBER;
-- Un procedimiento que incrementa en una unidad los elementos del VARRAY
CREATE OR REPLACE PROCEDURE INCREMENTAR(V IN OUT TIPO_VARRAY)
IS
BEGIN
FOR i IN V.FIRST..V.LAST LOOP
V(i) := V(i) + 1;
END LOOP;
END;
En el siguiente ejemplo se muestra cmo pasar un array de Java al procedimiento almacenado INCREMENTAR
de Oracle:
import java.math.BigDecimal;
import java.sql.*;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import oracle.sql.*;
public class MiClase {

Oracle /150
public static void main(String[] args) throws Exception {
Connection conn = null;
OracleCallableStatement comando = null;
// Se carga el driver de Oracle. Previamente se debe aadir la librera correspondiente al classpath
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
// Se realiza la conexin y se crea el comando de invocacin del procedimiento
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:BD", "propietario", "password");
comando = (OracleCallableStatement) conn.prepareCall("{call INCREMENTAR(?,?)}");
// Se inicializan las variables y parmetros de tipo array
ArrayDescriptor ad = new ArrayDescriptor("TIPO_VARRAY", conn);
double [] numeros = {1.1, 2.3, 4.45, 6.8};
ARRAY unArray = new ARRAY(ad, conn, numeros);
// Se pasa el parmetro al comando y se registra como parmetro de salida
comando.setARRAY(1, unArray);
comando.registerOutParameter(1, OracleTypes.ARRAY, "TIPO_VARRAY");
// Se ejecuta el comando y se recupera el parmetro
comando.execute();
BigDecimal[] nos = (BigDecimal []) comando.getARRAY(1).getArray();
...
// Se cierra la conexin
conn.close();
}
}
Hay que resaltar dos cuestiones:
- El nombre del tipo array debe ser pasado en maysculas ( "TIPO_ARRAY") porque as es como lo guarda
Oracle. Para ms seguridad podemos indicar el propietario del tipo, tambin en maysculas:
"PROPIETARIO.TIPO_ARRAY".
- Al recuperar el parmetro debemos moldearlo como un array de objetos java.math.BigDecimal y no como
objetos Double. Como alternativa se puede usar el mtodo comando.getARRAY(1).getDoubleArray(), el cual
devuelva ya un array de tipo double. Anlogamente, el tipo ARRAY posee los mtodos getFloatArray(),
getIntArray(), getLongArray() y getShortArray().

Nota. Slo es posible pasar arrays de Java a arrays de Oracle creados con el comando CREATE TYPE.
10.7. Cmo pasar y retornar un array de objetos a travs de un procedimiento almacenado.
Este ltimo ejemplo combina el uso de objetos y arrays. Supongamos creado en Oracle los siguientes tipos y
funcin:
-- Se crea un tipo de objeto
CREATE TYPE Venta_t AS OBJECT (
producto VARCHAR2(20); -- campo 0
precio NUMBER(14,2); -- campo 1
);
-- Se crea un tipo de array anidado
CREATE TYPE Ventas_TA AS TABLE OF Venta_t;
-- Una funcin que recibe un array de ventas y lo retorna modificado aplicando un IVA.
CREATE OR REPLACE PROCEDURE ActualizarVentas(v Ventas_TA, iva NUMBER) RETURN Ventas_TA
IS
BEGIN
FOR I IN v.FIRST..v.LAST LOOP
v(I).precio := v(I).precio *(1+iva);
END LOOP;
RETURN v;
END;
El cdigo siguiente invoca la funcin almacenada, para ello crea un array de objetos de venta y lo pasa como
parmetro a la funcin. Una vez ejecutada la funcin se recupera el array modificado:
import java.math.BigDecimal;
import java.sql.*;
import oracle.jdbc.OracleCallableStatement;

Oracle /151
import oracle.jdbc.OracleTypes;
import oracle.sql.*;
public class MiClase {
public static void main(String[] args) throws Exception {
Connection conn = null;
OracleCallableStatement comando = null;
// Se realiza la conexin y se crea el comando de invocacin del procedimiento
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:BD", "propietario", "password");
comando = (OracleCallableStatement) conn.prepareCall("{? = call ActualizarVentas( ?,?)}");
// Se crea un elemento de tipo venta como un objeto STRUCT
STRUCT [] items = new STRUCT[2]; // este array contendr las ventas
StructDescriptor sd = new StructDescriptor("VENTA_T", conn);
Object [] campos1 = {"producto 1", 12.4};// este array representa los datos de una venta
items[0] = new STRUCT(sd, conn, campos1); // aado la primera venta
Object [] campos2 = {"producto 2", 10.24}; // este array representa los datos de otra venta
items[1] = new STRUCT(sd, conn, campos2); // aado la segunda venta
// Se crea el array que pasaremos por parmetro del tipo ARRRAY
ArrayDescriptor ad = new ArrayDescriptor("VENTAS_TA", conn);
ARRAY lasVentas = new ARRAY(ad, conn, items);
// Se registra el primer parmetro como de salida, y se pasa valor a los otros parmetros
comando.registerOutParameter(1, OracleTypes.ARRAY, "VENTA_TA");
comando.setARRAY(2, lasVentas);
comando.setARRAY(3, 16.00);
// Se ejecuta el comando y se recupera el parmetro
comando.execute();
Object [] resultado = (Object []) comando.getARRAY(1).getArray();
// Se recupera la primera venta
STRUCT venta1 = (STRUCT) resultado[0];
// Se recuperan los valores de los campos de venta como un array de objetos
Object [] campo = venta1. getAttributes();
// Se imprime el precio de la primera venta:
System.out.println("Precio con iva = " + campo[1]);
...
// Se cierra la conexin
conn.close();
}
}
10.8. Paquete DBMS_JAVA.
El paquete DBMS_JAVA incluye funciones y procedimientos que proporcionan un punto de entrada para
acceder a las funcionalidades del sistema de gestin de bases de datos relacionales (RDBMS) mediante Java.
A continuacin se describen brevemente las funciones y procedimientos que incluye:
FUNCTION longname (shortname VARCHAR2) RETURN VARCHAR2
Retorna el nombre completo cualificado de un objeto de Java especificado. Debe tenerse en cuenta que
las clases y mtodos de Java pueden tener un nombre excesivamente largo para un identificador SQL, de
forma que la Mquina Virtual Java de Oracle usa abreviaturas internas para el acceso a SQL.
FUNCTION shortname (longname VARCHAR2) RETURN VARCHAR2
Esta funcin es la inversa a longname().
FUNCTION get_compiler_option(name VARCHAR2, optionName VARCHAR2) RETURN VARCHAR2
Retorna el valor de la opcin especificada en el segundo parmetro para el compilador Java o SQLJ
proporcionados con Oracle. El primer parmetro es un nombre de paquete Java, un nombre de clase
completamente cualificado o un string vaco.
PROCEDURE set_compiler_option(name VARCHAR2, optionName VARCHAR2, value VARCHAR2)
Asigna el valor de la opcin especificada en el segundo parmetro para el compilador Java o SQLJ
proporcionados con Oracle. El primer parmetro es un nombre de paquete Java, un nombre de clase
completamente cualificado o un string vaco.
PROCEDURE reset_compiler_option(name VARCHAR2, optionName VARCHAR2)
Asigna el valor por defecto de la opcin especificada en el segundo parmetro para el compilador Java o

Oracle /152
SQLJ proporcionados con Oracle.
FUNCTION resolver(name VARCHAR2, owner VARCHAR2, type VARCHAR2) RETURN VARCHAR2
Retorna la especificacin de resolucin para un objeto especificado en name (con su nombre corto),
dentro del esquema especificado en owner, con el tipo de objeto especificado en type (que puede ser
'SOURCE' o 'CLASS'). El invocador debe tener privilegios EXECUTE y acceso al objeto para usar esta
funcin.
Por ejemplo, si se invoca dbms_java.resolver('tst', 'SCOTT', 'CLASS') el valor devuelto puede ser ((*
SCOTT)(* PUBLIC)).
FUNCTION derivedFrom(name VARCHAR2, owner VARCHAR2, type VARCHAR2) RETURN VARCHAR2
Retorna el nombre del origen del objeto especificado (con su nombre corto), con el esquema y tipo
especificados (que puede ser 'SOURCE' o 'CLASS'). El invocador debe tener privilegios EXECUTE y acceso
al objeto para usar esta funcin.
FUNCTION fixed_in_instance(name VARCHAR2, owner VARCHAR2, type VARCHAR2) RETURN NUMBER
Retorna el estado de guardado del objeto especificado (con su nombre corto), con el esquema y tipo
especificados (que puede ser 'RESOURCE', 'SOURCE', 'CLASS', o 'SHARED_DATA'). El invocador debe
tener privilegios EXECUTE y acceso al objeto para usar esta funcin.
El valor devuelto es 0 para indicar no guardado, y 1 para indicar guardado.
PROCEDURE set_output(buffersize NUMBER)
Redirige la salida de los procedimientos almacenados de Java y triggers al paquete DBMS_OUTPUT.
PROCEDURE start_debugging(host VARCHAR2, port NUMBER, timeout NUMBER)
Inicia el agente de depuracin sobre un host y puerto especificados.
PROCEDURE stop_debugging
Detiene el agente de depuracin.
PROCEDURE restart_debugging(timeout NUMBER)
Reinicia el agente de depuracin.
PROCEDURE export_source(name VARCHAR2, schema VARCHAR2, blob BLOB)
PROCEDURE export_source(name VARCHAR2, blob BLOB)
PROCEDURE export_source(name VARCHAR2, clob CLOB)
Estos procedimientos se usan para exportar un origen Java como un objeto de esquema de origen Java a
una base de datos de Oracle. El origen se especifica en el parmetro name. Se puede especificar un
esquema, si no se utilizar el actual.
PROCEDURE export_class(name VARCHAR2, schema VARCHAR2, blob BLOB)
PROCEDURE export_class(name VARCHAR2, blob BLOB)
Estos procedimientos se usan para exportar una clase de Java como un objeto de esquema de clase Java
a una base de datos de Oracle. La clase se especifica en el parmetro name. Se puede especificar un
esquema, si no se utilizar el actual.
PROCEDURE export_resource(name VARCHAR2, schema VARCHAR2, blob BLOB)
PROCEDURE export_resource(name VARCHAR2, blob BLOB)
PROCEDURE export_resource(name VARCHAR2, schema VARCHAR2, clob CLOB)
PROCEDURE export_resource(name VARCHAR2, clob CLOB)
Estos procedimientos se usan para explorar un recurso a una base de datos Oracle como un objeto de
esquema de recurso.
PROCEDURE loadjava(options VARCHAR2)
PROCEDURE loadjava(options VARCHAR2, resolver VARCHAR2)
Estos procedimientos permiten cargar clases dentro de la base de datos, siendo una alternativa del
comando de lnea loadjava.
PROCEDURE dropjava(options VARCHAR2)
Elimina clases dentro de la base de datos, siendo una alternativa del comando de lnea dropjava.
PROCEDURE grant_permission(grantee VARCHAR2, tipo VARCHAR2, nombre VARCHAR2, accion VARCHAR2)
Permite asignar permisos para usuarios o roles especificados. Donde:
- grantee es el nombre de usuario, esquema o rol, o bien el valor 'PUBLIC' para indicar todos los
usuarios.
- tipo es la clase de permiso a conceder. Por ejemplo, para dar acceso a un archivo el tipo de permiso
debe ser 'FilePermission'. Este argumento requiere un nombre completo cualificado de una clase que
extienda a java.lang.security.Permission. Si la clase no est dentro de SYS, el nombre debe ser prefijado por
Oracle /153
el esquema; por ejemplo, miEsquema:miPaquete.MiPermiso.
- nombre es el nombre del atributo tal como se define en la clase Permission.
- acciones el tipo de accin que queremos especificar segn el tipo de permiso. Por ejemplo, para un
'FilePermission' podemos especificar 'read' o 'write'.
Por ejemplo, para dar permiso de escritura en un fichero se utilizar:
dbms_java.revoke_permission('MIESQUEMA', 'SYS:java.io.FilePermission', 'miarchivo.txt', 'write' );
PROCEDURE restrict_permission(grantee VARCHAR2, tipo VARCHAR2, nombre VARCHAR2, accion VARCHAR2)
Permite especificar limitaciones o excepciones a reglas generales.
PROCEDURE grant_policy_permission(grantee VARCHAR2, esquemaPermiso VARCHAR2, tipo VARCHAR2, nombre
VARCHAR2)
Se usa para conceder y limitar permisos del tipo PolicyTablePermission.
PROCEDURE revoke_permission(esquema VARCHAR2, tipo VARCHAR2, nombre VARCHAR2, accion VARCHAR2)
Permite revocar un permiso concedido.
PROCEDURE disable_permission(key NUMBER)
Permite desactivar un permiso concedido.
PROCEDURE enable_permission(key NUMBER)
Permite activar un permiso.
PROCEDURE delete_permission(key NUMBER)
Permite eliminar un permiso concedido.
procedure set_preference(user VARCHAR2, type VARCHAR2, abspath VARCHAR2, key VARCHAR2, value
VARCHAR2)
Permite insertar o actualizar un registro en la tabla SYS:java$prefs$ como sigue:
CALL dbms_java.set_preference('SCOTT', 'U', '/my/package/method/three', 'windowsize', '22:32');
El parmetro user especifica el nombre del esquema. El parmetro type puede ser 'U' (usuario) o 'S'
(sistema). El parmetro abspath especifica la ruta absoluta de la preferencia. El parmetro key especifica
la clase usada para buscar y value el valor de la clave preferente.

Oracle /154
IV. CARACTERSTICAS DE ORACLE GRID
La g de Oracle Database 11g significa "grid" (rejilla). La rejilla soporta la habilidad de tratar la infraestructura
como un servicio compartido cuya composicin es gestionada fuera de la vista de las aplicaciones clientes. En
este sentido, el servicio de computacin puede ser anlogo a una central elctrica en la cual los sistemas que
proporcionan el servicio no son vistos directamente por los usuarios finales. El origen de la electricidad y el
sistema usado para manejarla no son vistos por los usuarios.
1. Arquitectura de Rejilla
En una arquitectura de rejilla podemos gestionar recursos que soporten dinmicamente las necesidades del
usuario final. La arquitectura de rejilla ayuda a mejorar la disponibilidad de la aplicacin y tambin soporta el
aprovisionamiento de recursos para manejar cargas de trabajo cambiantes. Los recursos de la rejilla incluyen
servidores, discos e instancias. En versiones anteriores Oracle proporcionaba capacidades para alguna de las
funcionalidades de la rejilla, pero Oracle Database 11g introduce herramientas adicionales para facilitar la
administracin de la rejilla en nuestras aplicaciones, proporcionando un conjunto completo de opciones.
Funcionalidades soportadas por la rejilla incluyen:
Real Application Clusters (RAC). Podemos crear varias instancias que accedan a la misma base de
datos, permitiendo distribuir la carga de memoria entre varios servidores. Se pueden aadir nuevas
instancias al clster si es necesario.
Automated Storage Management (ASM). Podemos crear grupos de discos disponibles y asignar
ficheros de datos a los grupos de discos. Oracle entonces gestionar el acceso al grupo de discos y
redistribuir los ficheros como sea necesario.
Tecnologa de replicacin. La rplica rpida de datos entre bases de datos soporta el uso de las bases de
datos como parte de una rejilla de orgenes de datos disponibles. La tecnologa de replicacin incluye
tablespaces transportables, vistas materializadas, replicacin basada en registros, y transacciones
distribuidas.
Tecnologa de seguridad. Podemos apoyar el uso compartido de bases de datos por aplicaciones
diferentes o procesos comerciales. En una base de datos compartida podemos tener que crear bases de
datos virtuales que prevengan el acceso no autorizado de los datos que pertenecen a otras reas de negocio
o aplicaciones.
Planificacin de recursos mediante Oracle Enterprise Manager (OEM). Podemos usar los
procedimientos del paquete DBMS_SCHEDULER para crear programas en Oracle que soporten la ejecucin
de scripts al nivel del sistema operativo adems de tareas que se ejecuten con la base de datos. Podemos
crear programas mediante el procedimiento CREATE_PROGRAM, planificarlos mediante CREATE_SCHEDULE,
y enviar la tarea mediante CREATE_JOB.
Veremos los fundamentos de las funcionalidades de rejilla y como encajan en la arquitectura de computacin
de la rejilla. La implementacin de la rejilla requiere que la infraestructura sea configurada para soportar la
arquitectura distribuida y flexible requerida.
1.1. Hardware y elementos de configuracin del sistema operativo.
Para soportar una arquitectura de rejilla con varias instancias debemos habilitar el soporte de instancias sobre
servidores independientes. Si las instancias son parte de un entorno RAC, el entorno debe tener un rea de
disco compartido que sea accesible mediante redes de alta velocidad. Oracle se ejecuta sobre la mayora de
sistemas operativos, as que las capacidades de rejilla no sern dificultadas por las restricciones de un sistema
operativo particular. RAC no es soportado a travs de sistemas operativos en el entorno de rejilla.
En entornos RAC y de rejilla se usan normalmente servidores "blade". Un "blade" es un sistema
computacional que incluye procesadores y memoria sobre una nica placa en el servidor, mientras que otras
funcionalidades de servidor son compartidas mediante un conjunto de "blades". (Cada servidor "blade" es
una delgada "tarjeta" que contiene nicamente microprocesador, memoria y buses.) Podemos instalar un
nuevo "blade" dentro de un servidor, y el "blade" tendr las ventajas del poder, acceso a red, almacenamiento,
y capacidades de infraestructura ya instaladas. Los servidores "blade" pueden modificarse para soportar
requerimientos de proceso adicionales sin impactar significativamente al rea requerida para soportar el
servidor.
Los servidores mismos deben tener acceso virtual (esto es, una aplicacin de usuario debera ser capaz de
conectarse a una direccin IP que a su vez pueda conectarse a otra de varios servidores en un conjunto). Si

Oracle /155
uno de los servidores no est habilitado, otros servidores en el conjunto sern capaces de atender los
requerimientos sin interrumpir la aplicacin. Los usuarios que estn conectados a la aplicacin tendrn sus
conexiones redirigidas a una instancia de otro servidor. Los servidores deben tener discos externos
compartidos, una direccin IP privada, una direccin IP pblica, e interruptores redundantes.
La arquitectura de almacenamiento debe tambin soportar el concepto de rejilla (varios servidores accediendo
a un servicio de disco compartido). La arquitectura de servidor y el sistema operativo debe soportar una
tecnologa de almacenamiento que soporte acceso concurrente para el servicio de disco compartido. La
arquitectura de rejilla de Oracle soporta Storage Area Networks (SANs), Network Attached Storage
(NAS) e iSCSI (una forma en modo bloque de NAS). Cuando se usan en la rejilla, SANs e iSCSI requieren un
sistema de ficheros de clster o volmenes raw. Los volmenes NAS pueden ser compartidos a travs de
servidores sin la necesidad de un sistema de ficheros de clster.
El almacenamiento compartido puede ser usado por los ficheros crticos de la base de datos (los ficheros de
datos, ficheros de control, ficheros de registro de deshacer en lnea, y ficheros de parmetros del sistema)
adems de los ficheros adicionales para administrar el clster de instancias. Los ficheros deben ser accesibles
por todos los servidores del clster. El software de Oracle puede tambin ser almacenado en el rea
compartida.
Los sistemas de ficheros tradicionales no soportan los requerimientos de acceso de las arquitecturas de rejilla,
as que necesitamos usar un sistema de ficheros que soporte los requerimientos de acceso concurrente. Las
opciones ms comunes son dispositivos raw y sistemas de ficheros de clster. Los dispositivos raw han sido
usados por aos para soportar los entornos RAC de Oracle porque soportan acceso concurrente para varios
procesadores. Sin embargo, su administracin ha sido tradicionalmente ms compleja que la de los sistemas
de ficheros. Tanto los dispositivos raw como los sistemas de ficheros requieren almacenamiento en modo
bloque como SANs e iSCSI.
En general, los sistemas de fichero son ms simples de manejar que los dispositivos raw (ya que pueden ser
fcilmente redimensionados, movidos y renombrados). En general, la velocidad de acceso es comparable. A
menos que tengamos razones especficas para usar dispositivos raw en nuestro entorno, deberamos favorecer
el uso de sistemas de ficheros de clster en nuestra rejilla. Oracle proporciona su propio sistema de ficheros
de clster, el Oracle Cluster File System (OCFS) para soportar acceso compartido a ficheros.
1.1.1. Oracle Cluster File System.
Se ha diseado Oracle Cluster File System (OCFS) para soportar acceso concurrente a un conjunto
compartido de ficheros de base de datos. Se puede descargar desde la pgina oficial de Oracle.
En general, la instalacin de OCFS sigue los siguientes pasos:
1. Descargar el software OCFS para nuestro entorno.
2. Descargar la documentacin de instalacin relacionada. Ntese que el proceso de instalacin y el
software es especfico para cada sistema operativo y versin.
3. Realizar la instalacin.
4. Copiar las utilidades OCFS dentro del directorio compartido (en UNIX, /usr/sbin).
5. Usar la utilidad OCFSTOOL para crear los ficheros de configuracin (como /etc/ocf.conf).
6. Asegurarse de que el comando LOAD_OCFS es automticamente ejecutado en el arranque (en Oracle
Database 11g, esto debera realizarse durante la instalacin).
7. Usar la utilidad FDISK para crear las particiones apropiadas que sern formateadas con el Oracle Cluster
File System. Usar OCFSTOOL para formatear las particiones.
8. Crear puntos de montaje para el sistema de ficheros OCFS ( /u01, /u02, y as) y montar cada sistema de
ficheros.
9. Crear entradas en el fichero /etc/fstab de cada sistema de ficheros OCFS.
Como con el almacenaje conectado por red, es til reanudar uno o varios nodos RAC despus de la
instalacin para verificar que el nmero correcto de volmenes OCFS han sido montados.
1.1.2. Acceso a otros servidores.
En un entorno RAC debemos ser capaces de ejecutar comandos sobre todos los otros servidores del clster
sin proporcionar una contrasea. Por ejemplo, en UNIX debemos ser capaces de usar los comandos rsh y rcp
entre los servidores. Deberamos trabajar con nuestros administradores de red y sistema para determinar la
solucin tcnica apropiada para nuestro entorno. Nuestra eleccin para estos requerimientos puede estar
limitada por las polticas y prcticas de seguridad de nuestro entorno.
Por ejemplo, podemos necesitar usar los ficheros /home/oracle/rhosts para permitir hosts equivalentes para el
usuario de Oracle. Podemos especificar los hosts con los cuales las conexiones estn permitidas mediante el
Oracle /156
mtodo de acceso rhosts.
1.1.3. Oracle Cluster Manager.
El Oracle Cluster Manager (OCM) se instala mediante el Instalador Universal de Oracle. OCM requiere que
los nombres de host pblico y privado de cada servidor en el clster sean introducidos en dos pantallas
separadas. Debemos asegurarnos de que estos nombres correspondan exactamente para evitar problemas en
los pasos de instalacin posteriores.
OCM facilita un agente que monitoriza los servidores para determinar si estn todava disponibles.
Dependiendo de la versin de Oracle RAC que usemos, este agente puede denominarse "watchdogd" o
"hangcheck-timer".
Debemos crear directorios de registro (como $ORACLE_HOME/oracm/log) para que Oracle los use antes de
comenzar el OCM.
Ahora se puede iniciar OCM e instalar el software Oracle RAC.
1.2. Aadiendo servidores a la rejilla.
Cuando un servidor est disponible ("provisional") para una base de datos RAC, el administrador de sistemas
deber realizar varios pasos:
1. Traer el servidor dentro de la misma red que los otros nodos del clster.
2. Habilitar el nuevo servidor para acceder al almacenamiento compartido.
3. Habilitar el nuevo servidor para acceder a otros servidores del clster.
4. Instalar el software para el clster en el servidor. El nuevo servidor debera ser reconocido como parte
del mismo clster que los otros servidores, y debera tener el acceso apropiado al almacenamiento
compartido. Hay que asegurarse de que el nuevo servidor usa el mismo software de clster que usen los
otros servidores del clster.
5. Instalar el software de Oracle en el servidor. Usar el Instalador Universal de Oracle para instalar el
software de Oracle y aadir el nuevo servidor al la base de datos RAC mediante el Asistente de Creacin
de Bases de datos (DBCA). Durante la instalacin (la cual requiere la edicin empresarial), seleccionar la
instalacin slo de software, con lo cual no se crea una base de datos. Ejecutar el fichero de configuracin
(sobre UNIX, es root.sh) para completar la instalacin.
1.2.1. Aadir instancias a la rejilla.
Para crear una instancia sobre el nuevo servidor, hay que asegurarse de que el Global Services Daemon
(GSD) est ejecutndose sobre todos los servidores. Para arrancar GSD sobre UNIX hay que usar el
siguiente comando:
gsdctl start
Una vez que se est ejecutando GSD, hay que arrancar el OUI y elegir la opcin "Cluster database".
Debemos ir a la pgina de administracin de instancia, en la cual podemos decidir aadir instancias al clster
existente. Se nos solicitar informacin similar a la mostrada durante la instalacin de la base de datos
(detalles del grupo de registros de rehacer, informacin de tablespace y nombre de instancia). Cuando
aceptemos las opciones, el DBCA comenzar y crear la instancia requerida.
Para eliminar una instancia de la rejilla, debemos ir en el OUI a la pgina de administracin de instancia y
seleccionar borrar instancia.
1.3. Compartir datos entre la rejilla.
En una rejilla podemos disponer de varias bases de datos RAC o de varias bases de datos de instancia nica,
los cuales podemos administrar a travs de las tecnologas de la rejilla.
Para soportar varias configuraciones de base de datos, Oracle ofrece un conjunto de tecnologas. Las
tecnologas de replicacin incluyen:
Enlaces de base de datos. Podemos establecer enlaces entre cuentas de bases de datos independientes,
para usarlos solo en replicaciones de solo lectura o para actualizar copias de tablas.
Procedimientos y triggers. Para mantener datos replicados sincrnicamente, podemos crear un trigger
que cree una transaccin en una base de datos remota cuando una transaccin sea confirmada en una base
de datos local. Si la transaccin en la base de datos remota falla, la transaccin local falla y las dos bases de
datos permanecen sincronizadas.
Vistas materializadas. Podemos crear vistas materializadas basadas sobre objetos remotos. Las vistas
materializadas pueden ser refrescadas con datos desde el sistema fuente y confirmadas al momento o sobre
una planificacin predeterminada. Adems de usar registros de vistas materializadas, podemos usar
refrescos rpidos para enviar cambios incrementales desde el sistema fuente a la vista materializada.

Oracle /157
Tablespaces transportables. Podemos mover grandes volmenes de datos desde una base de datos a otra
mediante el transporte de tablespaces. Por ejemplo, podemos "despegar" un tablespace de un entorno de
pruebas y entones "pegarlo" en varias bases de datos diferentes. Desde Oracle Database 10g, las bases de
datos fuente y destino pueden estar en diferentes plataformas.
Tablas externas. Podemos tratar ficheros externos de la base de datos como si fuesen tablas de la misma,
consultndolas como si las lneas de los ficheros fuesen filas de una tabla. Estos ficheros pueden estar
localizados en discos compartidos.
Oracle Streams. Esta tecnologa usa las entradas de registros de rehacer para generar el SQL necesario
para replicar transacciones entre bases de datos.
Data Pump Export e Import. Podemos usar estas tecnologas para crear tareas en el lado servidor que
extraigan y carguen datos desde nuestras bases de datos.
Podemos usar todas estas tecnologas para hacer que los datos estn disponibles a travs de nuestra rejilla.
1.4. Administracin de la rejilla.
En Oracle Database 11g, Oracle Enterprise Manager (OEM) introduce o modifica varios componentes
diseados para soportar la administracin de la rejilla. Estos componentes incluyen los siguientes:
Grid Control Console. Una interfaz OEM que permite de forma fcil administrar todos los hosts,
bases de datos, oyentes, y aplicaciones servidoras de nuestro entorno computacional.
Oracle Management Agent. Un proceso desplegado sobre cada host monitoreado. Es responsable de
supervisar todos los objetivos del host, para comunicar esta informacin al administrador de servicio
intermedio, y para manejar y mantener el host y sus objetivos. El agente requiere al menos 360 MB de
espacio inicial de disco y 20 MB de memoria.
Oracle Management Service. Una aplicacin J2EE que muestra la Grid Control Console, trabaja con
todos los agentes de administracin para procesar informacin de tareas y supervisin, y usar el
Management Repository como almacn de datos. El Oracle Management Service se instala y es
desplegado sobre el servidor de aplicacin de Oracle. El servicio requiere al menos 240 MB de espacio de
disco y 1 GB de memoria. El servidor de aplicacin requiere 500 MB de disco y al menos 512 de memoria.
Oracle Management Repository. Dos tablespaces en una base de datos de Oracle que almacena
informacin acerca de los objetivos y aplicaciones manejadas con OEM. El Oracle Management Agent
recolecta los datos y usa el Oracle Management Service para cargarlos dentro del Oracle Management
Repository. El Oracle Management Repository puede ser accedido por varios administradores en la
rejilla. El tamao recomendado para el repositorio es de 1 GB de espacio en disco y de 3 GB de memoria.
Cuando se instala el Oracle Enterprise Manager 11g Grid Control podemos usar una nueva base de datos o
una base de datos existente para el repositorio. Si usamos una base de datos existente, la base de datos debe
ser local o remota sobre el servidor sobre el cual realizamos la instalacin. El repositorio debe ser instalado en
una base de datos para la cual est habilitado el control de acceso de grano fino (comprobar la vista
V$OPTION para verificar esta opcin).

Nota. El asistente de configuracin del Enterprise Manager Repository fallar si el usuario


SYSMAN ya existe en la base de datos que se especifica para el repositorio, o si el repositorio ya
existe en la base de datos.
Para instalar el Oracle Management Agent hay que ejecutar el OUI sobre cada servidor del entorno.
Durante la instalacin hay que elegir "Additional Management Agent" como tipo de instalacin. La opcin de
instalacin silenciosa tambin est disponible. Oracle proporciona ficheros de respuesta estndar para ser
usados por la instalacin silenciosa.
Despus de la instalacin se ejecuta el fichero root.sh como superusuario para completar el proceso de
instalacin.
1.4.1. Habilitar bsqueda de parches y descargas.
Podemos usar OEM para acceder a Oracle Metalink para buscar parches y descargas para nuestro entorno.
Si no especificamos nuestra informacin de conexin durante la instalacin, podemos ir a la pgina "Grid
Control" de OEM y acceder a la pgina "Setup | Patching Setup". En esta pgina podemos introducir
nuestras credenciales de Metalink y el sitio de bsqueda de parches Metalink:
http://oracle.com/support/metalink/index.html
Podemos usar esta configuracin para buscar y descargar parches desde la interfaz de OEM.

Oracle /158
1.4.2. Asignar credenciales para el sistema de tareas.
En sistemas basados en Windows (NT 4, Windows 2000, Windows 2003, Windows XP, Windows Vista y
Windows 7), podemos asignar las credenciales apropiadas para que el sistema de tareas trabaje
apropiadamente con OEM. Cuando enviamos una tarea, el usuario debe tener el permiso "Log on as a batch
job" habilitado. Por defecto, el Management Agent se instala como un usuario LocalSystem.
Para habilitar esta opcin en Windows 2000 y Windows XP, hay que iniciar la herramienta "Polticas de
seguridad local" en el Panel de Control. Se elige "Polticas locales | Derechos de usuario". Se hace doble clic
sobre la entrada "Log on as a batch job" y se aade el nombre del usuario. Hay que reiniciar el servidor para
que los cambios tengan efecto.
En Windows NT 4, se elige la herramienta "User Manager" dentro de la opcin "Programs | Administrative
Tools" del men de inicio. Se selecciona "Policies | User Rights" y se hace clic sobre "Show Advanced User
Rights". Se selecciona "Log on as a batch job" en el men desplegable y se aade el nombre del usuario.
1.4.3. Configurar bases de datos para supervisin.
Para habilitar la supervisin de una base de datos debemos permitir que la cuenta DBSNMP sea accesible.
Debido a que esta cuenta puede estar bloqueada en nuestro entorno, debemos verificar que es accesible
(podemos necesitar usar el comando ALTER USER DBSNMP ACCOUNT UNLOCK). Podemos entonces ir a la
pgina "Configurar base de datos | Propiedades" de la consola de control de rejilla de OEM y configurar la
base de datos para supervisin. En esta pgina se introduce la contrasea para el usuario DBSNMP en la base
de datos destino.
Para supervisin ASM, navegar a "Targets | All Targets" desde la consola de control de rejilla de OEM.
Cuando configuramos el destino debemos introducir la contrasea SYS para usar en supervisin ASM.
1.5. Lanzar OEM.
OEM es una interfaz grfica para administrar los componentes de la rejilla. Es una interfaz bastante intuitiva,
pero hay algunas cosas de las que hay que ser conscientes dentro de OEM:
Si tenemos configurado un Agente de Administracin en el servidor, los destinos soportados sobre el
mismo servidor sern detectados y sern supervisados mediante OEM.
Podemos configurar notificacin por e-mail automtica desde OEM por defecto. Podemos configurar
mtodos de notificaciones adicionales si es necesario.
Podemos agrupar destinos, crear roles, y crear administradores con OEM.
OEM se apoya sobre el Oracle Management Repository, Oracle Management Agent, y Oracle
Management Service para funcionar apropiadamente.
Ya que el repositorio es una base de datos, podemos pararla e iniciarla mediante los comandos SHUTDOWN y
STARTUP en SQL*Plus. El Oracle Management Service, sin embargo, necesita el uso de la utilidad EMCTL
instalada con Oracle. Para iniciar el Oracle Management se usa el siguiente comando en UNIX:
emctl start oms
Y para parar el servicio:
emctl stop oms
Podemos comprobar su estado mediante:
emctl status oms
Para comenzar todos los componentes del servidor de aplicaciones, incluyendo el Management Service:
opmnctl startall
Para parar todos los componentes:
opmnctl stopall.
En Windows los agentes de administracin de Oracle son manejados mediante "Servicios" en el Panel de
Control. Para comenzar los agentes sobre plataformas UNIX se usa el comando:
emctl start agent
Podemos parar un agente mediante:
emctl stop agent
Y podemos comprobar su estado mediante:
emctl status agent
Una vez que todos los componentes han sido iniciados, podemos acceder a la OEM Grid Control Console
mediante la apropiada URL, la cual est normalmente en el siguiente formato:
http://nombre_del_host_mgmtserver.dominio:puerto/em
1.5.1. Inicializacin de parmetros para el repositorio.
La siguiente tabla muestra los parmetros de inicializacin de base de datos requeridos para la base de datos

Oracle /159
en la cual el repositorio es almacenado.
Nota. No hay que asignar valor para RESOURCE_MANAGER_PLAN.
Parmetro Valor mnimo
job_queue_processes 10
db_block_size 8192
remote_login_passwordfile EXCLUSIVE
timed_statistics TRUE
open_cursors 300
shared_pool_size 67108864
dispatchers NULL o no presente en el fichero
aq_tm_processes 1 o mayor
compatible 9.0.1.3 o ms grande

La siguiente tabla lista parmetros adicionales recomendados para el Oracle Management Repository.
Parmetro Valor
db_cache_size 134217728
session_cached_cursors 200
large_pool_size 0
processes 150
fast_start_mttr_target 300
hash_area_size 1048576
sort_area_size 1048576
pga_aggregate_target 33554432
undo_management AUTO
undo_retention 10800
undo_tablespace UNDOTBS

2. Oracle Real Application Clusters


En un entorno de Oracle Real Application Clusters (RAC) varias instancias pueden acceder a una nica base
de datos. Estas instancias son normalmente creadas sobre servidores independientes que estn conectados
mediante interconexiones de alta velocidad con acceso a un rea de disco compartido. Los ficheros de base de
datos residen sobre un conjunto de discos compartidos, y cada instancia tiene sus propios archivos de control
y archivos de registros de deshacer en lnea que son tambin almacenados sobre los discos compartidos.
Un usuario puede conectarse directamente a la base de datos mediante una de las instancias asociadas con la
base de datos; si una de las instancias se cae, la conexin puede ser reconectada dinmicamente a la base de
datos mediante otra instancia del clster. RAC, por lo tanto, proporciona una solucin de disponibilidad alta
(considerando fallos en el servidor y la instancia) y una solucin escalable de alto rendimiento (al aumentar la
memoria y los procesadores disponibles en los procesos conectados).
Veremos cmo instalar y gestionar un RAC. Muchos detalles son especficos del sistema operativo, pero el
proceso de configuracin es el mismo entre plataformas.
2.1. Pasos de preinstalacin.
Antes de empezar la instalacin de Oracle RAC necesitamos verificar que nuestro entorno y clster estn
apropiadamente configurados para soportarlo. Los servidores que hospedarn las instancias se denominan los
nodos del clster. Cada nodo debera cumplir con lo siguiente:
Cada uno de los nodos debera tener discos externos compartidos.
Cada nodo debera tener interruptores redundantes para soportar requerimientos de sobrefallos.
Cada nodo debera tener una direccin IP privada para conexiones privadas y una IP pblica para
conexiones de clientes y conexiones de sobrefallos para otros nodos.
Oracle Database 11g proporciona una herramienta llamada VIPCA (Asistente de Configuracin de IP
Virtual) para soportar la configuracin de nuestras direcciones IP.
Cada nodo debe soportar el protocolo TCP/IP y un protocolo de interconexin de software compatible.
Nota. Debemos elegir una interconexin que sea soportada por Oracle.

Oracle /160
Oracle proporciona clusterware, simplificando el proceso de instalacin y configuracin. Los pasos de
instalacin son descritos en el siguiente captulo. Para el rea de disco compartido, Oracle recomienda el uso
de su funcionalidad de Administracin de Almacenamiento Automtico.
2.2. Instalacin de RAC.
La instalacin de RAC en Oracle Database 11g es un proceso de dos pasos. En el primer paso se usa la
Instalador Universal de Oracle (OUI) para instalar CRS (Cluster Ready Services). CRS, disponible como parte
de Oracle Database 11g, proporciona un conjunto integrado de soluciones para administrar clsteres.
Podemos usar CRS para administrar membresa de clster, servicios de grupo, administracin de recursos de
grupo y configuracin de alta disponibilidad. Podemos usar CRS para definir servicios que soporten
distribucin de cargas de trabajo a travs de servidores. El Depsito de Carga de Trabajo Automtico (AWR)
recoge la estadstica de los servicios.
Nota. RAC est disponible tanto con Standard Edition como con Enterprise Edition de Oracle
Database 11g.
Despus de completar el primer paso (instalar el CRS), podemos comenzar con el segundo paso de
instalacin: instalar el software de Oracle Database 11g con RAC en un directorio inicial de Oracle distinto
del usado en el primer paso. Deberamos usar tambin el instalador para crear y configurar servicios para
nuestro entorno RAC. Despus de que se complete la instalacin, OUI lanzar el Asistente de Configuracin
de Base de datos para completar la configuracin del entorno y crear la base de datos RAC.
Nota. Si tenemos instalada una versin previa de Oracle el Asistente de Actualizacin de Base de
datos actualizar nuestra base de datos a la versin 11g de RAC.
2.2.1. Almacenamiento.
Desde Oracle Database 10g, podemos usar el Administrador de Almacenamiento Automtico (ASM) para
crear grupos de discos y simplificar su mantenimiento. Los administradores de base de datos pueden aadir
nuevos discos a grupos de discos; Oracle gestionar el contenido y la distribucin de los ficheros entre los
discos involucrados.
Podemos usar ASM para proporcionar redundancia desde dentro de Oracle si no hay disponible redundancia
por hardware. Cuando definimos el grupo de discos podemos especificar un grupo de fallos; Oracle usar el
grupo de fallos como una versin redundante del grupo primario de discos en el grupo de discos. Los
programas de instalacin de Oracle se refieren a la redundancia basada en software como redundancia
"normal". Podemos especificar varios grupos de fallo para proteccin de redundancia adicional (bajo el costo
de espacio adicional). Si hay hardware de replicacin podemos usar redundancia externa basada en el sistema
de ficheros.
Muchos entornos RAC usan una combinacin de dispositivos fsicos y volmenes lgicos gestionados por
software.
Podemos usar grupos de discos ASM para intentar reducir la complejidad de gestin de la base de datos RAC
(Oracle gestiona los ficheros y el sistema de ficheros). Podemos administrar los ficheros y grupos de discos
manualmente o mediante la opcin de control de rejilla del Administrador Empresarial de Oracle.
2.2.2. Parmetros de inicializacin.
Como parte de configuracin de las instancias debemos asignar valores a los parmetros de inicializacin de
base de datos mantenidos en el fichero de parmetros del servidor. Las instalaciones RAC deberan usar el
fichero de parmetros del servidor para controlar el conjunto de parmetros compartidos por las instancias.
Los parmetros de inicializacin mostrados en la siguiente tabla deben tener los mismos valores para todas las
instancias del clster RAC.
Parmetro Descripcin
ACTIVE_INSTANCE_COUNT Permite designar una instancia en un clster de dos instancias
como la instancia primaria y la otra instancia como la secundaria.
Este parmetro no tiene funcionalidad en un clster con ms de
dos instancias. Cuando se asigna este parmetro a 1, la primera
instancia comenzar siendo la primaria y aceptar las conexiones
de clientes. La segunda instancia comenzar siendo la secundaria y
puede aceptar conexiones de clientes slo si la primera instancia
falla.

Oracle /161
CLUSTER_DATABASE Valor booleano que especifica si RAC est habilitado. Hay que
asignarlo a TRUE.
CONTROL_FILES Especifica uno o ms nombres de ficheros de control, separados
por comas.
DB_BLOCK_SIZE Especifica (en bytes) el tamao de los bloques de base de datos de
Oracle.
DB_DOMAIN Especifica la localizacin lgica de la base de datos dentro de la
estructura de red. El valor consiste de los componentes de
extensin de un nombre global de base de datos, formado por
identificadores vlidos separados por puntos.
DB_FILES Especifica el nmero mximo de ficheros de base de datos que
pueden ser abiertos por esta base de datos. El valor mximo vlido
es el nmero mximo de archivos, sujeto a las restricciones del
sistema operativo, que pueden ser especificados por la base de
datos, incluyendo ficheros que pueden ser aadidos por comandos.
Si se incrementa este valor debemos parar y reiniciar todas las
instancias que acceden a la base de datos antes de que el nuevo
valor tenga efecto.
DB_NAME Especifica el identificador de la base de datos de hasta 8 caracteres.
Este parmetro debe ser especificado y debe corresponder al
nombre especificado en el comando CREATE DATABASE.
DB_RECOVERY_FILE_DEST Especifica la localizacin por defecto del rea de recuperacin
instantnea. Esta rea contiene copias multiplexadas de los ficheros
de control actuales y registros de deshacer en lnea, as como los
registros de instantneas y copias de seguridad RMAN. Debe
especificarse este parmetro junto con el parmetro de
inicializacin DB_RECOVERY_FILE_DEST_SIZE.
DB_RECOVERY_FILE_DEST_SIZE Especifica (en bytes) el lmite del espacio total usado por los
ficheros de recuperacin de base de datos creados en el rea de
recuperacin instantnea.
DB_UNIQUE_NAME Especifica un nombre nico global para la base de datos. Cada
DB_UNIQUE_NAME de base de datos debe ser nico dentro de la
empresa.
MAX_COMMIT_PROPAGATION_DELAY Este parmetro no debera ser cambia excepto un limitado
conjunto de circunstancias especficas al clster de base de datos.
Este parmetro especifica la cantidad mxima de tiempo permitido
antes de que nmero de cambio de sistema (SCN) sostenido en el
SGA de una instancia sea refrescado por el proceso de escritura de
registro. Determina si el SCN local debera ser refrescado desde el
valor del bloqueo cuando obtenemos la instantnea SCN de una
consulta. Las unidades estn en centsimas de segundo. Asignando
este parmetro a cero provocamos que el SCN sea refrescado
inmediatamente despus de un COMMIT. El valor por defecto
(700) es un lmite superior que permite al mecanismo de alto
rendimiento permanecer.
SPFILE Nombres del fichero de parmetro de servidor en uso. Este
parmetro puede ser definido en un fichero de parmetros del lado
cliente para indicar el nombre del fichero de parmetros de
servidor usado. Cuando se usa el fichero por defecto del servidor,
el valor es asignado internamente por el servidor.
TRACE_ENABLED Valor booleano que controla el trazado de Oracle. Cuando se
asigna a TRUE, Oracle registra informacin en ficheros de registro
cuando ocurren errores. Oracle registra esta informacin para
todas las instancias.
UNDO_MANAGEMENT Especifica qu modo de gestin de espacio de deshacer debera
usar el sistema. Cuando se asigna a AUTO, la instancia comienza en
modo automtico.

Oracle /162
Nota. La asignacin para DML_LOCKS debe ser idntica para todas las instancias slo si se asignar a
cero.
La siguiente tabla lista los parmetros de inicializacin que deben tener valores nicos para cada instancia en
el clster RAC, junto con sus descripciones.
Parmetro Descripcin
INSTANCE_NUMBER Especifica un nico nmero que mapea las instancias en una lista de grupos libre
para cada objeto de base de datos creados con el parmetro de almacenamiento
FREELIST GROUPS.
ROLLBACK_SEGMENTS Asigna uno o ms segmentos de rollback por nombre a esta instancia. Cuando
UNDO_MANAGEMENT es asignado a AUTO, ROLLBACK_SEGMENTS se ignora.
THREAD Si se especifica, este parmetro deber tener valores nicos sobre todas las instancias.
El parmetro especifica el nmero de hilos de deshacer que sern usados por una
instancia.
UNDO_TABLESPACE Especifica el tablespace de deshacer que ser usado cuando una instancia arranca. Si
este parmetro se especifica cuando la instancia est en un modo manual de
administracin de deshacer, entonces ocurrir un error y el arranque fallar.

Nota. Dentro de una instancia, se asigna INSTANCE_NUMBER y THREAD al mismo valor.


Adems de los parmetros mostrados previamente, debemos especificar valores para los siguientes
parmetros de inicializacin:
Parmetro Descripcin
CLUSTER_DATABASE_INSTANCES Asigna el nmero de instancias del entorno RAC.
DISPATCHERS Se asigna este parmetro para habilitar una configuracin de servidor
compartida (en el cual varios procesos de usuario se unen a un
distribuidor).

2.3. Inicia y parar instancias RAC.


Podemos usar Control de Rejilla para administrar todas las instancias asociadas con una base de datos RAC.
Podemos parar, iniciar y supervisar bases de datos, instancias y sus oyentes mediante Control de Rejilla. Al
igual que con bases de datos que no son RAC, podemos usar SQL*Plus para introducir comandos de
apagados y arranque. Para bases de datos RAC podemos tambin usar la utilidad SRVCTL.
Independientemente de la herramienta usada para apagar o arrancar la instancia, las siguientes reglas se
aplican a clsteres RAC:
El apagado de una instancia no afecta a las operaciones de otras instancias ejecutndose.
Apagar una base de datos montada en modo compartido requiere apagar cada una de las instancias del
clster RAC.
Despus de un apagado normal (SHUTDOWN NORMAL) o inmediato (SHUTDOWN IMMEDIATE), no es
necesario recuperar ninguna instancia. Si se usa SHUTDOWN ABORT sobre una instancia RAC, una instancia
todava ejecutndose realiza la recuperacin de instancia para la instancia parada. Si la instancia abortada
fue la ltima que se ejecutaba, la siguiente instancia que se inicie realizar la recuperacin.
Si se usa SHUTDOWN TRANSACTIONAL con la opcin LOCAL, todas las transacciones en la instancia sern
confirmadas o rechazadas antes del apagado. Las transacciones de otras instancias no se vern afectadas. Si
no se especifica la clusula LOCAL, el apagado transaccional esperar por todas las transacciones sobre
todas las instancias que se inicien antes de que el comando SHUTDOWN se complete.
Podemos usar comandos de SQL*Plus para apagar y arrancar bases de datos RAC una a una hasta que todo
el entorno haya comenzado.
Podemos arrancar una instancia sobre nuestro nodo local mediante el comando STARTUP MOUNT.
Podemos usar la utilidad SRVCTL para administrar varias instancias con un nico comando. La sintaxis para
arrancar instancias es:
SRVCTL START INSTANCE -d <db_name> -i <inst_name_list> [-o <start_options>] [-c <connect_str> | -q]
Las palabras SRVCTL START especifican el servicio que ser iniciado ( INSTANCE, DATABASE, SERVICE,
NODEAPPS o ASM). Se pueden pasar varias instancias como parte del valor del parmetro inst_name_list
(separndolas con comas). Los valores para start_options son OPEN, MOUNT y NOMOUNT. El parmetro
connect_str permite pasar una cadena de conexin cuando conectamos la base de datos. El parmetro q, si se

Oracle /163
especifica, le dice a SRVCTL que solicite al usuario informacin de conexin cuando SRVCTL se ejecute; por
defecto SRVCTL se conectar a la base de datos local como SYSDBA.
El siguiente comando iniciar y abrir una base de datos local llamada MYDB:
SRVCTL START database d MYDB o OPEN
El siguiente comando iniciar dos instancias para la base de datos MYDB:
SRVCTL START instance d MYDB i MYDB1,MYDB2
Para instancias ASM hay que especificar el nombre de nodo ( -n), el nombre de instancia (-i), y la opcin de
inicio (-o), como en el siguiente ejemplo:
SRVCTL START ASM -n MYNODE1 -i ASM1 o OPEN

Nota. Para ver las instancias que son parte de nuestro clster, podemos usar OEM o SQL*Plus.
Dentro de SQL*Plus, se consulta la vista V$ACTIVE_INSTANCES. Esta vista mostrar una fila por
cada instancia, mostrando el nmero de instancia, el nombre de host, y el nombre de la instancia.
Podemos usar el siguiente comando
SRVCTL STOP {DATABASE | INSTANCE | SERVICE | NODEAPPS | ASM }
Para parar bases de datos, instancias y otros servicios.
Comando SRVCTL Descripcin
srvctl add {database | instance | service | Aade una configuracin a nuestra configuracin del clster de
nodeapps | asm} base de datos. SRVCTL ADD SERVICE aade servicios a una base
de datos y los asigna a instancias. Podemos usar el comando
SRVCTL ADD SERVICE para configurar la poltica "Transparent
Application Failover" para un servicio.
srvctl config {database | service | Muestra la informacin de configuracin almacenada en el
nodeapps|asm} Registro de Clster de Oracle.
srvctl disable {database | instance | Desactiva el objeto indicado y evita que sea iniciado
service|asm} automticamente.
srvctl enable {database | instance | Activa el objeto indicado para ser iniciado automticamente.
service|asm}
srvctl getenv {database | instance | Muestra el estado de entorno.
service | nodeapps}
srvctl modify {database | instance | Modifica la configuracin del objeto indicado sin quitar y aadir
service | nodeapps} los recursos CRS.
srvctl relocate service Traslada los nombres de servicio desde una instancia a otra.
srvctl remove {database | instance | Elimina el objeto indicado del entorno del clster.
service | nodeapps | asm}
srvctl setenv {database | instance | Asigna valores de entorno en el fichero de configuracin.
service | nodeapps}
srvctl start {database | instance | service Inicia el CRS habilitado, aplicaciones no ejecutndose en la base
| nodeapps | asm} de datos, todas o las instancia indicadas, todos o los servicios
indicados, o aplicaciones del nivel de nodo.
srvctl status {database | instance | Muestra el estado actual del objeto indicado.
service | nodeapps | asm}
srvctl stop {database | instance | service | Para las aplicaciones CRS para la base de datos, todas o las
nodeapps | asm} instancias indicadas, todos o los servicios indicados, o
aplicaciones del nivel de nodo.
srvctl unsetenv {database | instance | Desasigna los valores de entorno en el fichero de configuracin.
service | nodeapps}

2.4. Transparencia de sobrefallos de aplicacin.


RAC proporciona soporte transparente para sobrefallos de aplicacin (TAF) en el evento de fallo de una
instancia. Para protegerse contra el fallo de hardware, el fichero de base de datos almacenado debe ser
tolerante a fallos (por lo general mediante el uso de cadenas RAIS, replicacin, o replicacin por software
forzando ASM). Cuando un usuario se conecta a la base de datos a travs de una instancia, cualquier
transaccin ejecutada por el usuario se registra en el hilo de registro de deshacer para esta instancia.
Si una instancia falla (o se apaga mediante un SHUTDOWN ABORT), una de las instancias supervivientes
realizar las recuperaciones necesarias. Con TAF, las conexiones de usuario sern restablecidas mediante otra
instancia del mismo clster, conectado a la misma base de datos.
Oracle /164
Cuando instalamos y configuramos un entorno RAC, Oracle configura los servicios de red por nosotros. Por
ejemplo, si creamos un servicio llamado db.us.acme.com, la entrada de nombre de servicio en el fichero
tnsnames.ora puede ser reensamblado como sigue:
db.us.acme.com=
(description= (load_balance=on) (failover=on)
(address_list=
(address=(protocol=tcp)(host=db1-server)(port=1521))
(address=(protocol=tcp)(host=db2-server)(port=1521)))
(connect_data= (service_name=db.us.acme.com)))
El usuario puede conectarse a la instancia mediante el nombre de servicio db.us.acme.com (por ejemplo,
mediante una sesin remota de SQL*Plus) y ejecutar consultas. Mientras el usuario est conectado, podemos
apagar el host db1-server. Si el usuario (todava en la misma sesin) intenta ejecutar otra consulta, la sesin
ser transparentemente restablecida mediante el host db2-server y la consulta ser ejecutada.
La entrada del fichero listener.ora para la base de datos contendr entradas similares a las siguientes:
listeners_db.us.acme.com=
(address=(protocol=tcp)(host=db1-server)(port=1521)) (address=(protocol=tcp)(host=db2-server)(port=1521))
Si el
usuario ha cambiado variables del entorno dentro de la sesin (mediante ALTER SESSION), o ha asignado
variables especficas de la sesin, estos valores pueden necesitar ser restablecidos en la nueva sesin.
2.4.1. Servicios.
Podemos crear y administrar servicios dentro de nuestro clster RAC. Podemos asignar servicios para
ejecutar una o ms instancias; los servicios integran recursos del clster de base de datos para simplificar la
gestin de clster.
Podemos usar SVRCTL para crear y aadir servicios. Podemos identificar otras instancias que estn disponibles
para soportar cambios de niveles de servicios o para interrupciones planificadas.
2.5. Aadir nodos e instancias a un clster.
Podemos aadir nodos a un clster existente y podemos aadir instancias a un entorno RAC existente. Los
nodos deben cumplir con los criterios listados previamente (deben ser configurados con el protocolo de red
apropiado y deben soportar transmisiones de datos de alta velocidad con los otros nodos del clster).
Generalmente lo ms simple es realizar una copia de un nodo existente en el clster.
Los pasos de instalacin especficos para el nuevo nodo varan segn el sistema operativo. En general, un
administrador de clster en UNIX aadir el nuevo nodo a la configuracin de clusterware (segn las
direcciones de su fabricador). Podemos entonces iniciar el Instalador Universal de Oracle (OUI) en el modo
aadir nodo (en UNIX, mediante <CRS_HOME>/OUI/bin/addNode.sh y en Windows mediante
<CRS_HOME>\oui\bin\addNode.bat).
OUI entonces presentar una serie de pantallas de recogida de datos para aadir el nuevo nodo al clster as
como para verificar la configuracin.
OUI entonces iniciar el proceso de instalacin, instanciando scripts si es necesario, copiando los ficheros
CRS al nuevo nodo si es necesario, y solicitando que ejecutemos varios scripts al nivel del sistema operativo.
OUI entonces guardar el inventario del clster. Podemos entonces ejecutar la utilidad CRSSETUP para aadir
informacin CRS al nuevo nodo. Entonces podemos ejecutar una utilidad final, RACGONS, para configurar el
puerto de los Servicios de Notificacin de Oracle para el nuevo servidor.
Una vez que el nodo ha sido aadido al clster, podemos aadir una instancia. Se inicia el Asistente de
Configuracin de Base de datos (DBCA) y se elige "Real Application Clusters database". Podemos entonces
seleccionar "Aadir instancia" y el nombre de la instancia de base de datos que ser accedida. Tras introducir
los parmetros de la instancia y aceptar la informacin resumida se inicia la creacin de la instancia. Oracle
crear la instancia y sus servicios de red.
Para eliminar una instancia existente de un clster RAC, se inicia el DBCA sobre un nodo distinto del noto
que hospeda la instancia que ser eliminada. El DBCA mostrar una lista de instancias actuales en la
configuracin; se selecciona una de la lista. DBCA mostrar una lista de los servicios asignados a esta
instancia para poderlos recolocar en otras instancias del clster. La instancia seleccionada ser des registrada
del clster RAC.
2.6. Administracin de registro y servicios del clster.
El Registro de Clster de Oracle (OCR) contiene detalles de configuracin para la base de datos, servicios y
otros componentes del clster. Como se ha visto podemos usar comando de configuracin SRVCTL para

Oracle /165
mostear los detalles de configuracin almacenados en el OCR. Deberamos hacer copias del registro
regularmente para soportar cualquier recuperacin que sea necesaria ms tarde.
Una de las instancias registradas en el clster automticamente recuperar el OCR cada cuatro horas,
reteniendo tres copias de respaldo. Copias de respaldo adicionales ser realizan una vez por da y una vez por
semana. No podemos modificar la frecuencia de las copias o el nmero de copias retenidas. Podemos realizar
copias de respaldo adicionales mediante la herramienta OCRCONFIG. Las opciones de OCRCONFIG se
muestran en la siguiente tabla.
Opcin Propsito
-export Para exportar el contenido del OCR dentro del fichero destino.
-import Para importar el contenido OCR desde un fichero exportado
previamente.
-restore Para restaurar el OCR desde un fichero de respaldo OCR creado
automticamente.
-backuploc Para cambiar la localizacin del fichero de respaldo OCR. Para
esta entrada hay que usar una ruta completa que sea accesible por
todos los nodos.
-showbackup Para mostrar la localizacin, tiempo y nombre del nodo de origen
para los tres ltimos ficheros de respaldo creados
automticamente.
-upgrade Para actualizar el OCR a su ltima versin.
-downgrade Para des actualizar el OCR a su versin ms temprana.
-help Para mostrar las ayudas de este comando.

3. Seguridad en Oracle
A la hora de establecer una conexin con un servidor Oracle, es necesario que utilicemos un modo de acceso,
el cual describa de qu permisos dispondremos durante nuestra conexin. Estos permisos se definen sobre un
nombre de usuario. Un usuario no es ms que un conjunto de permisos que se aplican a una conexin de
base de datos. As mismo, el usuario tambin tiene otras funciones:
- Ser el propietario de ciertos objetos.
- Definir el tablespace por defecto para sus objetos.
- Realizar copias de seguridad.
- Aplicar cuotas de almacenamiento.
Un privilegio no es ms que un permiso dado a un usuario para que realice cierta operacin. Estas
operaciones pueden ser de dos tipos:
- Operacin de sistema: necesita el permiso de sistema correspondiente.
- Operacin sobre objeto: necesita el permiso sobre el objeto en cuestin.
Y por ltimo, un rol de base de datos no es ms que una agrupacin de permisos de sistema y de objeto.
3.1. Creacin de usuarios.
El sistema de Oracle viene con muchos usuarios ya creados incluyendo a SYSTEM y SYS. El usuario SYS es el
propietario de las tablas internas que Oracle usa para gestionar las bases de datos; el usuario SYSTEM es
propietario de tablas y vistas adicionales. Para crear nuevos usuarios deberemos registrarnos en el sistema
como SYSTEM, porque este usuario tiene este privilegio.
Cuando instalamos Oracle, lo habitual es entrar como el usuario SYSTEM y crear un usuario para nosotros o
para el administrador del sistema. La forma ms simple de crear un usuario es usar el comando CREATE USER,
cuya sintaxis bsica es la siguiente:
CREATE USER nombre_usuario
IDENTIFIED [ BY contrasea | EXTERNALLY ]
DEFAULT TABLESPACE tablespace_por_defecto
TEMPORARY TABLESPACE tablespace_temporal
DEFAULT ROLE [ roles, ALL [EXCEPT roles], NONE ]
QUOTA cantidad {K | M} ON tablespace
QUOTA UNLIMITED ON tablespace
PROFILE nombre_de_perfil
PASSWORD EXPIRE
ACCOUNT {LOCK|UNLOCK};

Oracle /166
Si no asignamos una cuota el usuario no podr crear objetos. Si no asignamos un pefil al usuario se la aplicar
el perfil por defecto.
Si queremos conectarnos a Oracle usando el identificador de usuario y contrasea que usamos al conectarnos
al sistema operativo del ordenador, podemos usar la palabra clave EXTERNALLY en vez de una contrasea en
la clusula IDENTIFIED del comando CREATE USER.
Un Administrador de sistema (el cual tiene los mximos privilegios) puede querer tener la seguridad extra de
tener una contrasea propia. Vamos a llamar al administrador de sistema Pedro en este ejemplo:
CREATE USER Pedro IDENTIFIED BY profesor;
Ahora existe la cuenta de Pedro y est asegurada mediante una contrasea.
Podemos establecer que la cuenta de usuario se asocie con un tablespace especfico, y que est limitada su
cuota de espacio en disco y su uso de recursos. La clusula DEFAULT TABLESPACE permite establecer el
tablespace por defecto para la creacin de objetos del usuario. Si se omite se utilizar el tablespace SYSTEM.
La clusula TEMPORARY TABLESPACE indica el tablespace que se utilizar para la creacin de objetos
temporales en las operaciones internas de Oracle. Si se omite se utilizar el tablespace TEMP.
La clusula DEFAULT ROLE permite asignar roles de permisos durante la creacin del usuario.
3.2. Eliminacin de usuarios.
La eliminacin de usuarios se hace a travs de la instruccin DROP USER. Su sintaxis es:
DROP USER usuario [CASCADE];
La clusula CASCADE permite borrar el usuario y todos los objetos que posea.
3.3. Gestin de contraseas.
Si queremos cambiar la contrasea del usuario podemos usar el comando ALTER USER, tal como sigue:
ALTER USER Pedro IDENTIFIED BY otracontrasea;
Ahora Pedro tiene la contrasea "otracontrasea" en vez de "profesor".
Las contraseas pueden expirar, y las cuentas pueden ser bloqueadas ante repetitivos intentos fallidos de
conectarnos. Cuando cambiamos nuestra contrasea, puede mantenerse un histrico de contraseas para
prevenir que puedan reutilizarse.
Las caractersticas de expiracin de las contraseas son determinadas por el perfil asignado a la cuenta de
usuario. Los perfiles, los cuales se crean con el comando CREATE PROFILE, son administrados por el DBA
(administrador de la base de datos). Los perfiles pueden forzar los siguientes aspectos sobre las contraseas y
cuentas de usuario:
El tiempo de vida de nuestra contrasea, lo que determina la frecuencia en la que debe cambiarse la
contrasea.
El periodo de gracia, despus de fecha de expiracin de la contrasea, durante el cual podemos
cambiarla.
El nmero consecutivos de intentos fallidos de conexin antes de que la cuenta sea automticamente
bloqueada.
El nmero de das que la cuenta permanecer bloqueada.
El nmero de das que deben pasar antes de que podamos reutilizar una contrasea.
El nmero de cambios de contraseas que podemos hacer ante de reutilizar una contrasea antigua.
Funcionalidades adicionales de administracin de contraseas permiten que se haga cumplir con una longitud
mnima y complejidad en las contraseas.
Adems del comando ALTER USER, podemos usar el comando PASSWORD en SQL*Plus para cambiar nuestra
contrasea. Si usamos el comando PASSWORD, nuestra contrasea no ser mostrada en la consola cuando la
escribamos. Los administradores de base de datos pueden cambiar cualquier contrasea de usuario mediante
el comando PASSWORD; otros usuarios pueden cambiar slo su propia contrasea.
Cuando introducimos el comando PASSWORD, se nos solicita la antigua y nueva contrasea, tal como se
muestra a continuacin:
CONNECT Pedro/otracontrasea
PASSWORD
Changing password for Pedro
Old password: otracontrasea
New password: nuevacontrasea
Retype new password: nuevacontrasea
Cuando la contrasea haya sido cambiada recibiremos el siguiente mensaje:

Oracle /167
Password changed
Podemos asignar otra contrasea a un usuario desde una cuenta DBA. Simplemente se aade el nombre de
usuario al comando PASSWORD. En este caso no se nos solicitar la antigua contrasea:
PASSWORD Juan
Changing password for Juan
New password:
Retype new password:
3.3.1. Cmo forzar la expiracin de la contrasea?
Podemos usar perfiles para gestionar la expiracin, reutilizacin y complejidad de las contraseas. Podemos
limitar el tiempo de vida de una contrasea, y bloquear una cuenta si la contrasea es demasiado vieja.
Tambin podemos forzar que una contrasea sea moderadamente compleja, y bloquear una cuenta sobre la
cual se han intentado varios accesos de registro fallidos.
Por ejemplo, si asignamos el recurso FAILED_LOGIN_ATTEMPTS de un perfil de usuario a 5, entonces cuatro
fallos consecutivos de registro sern permitidos, pero al quinto intento la cuenta ser bloqueada.
Nota. Si se proporciona la contrasea correcta al quinto intento, el recurso FAILED LOGIN ATTEMPT
se reinicializa a cero, permitiendo as cinco intentos ms consecutivos antes de que la cuenta se
bloquee.
En el siguiente listado, se crea el perfil PERFIL_LIMITADOR para el usuario Juana:
CREATE PROFILE PERFIL_LIMITADOR LIMIT FAILED_LOGIN_ATTEMPTS 5;
CREATE USER Juana IDENTIFIED BY sucontrasea PROFILE PERFIL_LIMITADOR;
GRANT CREATE SESSION TO Juana;
Si se realizan cinco intentos consecutivos fallidos de conexin en la cuenta de Juana, la cuenta ser
automticamente bloqueada por Oracle. Si en el sexto intento se usa la contrasea correcta para la cuenta de
Juana, recibiremos un error.
Para desbloquear la cuenta se usa la clusula ACCOUNT UNLOCK del comando ALTER USER (desde una cuenta
DBA), tal como se muestra a continuacin:
ALTER USER Juana ACCOUNT UNLOCK;
Tambin podemos bloquear manualmente una cuenta mediante la clusula ACCOUNT LOCK del comando
ALTER USER.
ALTER USER Juana ACCOUNT LOCK;

Nota. Podemos especificar ACCOUNT LOCK como parte del comando CREATE USER.
Si una cuenta se ha cerrado debido a repetidos fracasos de conexin, automticamente ser desbloqueada
cuando se exceda al valor de tiempo especificado en el perfil PASSWORD_LOCK_TIME. Por ejemplo, si
PASSWORD_LOCK_TIME est asignado a 1, la cuenta Juana del ejemplo previo ser bloqueada por un da,
despus de lo cual la cuenta se desbloquear.
Podemos establecer el tiempo de vida mximo de una contrasea mediante el recurso
PASSWORD_LIFE_TIME. Por ejemplo, podemos forzar a los usuarios del perfil PERFIL_LIMITADOR a cambiar
su contrasea cada 30 das de la siguiente forma:
ALTER PROFILE PERFIL_LIMITADOR LIMIT PASSWORD_LIFE_TIME 30;
En este ejemplo, se usa el comando ALTER PROFILE para modificar el perfil PERFIL_LIMITADOR. El valor de
PASSWORD_LIFE_TIME es asignado a 30, de forma que cada cuenta que use este perfil forzar al usuario a
cambiar la contrasea cada 30 das.
Podemos tambin especificar un periodo de gracia para cuando expire una contrasea, mediante el parmetro
PASSWORD_GRACE_TIME. Si la contrasea no es cambiada dentro del periodo de gracia, la cuenta expirar.

Nota. Si se usa el parmetro PASSWORD_LIFE_TIME, deberemos proporcionar a los usuarios una


forma sencilla de cambiar sus contraseas.
Una cuenta "expirada" es diferente de una cuenta "bloqueada". Una cuenta bloqueada puede ser
desbloqueada automticamente con el paso del tiempo. Una cuenta expirada, sin embargo, requiere la
intervencin manual del DBA para ser rehabilitada. Para rehabilitar una cuenta expirada se ejecuta el
comando ALTER USER. En el siguiente ejemplo, el DBA expira manualmente la contrasea de Juana:
ALTER USER Juana PASSWORD EXPIRE;
Usuario modificado.

Oracle /168
A continuacin, Juana intenta conectarse a su cuenta. Cuando ella proporciona su contrasea inmediatamente
se la solicitar una nueva contrasea para la cuenta:
CONNECT Juana/contrasea
ERROR:
ORA-28001: la contrasea ha vencido
Cambiando la contrasea para Juana
Contrasea Nueva:
Confirmar Contrasea:
Contrasea cambiada
Conectado.
Tambin podemos forzar que los usuarios cambien su contrasea cuando accedan por primera vez a sus
cuentas, a travs de la clusula PASSWORD EXPIRE del comando CREATE USER. El comando CREATE USER no
permite, sin embargo, asignar una fecha de expiracin para la nueva contrasea asignada por el usuario; para
hacer esto, debemos usar el parmetro de perfil PASSWORD_LIFE_TIME, tal como se ha visto en los ejemplos
previos.
Podemos consultar la columna Expiry_Date de la tabla DBA_USERS del diccionario de datos para ver las fechas
de expiracin de cualquier cuenta. Los usuarios que quieran ver la fecha de expiracin de sus cuentas pueden
consultar la columna Expiry_Date de la vista USER_USERS del diccionario de datos.
3.3.2. Cmo forzar limitaciones al reutilizar contraseas?
Para evitar que una contrasea pueda ser reutilizada, podemos usar uno de los dos siguientes parmetros de
perfil: PASSWORD_REUSE_MAX o PASSWORD_REUSE_TIME. Estos dos parmetros son mutuamente
exclusivos; si se asigna el valor de uno de ellos, el otro debe estar asignado a UNLIMITED.
El parmetro PASSWORD_REUSE_TIME especifica el nmero de das que deben pasar antes de que una
contrasea pueda ser reutilizada. Por ejemplo, si asignamos PASSWORD_REUSE_TIME a 60, no podremos
reutilizar la misma contrasea antes de 60 das.
El parmetro PASSWORD_REUSE_MAX especifica el nmero de cambios de contrasea que deben ocurrir
antes de que una contrasea pueda ser reutilizada. Si intentamos reutilizar la contrasea antes del lmite,
Oracle rechazar el cambio de contrasea.
Por ejemplo, podemos asignar PASSWORD_REUSE_MAX para el perfil PERFIL_LIMITADOR creado
previamente:
ALTER PROFILE PERFIL_LIMITADOR LIMIT
PASSWORD_REUSE_MAX 3
PASSWORD_REUSE_TIME UNLIMITED;
Si elusuario Juana intenta ahora reutilizar una contrasea reciente no podr. Por ejemplo, supongamos que
ella cambia su contrasea, como en la siguiente lnea:
ALTER USER Juana IDENTIFIED BY contrasea1;
Y ella la cambia otra vez:
ALTER USER Juana IDENTIFIED BY contrasea2;
Durante su siguiente cambio de contrasea, ella intenta reutilizar una contrasea reciente, y su intento falla:
ALTER USER Juana IDENTIFIED BY contrasea1;
ERROR en lnea 1:
ORA-28007: la contrasea no puede ser reutilizada
3.4. Perfiles de usuario.
Los perfiles se utilizan para limitar la cantidad de recursos del sistema y las bases de datos disponibles para un
usuario. Si no se definen perfiles para un usuario se utiliza el perfil por defecto, que especifica recursos
ilimitados.
Los recursos que pueden ser limitados mediante perfiles son los siguientes:
Recurso Descripcin
SESSIONES_PER_USER El nmero de sesiones concurrentes que un usuario puede tener en una
instancia.
CPU_PER_SESSION El tiempo de CPU, en centenas de segundos, que una sesin puede
utilizar.
CONNECT_TIME El nmero de minutos que una sesin puede permanecer activa.

Oracle /169
IDLE_TIME El nmero de minutos que una sesin puede permanecer sin que sea
utilizada de manera activa.
LOGICAL_READS_PER_SESSION El nmero de bloques de datos que se pueden leer en una sesin.
LOGICAL_READS_PER_CALL El nmero de bloques de datos que se pueden leer en una operacin.
PRIVATE_SGA La cantidad de espacio privado que una sesin puede reservar en la zona
de SQL compartido de la SGA.
COMPOSITE_LIMIT El nmero de total de recursos por sesin, en unidades de servicio. Esto
resulta de un clculo ponderado de CPU_PER_SESSION,
CONNECT_TIME, LOGICAL_READS_PER_SESSION y PRIVATE_SGA,
cuyos pesos se pueden variar con el comando ALTER RESOURCE COST.
Los perfiles se pueden crear mediante el comando CREATE PROFILE, y se pueden modificar con la sentencia
ALTER PROFILE.
En general, el perfil por defecto debe ser adecuado para los usuarios normales; los usuarios con
requerimientos especiales deberan tener perfiles especiales.
3.5. Cuentas de base de datos sobre cuentas del sistema operativo.
Los usuarios pueden entrar en la base de datos una vez que han dado un nombre de usuario y una contrasea.
Sin embargo, es posible aprovecharse del Sistema Operativo para obtener un nivel adicional de
autentificacin.
La cuenta de la base de datos (BD) y del Sistema Operativo (SO) pueden relacionarse de manera que la de la
BD se diferencie slo en un prefijo de la cuenta del SO. Este prefijo se fija en el parmetro
OS_AUTHENT_PREFIX del fichero init.ora. Por defecto est puesto a "OPS$", pero puede tomar cualquier
forma, incluso ser la cadena nula, "", con lo que no existe prefijo que diferencie las cuentas en la BD y en el
SO. Se puede mostra el valor actual de este parmetro con la orden:
SHOW PARAMETER OS_AUTHENT_PREFIX;
Por ejemplo, consideremos una cuenta del SO llamada alu10. La correspondiente cuenta en la BD sera
OPS$ALU10. Cuando el usuario alu10 est en activo en el SO, puede acceder a su cuenta OPS$ALU10 sin
especificar la contrasea, como se muestra a continuacin:
CONNECT /
En este caso el carcter "/" toma el lugar de la combinacin del nombre de usuario y de la contrasea que
debera aparecer.
Las cuentas pueden ser creadas con contraseas aunque no vaya a ser utilizada. Ya que de este modo ser
posible acceder a la cuenta de OPS$ALU10 desde otra cuenta diferente a la alu10 del SO. La sentencia de
creacin de la cuenta OPS$ALU10 puede ser la siguiente:
CREATE USER ops$alu10
IDENTIFIED BY 01ula
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;
As, la forma de conectarse como OPS$ALU10 desde una cuenta del SO diferente es:
CONNECT ops$alu10/01ula
Existen dos formas de evitar este tipo de conexin. La primera es creando el usuario BD sin especificar una
contrasea, utilizando la clusula IDENTIFIED EXTERNALLY. De esta manera evitamos la necesidad de
especificar una contrasea para la cuenta, obligando a la conexin entre las cuentas de la BD y del SO:
CREATE USER ops$alu10
IDENTIFIED EXTERNALLY;
La otra manera de evitar este tipo de conexin es crear una cuenta con una contrasea imposible. Se puede
crear una contrasea no vlida indicando un valor encriptado de menos de 16 caracteres:
CREATE USER usuario IDENTIFIED BY VALUES '123AB456C'
3.6. Usuarios globales.
Oracle Advanced Security permite centralizar la gestin de la informacin relacionada con el usuario,
incluidas las autorizaciones, en un servicio de directorio basado en LDAP. Los usuarios pueden ser
identificados en la base de datos como usuarios globales, lo que significa que son autentificados por SSL y
que la gestin de estos usuarios se realiza fuera de la base de datos por el servicio de directorio centralizado.
Se definen roles globales en una base de datos y son conocidos slo por la base de datos, pero la autorizacin
para dichos roles la realiza el servicio de directorio.

Oracle /170
Esta gestin centralizada permite la creacin de usuarios de empresa y roles de empresa. Los usuarios
empresariales son definidos y gestionados en el directorio. Estos usuarios tienen identidades nicas en toda la
empresa y se pueden asignar roles empresariales que determinan sus privilegios de acceso a travs de
mltiples bases de datos. Un rol de empresa se compone de uno o ms roles globales, y pueden ser
considerados como un contenedor para roles globales.
3.6.1. Creacin de un usuario que es autorizado por el servicio de directorio.
Tenemos dos opciones para especificar los usuarios que estn autorizados por un servicio de directorio.
Esquemas privados:
La siguiente declaracin ilustra la creacin de un usuario global con un esquema privado, autentificado por
SSL, y autorizado por el servicio de directorio de la empresa:
CREATE USER scott CREATE USER scott
IDENTIFIED GLOBALLY AS 'CN=scott,OU=division1,O=oracle,C=US';
La cadena proporcionada en la clusula AS proporciona un identificador (nombre completo o DN)
significativo para el directorio de la empresa. En este caso, scott es un usuario global. Sin embargo, la
desventaja aqu es que el usuario scott entonces se debe crear en cada base de datos que deba acceder, adems
de en el directorio.
Esquemas compartidos:
Varios usuarios de la empresa pueden compartir un solo esquema en la base de datos. Estos usuarios estn
autorizados por el servicio de directorio de la empresa pero no poseen esquemas propios en la base de datos.
Estos usuarios no son creados individualmente en la base de datos, se conectan a un esquema comn en la
base de datos.
El proceso de creacin de un usuario independiente del esquema es el siguiente:
1) Crear un esquema compartido en la base de datos de la siguiente manera.
CREATE USER appschema INDENTIFIED GLOBALLY AS '';
2) En el directorio, ahora crear varios usuarios de la empresa, y un objeto de mapeo. El objeto de mapeo le
dice a la base de datos cmo asignar los DN de los usuarios al esquema compartido. Podemos hacer un
mapeado completo de DN (una entrada de directorio por cada DN nico), o podemos mapear, por
ejemplo, cada usuario que contiene los siguientes componentes DN al appschema:
OU=division,O=Oracle,C=US
La mayora de los usuarios no necesitan sus propios esquemas y la implementacin de usuarios
independientes de esquema divorcia al usuario de las bases de datos. Podemos crear varios usuarios que
compartan el mismo esquema en una base de datos, y como usuarios de la empresa, pueden acceder tambin
a esquemas compartidos en otras bases de datos.
3.6.2. Ventajas de autentificacin y autorizacin global.
Algunas de las ventajas de la autentificacin y autorizacin de usuarios global son las siguientes:
Proporciona autenticacin segura usando SSL, Kerberos, o la autentificacin nativa de Windows NT.
Permite la gestin centralizada de usuarios y permisos a travs de toda la empresa.
Es fcil de administrar. No tenemos que crear un esquema para cada usuario en cada base de datos de la
empresa.
Facilita el inicio de sesin nico: los usuarios slo tienen que firmar una vez para acceder a varias bases
de datos y servicios. Adems, los usuarios que utilizan contraseas pueden tener una sola contrasea para
acceder a varias bases de datos.
Dado que la autentificacin y autorizacin de usuarios globales proporciona acceso basado en
contrasea, los usuarios basados en contrasea previamente definidos en la base de datos pueden migrar al
directorio (usando la utilidad de migracin de usuario) para ser administrados centralmente. Esto hace que
la autentificacin y autorizacin globales est disponibles para las versiones previas de Oracle que sean
compatibles.
Los enlaces de bases de datos CURRENT_USER conectan como un usuario global. Un usuario local puede
conectarse como un usuario global en el contexto de un procedimiento almacenado, es decir, sin guardar la
contrasea de usuario global en la definicin del enlace.
3.7. Usuarios con permisos especiales: SYSOPER y SYSDBA.
Cuando nos conectamos a Oracle, podemos diferenciar entre dos grupos de usuarios:
Grupo 1: Usuarios que slo se pueden conectar a la base de datos cuando est abierta.
Grupo 2: Usuarios que se pueden conectar a la base de datos tanto cuando est abierta como cuando est

Oracle /171
cerrada.
Los usuarios del Grupo 2 son aquellos que tiene el privilegio SYSOPER y/o el SYSDBA. Estos dos privilegios
caracterizan a aquellos usuarios de Oracle que pueden hacer operaciones de "seguridad", como el arranque y
parada de la base de datos.
Para poder conectarnos con estos privilegios ( SYSDBA y SYSOPER) tenemos que conectarnos con nuestras
credenciales indicando que queremos tener estos privilegios. Por ejemplo, si somos el usuario SYS y
queremos conectarnos con permisos SYSDBA usaramos:
CONNECT SYS/contrasea AS SYSDBA
Anlogamente, para conectarnos con permisos SYOPER, podemos usar:
CONNECT SYS/contrasea AS SYSOPER
En Oracle existe un fichero de contraseas donde se limita cual es el nmero de usuarios que se pueden crear
en la base de datos con estos privilegios. Este fichero de Oracle contiene las contraseas de los usuarios que
tienen los privilegios de SYSDBA y/o SYSOPER. Este archivo se crea cuando creamos la base de datos, sin
embargo tambin puede ser recreado mediante la utilidad orapwd. Para utilizar este comando y recrear el
archivo de contraseas tenemos que tener en cuenta que el ejecutable orapwd se encuentra en
$ORACLE_HOME/bin/orapwd.
Por ejemplo, si queremos establecer el nmero mximo en 12 usuarios:
$orapwd file=$ORACLE_HOME/dbs/orapwdorasite.ora password=oracle entries=12
File= nombre del fichero de contraseas.
Password= contrasea para SYS AS SYSDBA.
Entries= nmero mximo de DBA.
Los argumentos file y password son obligatorios.
Como vemos, mediante entries limitamos el nmero de usuarios mximos que pueden tener ese privilegio en
la base de datos.
3.8. Roles estndar.
La creacin de roles permite asignar un grupo de permisos a un usuario, y poder modificar este grupo de
permisos sin tener que ir modificando todos los usuarios. Si asignamos un rol con 10 permisos a 300 usuarios,
y posteriormente aadimos un permiso nuevo al rol, no ser necesario ir aadiendo este nuevo permiso a los
300 usuarios, ya que el rol se encarga automticamente de propagarlo. La sintaxis bsica es:
CREATE ROLE nombre_rol [NOT IDENTIFIED | IDENTIFIED [BY contrasea | EXTERNALLY]] ;
Una vez que el rol ha sido creado ser necesario aadirle permisos a travs del comando GRANT.
Si creamos un nuevo usuario, como Juana, no tendr ningn privilegio del sistema. En la mayora de casos, un
usuario de aplicacin recibir privilegios a travs de roles. Podemos agrupar privilegios del sistema y acceso a
objetos dentro de roles especficos segn las necesidades de los usuarios de aplicacin. Podemos crear
nuestros propios roles para acceder a aplicaciones, y podemos usar los roles por defecto de Oracle para algn
requerimiento de acceso al sistema. Los roles estndar ms importantes creados durante la creacin de la base
de datos son:
CONNECT, RESOURCE y DBA Se proporcionan para compatibilidad con versiones previas de Oracle.
DELETE_CATALOG_ROLE, Se proporcionan estos roles para acceder a las vistas y paquetes del
EXECUTE_CATALOG_ROLE, diccionario de datos.
SELECT_CATALOG_ROLE
EXP_FULL_DATABASE, Se proporcionan para usar las utilidades Import y Export.
IMP_FULL_DATABASE
AQ_USER_ROLE, Estos roles son necesarios para Oracle Advanced Queuing.
AQ_ADMINISTRATOR_ROLE
SNMPAGENT Este rol es usado por el Enterprise Manager Intelligent Agent.
RECOVERY_CATALOG_OWNER Se requiere este rol para la creacin de un catlogo de recuperacin
propietario de esquema.
SCHEDULER_ADMIN Este rol permite la ejecucin de los procedimientos del paquete
DBMS_SCHEDULER. Debera restringirse slo a los DBA's.

CONNECT, RESOURCE y DBA se proporcionan para compatibilidad y no deberan usarse ms. CONNECT da a los
usuarios la habilidad de conectarse (iniciar una sesin) y realizar funciones bsicas. Los usuarios con el rol
CONNECT pueden crear tablas, vistas, secuencias, clsteres, sinnimos y enlaces de base de datos.
Los usuarios con el rol RESOURCE pueden crear sus propias tablas, secuencias, procedimientos, triggers, tipos

Oracle /172
de datos, operadores, tipos de ndices, ndices y clsteres. Los usuarios con este rol pueden recibir tambin el
privilegio del sistema UNLIMITED TABLESPACE, que les permite saltarse las cuotas de todos los tablespaces.
Los usuarios con el rol DBA pueden realizar funciones de administracin de base de datos, incluido crear y
alterar usuarios, espacios de tabla y objetos.
En lugar de CONNECT, RESOURCE y DBA, deberamos crear nuestros propios roles que tengan privilegios para
ejecutar privilegios especficos del sistema.
3.9. Permisos del sistema.
Ya hemos dicho que los privilegios de sistema son permisos para realizar ciertas operaciones en la base de
datos. El modo de asignar un privilegio es a travs de la instruccin GRANT y el modo de cancelar un
privilegio es a travs de la instruccin REVOKE.
3.9.1. Instruccin GRANT.
Para conceder permisos se utiliza el comando GRANT, el cual tiene la siguiente sintaxis:
GRANT [privilegios_de_sistema | roles] TO [usuarios | roles | PUBLIC] [WITH ADMIN OPTION];
Es posible dar ms de un privilegio de sistema o rol, separndolos por comas. Tambin es posible asignarle
uno (o varios) privilegios a varios usuarios, separndolos por comas. Si se le asigna el privilegio a un rol, se
asignar a todos los usuarios que tengan ese rol. Si se asigna el privilegio a PUBLIC, se asignar a todos los
usuarios actuales y futuros de la base de datos. La clusula WITH ADMIN OPTION permite que el privilegio/rol
que hemos concedido, pueda ser concedido a otros usuarios por el usuario al que estamos asignando.
Veamos algunos ejemplos sencillos:
Permiso para acceder a la base de datos (permiso de sistema):
GRANT CREATE SESSION TO un_usuario;
Permiso para usuario de modificacin de datos (permiso sobre objeto):
GRANT SELECT, INSERT, UPDATE, DELETE ON una_tabla TO un_usuario;
Permiso de solo lectura sobre una tabla para todos:
GRANT SELECT ON una_tabla TO PUBLIC;
Permisos de sistema (system privileges):
Los permisos de sistema ms importantes son CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE USER,
CREATE PROCEDURE, CREATE SYNONYM, ALTER TABLE, ALTER VIEW, ALTER PROCEDURE, ALTER SYNONYM,
DROP TABLE, DROP VIEW, DROP PROCEDURE, DROP SYNONYM, ...
Se pueden usar las siguientes sintaxis para conceder los permisos de sistema:
GRANT privilegios TO {usuario, | rol, | PUBLIC} [IDENTIFIED BY contrasea] [WITH ADMIN OPTION];
GRANT rol TO {usuario, | rol, | PUBLIC} [IDENTIFIED BY contrasea] [WITH ADMIN OPTION];
GRANT ALL PRIVILEGES TO {usuario, | rol, |PUBLIC} [IDENTIFIED BY contrasea] [WITH ADMIN OPTION];
Podemos obtener la lista de permisos del sistema con el comando siguiente:
SELECT * FROM SYSTEM_PRIVILEGE_MAP;
Por ejemplo, si deseamos dar permisos de creacin y borrado de tablas al usuario Empleado podemos usar:
GRANT CREATE ANY TABLE, DROP ANY TABLE TO Empleado;
Los permisos de sistema son auditables.
Permisos sobre objetos (object privileges):
Los permisos sobre objetos ms importantes son: SELECT, UPDATE, INSERT, DELETE, ALTER, DEBUG,
EXECUTE, INDEX, y REFERENCES.
Se pueden usar las siguientes sintaxis para conceder permisos sobre objetos:
GRANT permiso [(columna, columna, ...)] ON [esquema.]objeto
TO {usuario, | rol, | PUBLIC} [WITH GRANT OPTION] [WITH HIERARCHY OPTION];
GRANT ALL PRIVILEGES [(columna, columna, ...)] ON [esquema.]objeto
TO {usuario, | rol, | PUBLIC} [WITH GRANT OPTION] [WITH HIERARCHY OPTION];
GRANT permiso [(columna, columna, ...)] ON DIRECTORY nombre_directorio
TO {usuario, | rol, | PUBLIC} [WITH GRANT OPTION] [WITH HIERARCHY OPTION];
GRANT permiso [(columna, columna, ...)] ON JAVA [RE]SOURCE [esquema.]objeto
TO {usuario, | rol, | PUBLIC} [WITH GRANT OPTION] [WITH HIERARCHY OPTION];
Con la opcin WITH HIERARCHY OPTION damos permisos sobre todos los sub-objetos, incluso sobre los que
se creen despus de ejecutar el comando GRANT.
Con la opcin WITH GRANT OPTION damos permiso para que el que los recibe los pueda a su vez asignar a
otros usuarios y roles.
La opcin "GRANT ALL PRIVILEGES..." se puede escribir tambin como "GRANT ALL..."

Oracle /173
Podemos obtener la lista de permisos de las tablas con el comando siguiente:
SELECT * FROM all_tab_privs_made;
3.9.2. Instruccin REVOKE.
Para quitar permisos concedidos se utiliza el comando REVOKE, el cual tiene la siguiente sintaxis:
REVOKE [privilegios_de_sistema | roles] FROM [usuarios | roles |PUBLIC];
Es posible eliminar ms de un privilegio de sistema o rol, separndolos por comas. Tambin es posible
eliminar uno (o varios) privilegios a varios usuarios, separndolos por comas. Si se elimina el privilegio de un
rol, se eliminar de todos los usuarios que tengan ese rol. Si se elimina el privilegio de PUBLIC, se eliminar de
todos los usuarios actuales y futuros de la base de datos. Como es lgico, slo se podr eliminar un
privilegio/rol, si previamente ha sido concedido a travs de la instruccin GRANT.
Ejemplos:
REVOKE DBA FROM ADMINISTRADOR;
REVOKE CREATE USER FROM PEPOTE;
REVOKE DROP USER FROM JUANCITO;
RECOKE CONNECT, RESOURCE FROM PEPOTE, JUANCITO;
REVOKE CONNECT, RESOURCE, DBA, EXP_FULL_DATABASE, IMP_FULL_DATABASE
FROM CONTROL_TOTAL;
REVOKE CONTROL_TOTAL FROM ADMINISTRADOR;
Revocando privilegios de objetos.
El modo de eliminar permisos de objeto es con:
REVOKE [ALL {PRIVILEGES} | SELECT | INSERT | UPDATE | DELETE]
[(columna, ...)] ON objeto FROM [usuario | rol | PUBLIC] {WITH ADMIN OPTION};
Al igual que con los permisos de sistema, es posible asignar un permiso de objeto sobre uno o varios usuario
y/o roles (separados por comas). Si se asigna a PUBLIC ser accesible en toda la base de datos.
Si se incluye la clusula WITH ADMIN OPTION, este permiso podr ser concedido por el usuario al que se le ha
asignado.
3.9.3. Lo que los usuarios pueden conceder.
Un usuario puede conceder privilegios sobre cualquier objeto del que sea propietario. El administrador de la
base de datos puede conceder cualquier privilegio del sistema.
Supongamos que el usuario Dora es propietario de la tabla Ventas y es un administrador de la base de datos.
Crea dos nuevos usuarios, Bob y Judy, con estos privilegios:
CREATE USER Judy IDENTIFIED BY contrasea;
/
GRANT CREATE SESSION TO Judy;
/
CREATE USER Bob IDENTIFIED BY contrasea;
/
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SYNONYM TO Bob;
/
ALTER USER Bob DEFAULT TABLESPACE USERS QUOTA 5m ON USERS;
Esta secuencia de comandos da a Judy y Bob la habilidad de conectarse a Oracle, y da a Bob algunas
capacidades extra. Pero, pueden hacer algo con las tablas de Dora? No sin permisos explcitos.
Para dar acceso a nuestras tablas se usan la siguiente sintaxis del comando GRANT:
GRANT { permiso | ALL [PRIVILEGES] }
[(columna [, columna] . . .)]
[, { permiso | ALL [PRIVILEGES] }
[(columna [, columna] . . .)] ] . . .
ON objeto TO {usuario | rol}
[WITH GRANT OPTION]
[WITH HIERARCHY OPTION];
Los permisos que un usuario puede conceder incluyen los siguientes:
Sobre tablas de usuario, vistas y vistas materializadas:
FLASHBACK.
INSERT.
UPDATE (todas o columnas especficas)
DELETE.

Oracle /174
SELECT.
Los permisos INSERT, UPDATE y DELETE slo pueden concederse sobre vistas materializadas si son
actualizables.
Sobre tablas, tambin se pueden conceder:
ALTER (tabla todas o columnas especficas)
DEBUG.
REFERENCES.
INDEX (columnas en una tabla)
ON COMMIT REFRESH.
QUERY REWRITE.
ALL (de los elementos previamente listados)
Sobre procedimientos, funciones, paquetes, tipos de datos abstractos, libreras, tipos de ndices y
operadores:
EXECUTE.
DEBUG.
Sobre secuencias:
SELECT.
ALTER.
Sobre directorios (para tipos de datos BFILE LOB y tablas externas):
READ.
WRITE.
Sobre tipos de datos abstractos y vistas:
UNDER (para la habilidad de crear subvistas bajo una vista, o subtipos bajo un tipo)
Cuando se ejecuta otro procedimiento o funcin de usuario, normalmente se ejecuta usando los permisos de
su propietario. Esto significa que no necesitamos explcitamente acceder a los datos que el procedimiento o
funcin usa; podemos ver slo el resultado de la ejecucin, no los datos subyacentes. Tambin podemos crear
procedimientos almacenados que se ejecuten bajos los permisos del usuario que los invoca en vez de los
permisos del propietario.
Dora le da a Bob acceso SELECT a la tabla Ventas:
GRANT SELECT ON Ventas TO Bob;
La clusula WITH GRANT OPTION del comando GRANT permite al recibidor de permisos pasarlos a otros. Si
Dora concede permisos a Bob usando WITH GRANT OPTION, Bob podr dar permisos de acceso a las tablas de
Dora a otros usuarios.
Movernos a otro usuario con CONNECT.
Para realizar pruebas, Dora se conecta a la base de datos con el nombre de usuario de Bob usando el comando
CONNECT. Este comando puede usarse a travs de uno de los siguientes mtodos:
Indicando el nombre de usuario y contrasea sobre la misma lnea de comando.
Escribiendo slo el comando y respondiendo a las peticiones de credenciales.
Escribiendo el comando y el nombre de usuario, y despus respondiendo a la peticin de contrasea.
Los dos ltimos mtodos evitan mostrar la contrasea y por tanto son inherentemente ms seguros. El
siguiente comando es una muestra de conexin a la base de datos:
CONNECT Bob/contrasea
Una vez conectado, Dora selecciona los datos de una tabla a la cual Bob tiene permisos de acceso.
SELECT * FROM Dora.Ventas;
Se crea una vista llamada VENTAS, la cual simplemente selecciona los datos de la tabla Dora.Ventas:
CREATE VIEW VENTAS AS SELECT * FROM Dora.Ventas;
Esta vista producir exactamente los mismos resultados que la tabla Dora.Ventas.
Si ahora Dora retorna a su propia cuenta y crea una vista que seleccione slo parte de la tabla Ventas:
CONNECT Dora/contrasea
/
CREATE VIEW ALGUNAS_VENTAS AS
SELECT * FROM Ventas WHERE IdCliente = 1;
Si entonces le concede permisos SELECT y UPDATE a Bob sobre esta vista, y revoca todos los permisos de Bob
sobre la tabla Ventas:
GRANT SELECT, UPDATE ON ALGUNAS_VENTAS TO Bob;

Oracle /175
/
REVOKE ALL ON Ventas FROM Bob;
Y si ahora Dora se reconecta con la cuenta de Bob para probar los cambios:
CONNECT Bob/contrasea
/
SELECT * FROM VENTAS;
Se produce un error:
ERROR en lnea 1:
ORA-04063: vista "BOB.VENTAS" tiene errores
Intentar hacer una seleccin sobre la vista VENTAS falla porque para su defincin se necesitan permisos de
acceso a la tabla subyacente Dora.Ventas, para la cual el usuario Bob ya no tiene permisos de acceso. Sin
embargo, un intento de seleccionar la vista Dora.ALGUNAS_VENTAS:
SELECT * FROM Dora.ALGUNAS_VENTAS;
No provoca ningn tipo de error; aunque no se tengan permisos sobre la tabla subyacente Dora.Ventas, el
acceso a parte de esta tabla est permitido a travs de esta vista.
Es decir, podemos crear una vista usando virtualmente alguna restriccin o computacin en sus columnas, y
entonces podemos dar permisos a otros usuarios de acceso a la vista, en vez de a las tablas subyacentes. Esos
usuarios slo vern la informacin que devuelva la vista.
Ahora, si se crea la vista ALGUNAS_VENTAS_CORTO bajo la cuenta de Bob:
CREATE VIEW ALGUNAS_VENTAS_CORTO AS SELECT * FROM Dora.ALGUNAS_VENTAS;
Y se actualiza un registro:
UPDATE ALGUNAS_VENTAS_CORTO SET Cantidad = 88 WHERE IdVenta = 3;
Cuando la vista ALGUNAS_VENTAS_CORTO es consultada, se muestran los efectos de la actualizacin. Una
consulta sobre Dora.ALGUNAS_VENTAS debera mostrar los mismos resultados, ya que la actualizacin se
realiz sobre la tabla subyacente.
Nota. Necesitamos conceder el permiso SELECT a cualquier tabla de la que queramos actualizar o
borrar registros. Esto est de acuerdo con el desarrollo ANSI estndar y refleja el hecho de que un
usuario que slo tiene permiso UPDATE o DELETE sobre una tabla podra usar los comentarios de
generacin de la base de datos para descubrir informacin sobre los datos subyacentes.
Creacin de sinnimos.
Un mtodo alternativo para crear una vista que incluya una tabla entera o una vista desde otro usuario es
crear un sinnimo:
CREATE SYNONYM BOB_VENTAS FOR Dora.ALGUNAS_VENTAS;
Este sinnimo puede ser tratado exactamente como una vista.
Usando permisos no concedidos.
Intentemos suprimir el registro que fue actualizado previamente:
DELETE FROM ALGUNAS_VENTAS WHERE IdVenta = 3;
Se produce un error:
ERROR en lnea 1:
ORA-01031: permisos insuficientes
Bob no recibi el permiso DELETE por parte de Dora, as que el intento falla.
Pasando permisos.
Bob puede conceder autoridad a otros usuarios para acceder a sus tablas, pero no puede otorgar a otros
usuarios a tablas que no le pertenecen. As, si intenta dar la autoridad INSERT a Judy:
GRANT INSERT ON Dora.ALGUNAS_VENTAS TO Judy;
Se produce un error:
ERROR en lnea 1:
ORA-01031: permisos insuficientes
Debido a que Bob no tiene esta autoridad, falla. Ahora, si Bob intenta pasar un permiso que s tiene, como
SELECT:
GRANT SELECT ON Dora.ALGUNAS_VENTAS TO Judy;
Se produce un error:
ERROR en lnea 1:
ORA-01031: permisos insuficientes
l no puede ceder este permiso tampoco, porque la vista ALGUNAS_VENTAS no le pertenece. Si se le hubiese

Oracle /176
concedido el acceso a ALGUNAS_VENTAS con WITH GRANT OPTION, entonces el comando precedente no
hubiese fallado. La vista ALGUNAS_VENTAS_CORTO realmente le pertenece, as que puede tratar de pasar la
autoridad de esta vista a Judy:
GRANT SELECT ON ALGUNAS_VENTAS_CORTO TO Judy;
Pero el resultado es tambin un error:
ERROR en lnea 1:
ORA-01720: no existe la opcin grant para 'DORA.ALGUNAS_VENTAS'
Ya que la vista ALGUNAS_VENTAS es realmente una de las vistas de Dora, y Bob no tiene concedido SELECT
WITH GRANT OPTION sobre la vista, la concesin de Bob falla.
Adicionalmente, una nueva tabla, propiedad de Bob, es creada y cargada con la informacin actual de su vista
ALGUNAS_VENTAS_CORTO:
CREATE TABLE NO_VENTAS AS
SELECT * FROM ALGUNAS_VENTAS_CORTO;
Se concede el permiso SELECT sobre esta tabla a Judy:
GRANT SELECT ON NO_VENTAS TO Judy;
Podemos hacer consultas a esta tabla a travs de la cuenta de Judy:
CONNECT Judy/contrasea
/
SELECT * FROM Bob.NO_VENTAS;
Si Dora quiere que Bob ser capaz de pasar sus permisos a otros, pueden aadir otra clusula al comando
GRANT:
CONNECT Dora/contrasea
/
GRANT SELECT, UPDATE ON ALGUNAS_VENTAS TO Bob WITH GRANT OPTION;
La clusula WITH GRANT OPTION permite a Bob pasar los accesos de ALGUNAS_VENTAS a Judy a travs de su
vista ALGUNAS_VENTAS_CORTO.
Si cualquier otro usuario intenta acceder a una tabla para la cual no tiene el permiso SELECT siempre se
producir el siguiente mensaje:
ERROR en lnea 1:
ORA-00942: la tabla o vista no existe
Creacin de un rol.
Adems de los roles por defecto vistos previamente, podemos crear nuestros propios roles con Oracle. Los
roles que creamos pueden comprender tablas o permisos del sistema o una combinacin de ambos.
Para crear un rol necesitamos tener el permiso de sistema CREATE ROLE. La sintaxis para crear un rol es la
siguiente:
CREATE ROLE nombre_del_rol
[NOT IDENTIFIED |
IDENTIFIED {BY contrasea | USING [esquema.]paquete | EXTERNALLY | GLOBALLY }];
Cuando se crea un rol no tiene ningn permiso asociado.
Dos ejemplo de creacin de roles son los siguientes:
CREATE ROLE Empleado;
CREATE ROLE Administrador;
El primer comando crea un rol llamado Empleado, el cual es usado en ejemplos posteriores. El segundo
comando crea un rol llamado Administrador.
Concediendo permisos a un rol.
Una vez creado un rol, podemos darle permisos. La sintaxis del comando GRANT es la misma para roles como
para usuarios. Cuando concedemos permisos a roles, se usa el nombre de rol en la clusula del comando
GRANT, tal como se muestra a continuacin:
GRANT SELECT ON Ventas TO Empleado;
El permiso de acceso a la tabla Ventas ser concedido a cualquier usuario perteneciente al rol Empleado.
Si somos administradores de base de datos, o tenemos concedidos el role de sistema GRANT ANY PRIVILEGE
podemos conceder permisos del sistema (como CREATE SESSION, CREATE SYNONYM y CREATE VIEW). Estos
permisos estarn entonces disponibles para cualquier usuario de nuestro rol.
La habilidad de registrarnos dentro de una base de datos se realiza a travs del permiso de sistema CREATE
SESSION. En el siguiente ejemplo, este permiso es concedido al rol Empleado. Este permiso es tambin
concedido al rol Administrador, adems del permiso CREATE VIEW:

Oracle /177
GRANT CREATE SESSION TO Empleado;
GRANT CREATE SESSION, CREATE VIEW TO Administrador;
Concediendo un rol a otro rol.
Los roles pueden ser concedidos a otros roles. Podemos hacer esto a travs del comando GRANT, tal como se
muestra a continuacin:
GRANT Empleado TO Administrador;

Nota. No se pueden hacer concesiones circulares, as que no podemos conceder Administrador a


Empleado.

En este ejemplo, el rol Empleado es concedido al rol Administrador. Incluso aunque no hayamos concedido
directamente ningn permiso de tabla al rol Administrador, ahora heredar cualquier permiso concedido al rol
Empleado. La organizacin de roles de este modo es un diseo comn en organizaciones jerrquicas.
Cuando concedemos un rol a otro (o a un usuario) podemos utilizar la clusula WITH ADMIN OPTION:
GRANT Empleado TO Administrador WITH ADMIN OPTION;
Cuando se usa esta clusula, el destinatario tiene la autoridad de conceder el rol a otro usuario o roles. El
destinatario tambin podr alterar o borrar el rol.
Concediendo un rol a usuarios.
Los roles pueden ser concedidos a usuarios. Cuando se conceden a usuarios, los roles pueden ser pensados
como conjuntos de permisos con nombre. En vez de conceder cada permiso a cada usuario, podemos
conceder los permisos al rol y entonces conceder el rol a cada usuario. Esto simplifica enormemente las tareas
administrativas involucradas con la gestin de permisos.
Nota. Los permisos que son concedidos a travs de roles no pueden ser usados para vistas,
procedimientos, funciones, paquetes o claves forneas. Cuando se crean estos tipos de objetos de
base de datos, debemos confiarles directamente los necesarios privilegios.
Podemos conceder un rol a un usuario a travs del comando GRANT, tal como se muestra a continuacin:
GRANT Empleado TO Bob;
En este ejemplo, el usuario Bob hereda todos los permisos concedidos al rol Empleado (CREATE SESSION y
SELECT sobre la tabla Ventas).
Cuando concedemos un rol a un usuario, podemos incluir la clusula WITH ADMIN OPTION:
GRANT Administrador TO Dora WITH ADMIN OPTION;
Esto permitir a Dora la autoridad de conceder el rol Administrador a otros usuarios o roles, o de alterar y
eliminar el rol.
Aadiendo una contrasea a un rol.
Se puede usar el comando ALTER ROLE para un nico propsito: cambiar la autoridad necesaria para habilitar
el rol. Por defecto, los roles no tienen contraseas asociadas con ellos. Para habilitar la seguridad de un rol se
usa la palabra clave IDENTIFIED en el comando ALTER ROLE. Hay dos formas de implementar esta seguridad.
Primera, podemos usar la clusula IDENTIFIED BY del comando ALTER ROLE para especificar una contrasea,
tal como se muestra a continuacin:
ALTER ROLE Administrador IDENTIFIED BY contrasea;
Cada vez que un usuario intente activar este rol, se le requerir la contrasea. Sin embargo, si este rol es
asignado como el rol por defecto del usuario, no se le requerir ninguna contrasea cuando el usuario se
registre.
Los roles pueden atarse tambin a permisos del sistema operativo. Si esta capacidad est disponible en el
sistema operativo, se usa la clusula IDENTIFIED EXTERNALLY en el comando ALTER ROLE. Cuando el rol se
habilite, Oracle comprobar el sistema operativo para verificar el acceso. El siguiente ejemplo muestra cmo
cambiar un rol para esta funcionalidad:
ALTER ROLE Administrador IDENTIFIED EXTERNALLY;
En muchos sistemas UNIX, el proceso de comprobacin usa el fichero /etc/group. Para usar este fichero en
algn sistema operativo, el parmetro de inicio OS_ROLES del fichero init.ora debe ser asignado a TRUE. El
siguiente ejemplo de este proceso de comprobacin es para una instancia de base de datos llamada "Local"
sobre un sistema UNIX. El fichero de servidor /etc/group puede contener la siguiente entrada:
ora_local_administrador_d:NONE:1:dora
Esta entrada concede el rol Administrador a la cuenta llamada Dora. El sufijo _d indica que este rol es asignado
por defecto cuando Dora se registra. Un sufijo _a indicara que este rol estara habilitado con WITH ADMIN

Oracle /178
OPTION. Si ms de un usuario tienen concedido este rol, los nombres de usuario adicionales deben ser
aadidos a la entrada de /etc/group, tal como se muestra a continuacin:
ora_local_manager_d:NONE:1:dora,judy
Si usamos esta opcin, los roles en la base de datos sern habilitados a travs del sistema operativo.
Eliminando una contrasea de un rol.
Para eliminar una contrasea de un rol, se usan la clusula NOT IDENTIFIED en el comando ALTER ROL, tal
como se muestra a continuacin:
ALTER ROLE Administrador NOT IDENTIFIED;
Habilitando y deshabilitando roles.
Cuando una cuenta de usuario es alterada, una lista de roles por defecto para ese usuario pueden ser creados a
travs de la clusula DEFAULT ROLE del comando ALTER USER. La accin por defecto de este comando asigna
todos los roles del usuario como roles por defecto, habilitndolos cada vez que el usuario se registra.
Nota. El nmero mximo de roles que un usuario puede tener habilitados cada vez es determinado
por el parmetro de inicializacin MAX_ENABLED_ROLES.
La sintaxis para este parte del comando ALTER USER es la siguiente:
ALTER USER nombre_del_usuario
DEFAULT ROLE {[rol1, rol2]
[ALL | ALL EXCEPT rol1, rol2] [NONE]};
Un usuario puede ser modificado para tener, por defecto, roles especficos habilitados, todos los roles
habilitados, todos habilitados excepto roles especficos, o ningn rol habilitado. Por ejemplo, el siguiente
comando ALTER USER habilita el rol Empleado cuando Bob se registra:
ALTER USER Bob
DEFAULT ROLE Empleado;
Para habilitar un rol que no sea por defecto, se usa el comando SET ROLE, tal como se muestra a
continuacin:
SET ROLE Empleado;
Para ver qu roles estn habilitados dentro de la sesin actual, hay que consultar la vista del diccionario de
datos SESSION_ROLES. Consultando la vista SESSION_PRIVS podemos ver los permisos de sistema
habilitados actualmente. Tambin se pueden usar las clusulas ALL y ALL EXCEPT del comando ALTER USER.
SET ROLE ALL;
SET ROLE ALL EXCEPT Empleado;
Si un rol tiene asociada una contrasea, sta debe ser especificada mediante la clusula IDENTIFIED BY:
SET ROLE Administrador IDENTIFIED BY contrasea;
Para deshabilitar un rol en nuestra sesin, se usan el comando SET ROLE NONE. Esto deshabilita todos los
roles de la sesin actual. Una vez que todos los roles han sido deshabilitados deberemos habilitar los que
queramos.
Ya que puede ser necesario ejecutar un comando SET ROLE NONE de vez en cuando, podemos conceder el
permiso CREATE SESSION directamente a los usuarios en vez de usar roles.
Revocando los permisos de un rol.
Para revocar los permisos de un rol se usa el comando REVOKE, descrito previamente. Se debe especificar el
permiso, nombre del objeto y nombre del rol, tal como se muestra a continuacin:
REVOKE SELECT ON Ventas FROM Empleado;
Con este comando, los usuarios del rol Empleadoya no podrn consultar la tabla Ventas.
Eliminando un rol.
Para eliminar un rol se usa el comando DROP ROL, tal como se muestra a continuacin:
DROP ROLE Administrador;
El rol especificado y sus permisos asociados son eliminados de la base de datos. Las concesiones y
revocaciones de permisos del sistema y de objetos tienen efecto inmediato. Las concesiones y revocaciones de
roles se observan slo cuando un usuario actual enva un comando SET ROLE o se inicia una nueva sesin de
usuario.
Concediendo actualizaciones a columnas especficas.
Podemos querer conceder a usuarios el permiso SELECT para ms columnas de las que les queremos conceder
el permiso UPDATE. Debido a que las columnas SELECT pueden restringirse a travs de una vista, para
restringir las columnas que pueden ser actualizadas se necesita una forma especial del comando GRANT de
usuario. A continuacin se muestra un ejemplo para dos columnas de la tabla Ventas:

Oracle /179
GRANT UPDATE (Producto, Cantidad) ON Ventas TO Judy;
Revocando privilegios de objetos.
La sintaxis para revocar permisos es similar a la del comando GRANT:
REVOKE { permiso_de_objeto | ALL [permisos]}
[(columna [, columna] . . . )]
[, { permiso_de_objecto | ALL [permisos]}
[(columna [, columna] . . . )]] . . .]
ON objecto
FFROM {usuario | rol} [, {usario | rol}]
[CASCADE CONSTRAINTS] [FORCE];
REVOKE ALL elimina cualquiera de los permisos listados previamente, desde SELECT hasta INDEX; si se revocan
permisos individuales se dejarn intactos los que se haban concedido. La clusula WITH GRANT OPTION es
revocada junto con el permiso al cual se conect; se revoca entonces en cascada a todos los usuarios que
recibieron sus accesos a travs de WITH GRANT OPTION.
Si un usuario define restricciones de integridad referencial sobre un objeto, Oracle elimina estas restricciones
si revocamos los permisos sobre el objeto usando la opcin CASCADE CONSTRAINTS. La opcin FORCE se
aplica a los tipos de datos definidos por el usuario, y revoca el permiso EXECUTE sobre tipos de datos
definidos por el usuario con tablas o dependencias de tipos; todos los objetos dependientes sern marcados
como invlidos y los datos en tablas dependientes sern inaccesibles hasta que se concedan los permisos
necesarios.
Seguridad por usuario.
Se puede conceder el acceso a tablas especficamente, tabla por tabla y vista por vista, para cada usuario o rol.
Hay, sin embargo, una tcnica adicional que simplifica este proceso en algunos casos. Supongamos una
consulta sobre la tabla Ventas donde seleccionamos el nombre del cliente asociado con la venta, el nombre del
producto y el precio del producto:
SELECT NombreCliente, Producto, Precio FROM Ventas;
Si queremos restringir el acceso a esta tabla a cada cliente, de forma que cada cliente pueda ver slo sus
ventas, podemos crear tantas vistas como clientes aplicando permisos diferentes. Pero si el nombre de cliente
coincide con el nombre de usuario de la base de datos, tambin podemos crear una nica vista con una
clusula WHERE que filtre por el usuario actual (dado por la pseudo-columna USER de SQL*Plus).
CREATE OR REPLACE VIEW Mis_Ventas AS
SELECT * FROM Ventas
WHERE NombreCliente = USER;
El propietario de la tabla Ventas puede crear estavista y conceder el permiso SELECT a todos los usuarios que
son clientes. Un usuario puede entonces consultar la tabla Ventas a travs de la vista Mis_Ventas, de forma que
slo podr ver nicamente sus registros de venta.
El siguiente ejemplo muestra cmo el administrador Dora crea un usuario para el cliente Juan, y cmo le
concede permisos para que consulte sus ventas:
CREATE USER Juan IDENTIFIED BY contrasea;
/
GRANT CREATE SESSION TO Juan;
/
GRANT SELECT ON Mis_Ventas TO Juan;
/
CONNECT Juan/contrasea
/
SELECT * FROM Dora.Mis_Ventas;
El resultado de la ltima consulta sern aquellos registros de venta donde el campo NombreCliente es igual a
'Juan'.
Concediendo accesos en general.
En vez de conceder accesos a cada usuario, el comando GRANT puede ser generalizado para todo el mundo:
GRANT SELECT ON Mis_Ventas TO PUBLIC;
Esto permite a todos acceder a la vista, incluidos los usuarios creados despus de aplicar este comando. Sin
embargo, para acceder a la vista cada usuario tendr que usar el nombre de usuario del propietario de la vista
(en este ejemplo, Dora) como un prefijo. Para evitar esto, Dora puede crear un sinnimo pblico:
CREATE PUBLIC SYNONYM Mis_Ventas FOR Dora.Mis_Ventas;

Oracle /180
De esta forma, cualquiera puede acceder a Mis_Ventas sin prefijarlo con el esquema del propietario.
3.9.4. Concesin de recursos limitados.
Cuando concedemos cuotas de recursos en una base de datos de Oracle, se usa el parmetro QUOTA del
comando CREATE USER o ALTER USER, tal como se muestra a continuacin.
ALTER USER Bob
QUOTA 100M ON USERS;
En este ejemplo, se le concede a Bob una cuota de 100 Megabytes en el espacio de tablas USERS. Se puede
asignar un espacio de cuota, cuando se crea el usuario, a travs del comando CREATE USER. Si queremos quitar
los lmites a la cuota de un usuario, podemos conceder al usuario el permiso de sistema UNLIMITED
TABLESPACE (no se puede conceder a un role este permiso).
Podemos usar tambin perfiles para forzar otros lmites de recursos, como la cantidad de tiempo de CPU o el
tiempo de espera para las respuestas a un usuario. Se crea un perfil detallando estos lmites de recursos y
entonces se asigna a uno o ms usuarios.
3.10. Metadatos sobre permisos y usuarios.
El diccionario de datos de Oracle proporciona varias vistas que se pueden utilizar para consultar los usuarios
y permisos registrados. Las ms relevantes son:
Para obtener los usuarios:
- dba_users: lista los usuarios con permisos de administrador.
- user_users: lista el usuario actual.
- all_users: lista todos los usuarios de la base de datos.
Para obtener los roles.
- dba_roles: lista los roles registrados en la base de datos.
Roles asignados a roles o usuarios.
- dba_role_privs: lista las asociaciones de los roles o usuarios de administrador con los roles que tienen
asignados.
- user_role_privs: lista las asociaciones del usuario actual con los roles que tiene asignado.
Privilegios asignados a roles o usuarios.
- dba_sys_privs: lista las asociaciones entre usuarios o roles con sus privilegios asignados.
Permisos sobre tablas asignados a roles o usuarios.
- dba_tab_privs: lista los permisos sobre tablas indicando el usuario, el permiso, quin lo concedi, etc.
Roles asignados a roles.
- role_role_privs: lista la asociacin entre roles y a que roles fueron asignados.
Privilegios de cada rol:
- role_sys_privs: lista las asociaciones entre roles y sus privilegios.
Lmites de recursos
- user_resource_limits: lista registros indicando por cada nombre de recursos si tiene limitaciones.
Perfiles y sus lmites de recursos asociados
- dba_profiles: lista las asociaciones entre perfiles, recursos y lmites.
Lmites de recursos en cuanto a restricciones en claves
- user_password_limits: lista registros indicando por cada recurso si tiene limitaciones de clave.
Lmites de recursos en cuanto a espacio mximo en tablespaces
- dba_ts_quotas: lista los tablespaces indicando los administradores y los lmites de espacio.
- user_ts_quotas: lista los tablespaces del usuario actual y los lmites de espacio.
4. Bases de datos virtuales privadas.
En el captulo previo se ha visto cmo usar vistas para establecer cierta seguridad a la hora de mostrar
registros que cumplan criterios especficos. En este captulo veremos cmo usar bases de datos virtuales
privadas (VPD) para proporcionar seguridad a nivel de registro a travs de las tablas de nuestra aplicacin. En
VPD podemos asociar polticas de seguridad directamente a tablas, vistas y sinnimos de forma que ningn
usuario podr saltarse los ajustes de seguridad.
En VPD, cualquier consulta usada para acceder a una tabla, vista o sinnimo protegido por las polticas de
VPS es modificado dinmicamente para incluir condiciones limitantes (una clusula WHERE o AND). La
modificacin ocurre transparentemente, y el usuario ver slo los datos que pasen la condicin limitante en la
clusula WHERE. Este acceso de grano fino permite un mayor control sobre los accesos a las tablas de nuestra

Oracle /181
aplicacin. Las polticas VPD pueden aplicarse a los comandos SELECT, INSERT, UPDATE, INDEX y DELETE. Se
pueden crear diferentes polticas de seguridad para cada uno de estos accesos.
Desde Oracle Database 10g, VPD se ha extendido para incluir VPD a nivel de columna, en las cuales las
polticas de seguridad se aplican slo cuando una determinada columna o columnas son accedidas. Oracle
Database 11g tambin soporta mscara de columna, con lo cual columnas protegidas pueden mostrar slo
valores nulos cuando se accede a los registros. Adems, las opciones de auditora se han mejorado, de forma
que los DBA's pueden realizar auditorias de grado fino para los comandos SELECT, INSERT, UPDATE y
DELETE.
4.1. Cmo implementar VPD a nivel de tabla.
VPD permite personalizar el modo en el que diferentes usuarios pueden ver la misma tabla.
Nota. El mecanismo para implementar VPD solo est disponible con la Enterprise Edition de
Oracle. Adems, VPD hace uso del paquete SYS.DBMS_RLS, el cual debera haber sido instalado
automticamente con el resto de paquetes predefinidos. Si no se pueden ejecutar los procedimientos
de este paquete debemos instalarlos personalmente. Para hacer esto debemos conectarnos como un
usuario privilegiado a una consola de SQL*Plus y ejecutar los siguientes archivos de script:
carpeta_instalacin_Oracle \Rdbms\Admin\dbmsrlsa.sql
carpeta_instalacin_Oracle \Rdbms\Admin\prvtrlsa.plb
4.1.1. Configuracin inicial.
Para seguir los ejemplos mostrados es este captulo se necesita acceder con una cuenta de SYSDBA privilegiada
(accediendo con el rol SYSDBA). VPD requiere el uso de un paquete llamado SYS.DBMS_RLS; desde la cuenta
SYSDBA privilegiada hay que conceder el permiso EXECUTE sobre el paquete SYS.DBMS_RLS a todos los
usuarios. Tambin hay que crear los usuarios que sern usados durante los ejemplo: Dora (que ser el
propietario de las tablas), Ana y Bob.
GRANT EXECUTE ON SYS.DBMS_RLS TO PUBLIC;
CREATE USER Ana IDENTIFIED BY contrasea;
CREATE USER Bob IDENTIFIED BY contrasea;
GRANT CREATE SESSION TO Ana, Bob;
Desde la cuenta SYSDBA privilegiada se crea al usuario Dora (si es que no existe todava), y se le dan los
permisos del sistema CREATE ANY CONTEXT y CREATE PUBLIC SYNONYM:
GRANT CREATE ANY CONTEXT, CREATE PUBLIC SYNONYM TO Dora;
Ahora crearemos dos tablas para el usuario Dora: la tabla STOCK_CUENTA y la tabla STOCK_TRX. La tabla
STOCK_CUENTA contendr un registro por cada cuenta que pueda realizar el seguimiento de stocks. La tabla
STOCK_TRX contendr un registro por cada stock vendido o comprado por el titular de la cuenta.
CONNECT Dora/contrasea
/
CREATE TABLE STOCK_CUENTA (
Cuenta NUMBER(10),
NombreCuenta VARCHAR2(50)
);
/
INSERT INTO STOCK_CUENTA VALUES (1234, 'Ana');
INSERT INTO STOCK_CUENTA VALUES (7777, 'Bob');
/
CREATE TABLE STOCK_TRX (
Cuenta NUMBER(10),
Simbolo VARCHAR2(20),
Precio NUMBER(6,2),
Cantidad NUMBER(6),
Trx_Flag VARCHAR2(1) /* C (comprada) o V (vendida) */
);
/
INSERT INTO STOCK_TRX VALUES (1234, 'ADSP', 31.75, 100, 'C');
INSERT INTO STOCK_TRX VALUES (7777, 'ADSP', 31.50, 300, 'V');
INSERT INTO STOCK_TRX VALUES (1234, 'ADSP', 31.55, 100, 'C');

Oracle /182
INSERT INTO STOCK_TRX VALUES (7777, 'OCKS', 21.75, 1000, 'C');
COMMIT;
Una vez creadas estas tablas concedemos permisos de acceso a Ana y Bob:
GRANT SELECT, INSERT ON STOCK_TRX TO Ana, Bob;
GRANT SELECT ON STOCK_CUENTA TO Ana, Bob;
Ahora ya tenemos la aplicacin configurada (en el esquema Dora, propietario de las tablas). Con esta
configuracin crearemos primero un contexto de aplicacin, tal como se muestra en la siguiente seccin.
4.1.2. Creacin de un contexto de aplicacin.
En siguiente paso en la configuracin VPD es crear un contexto de aplicacin. El propsito de este contexto
es definir las reglas que sern usadas por cada usuario. El contexto ser parte de cada caracterstica de sesin.
Primero se usa el comando CREATE CONTEXT para especificar el nombre del paquete que ser usado para
asignar las reglas:
CONNECT Dora/contrasea
CREATE CONTEXT Dora USING Dora.CONTEXT_PACKAGE;

Nota. Los contextos de aplicacin se crea a nivel de la base de datos, por tanto no pueden existir
dos contextos con el mismo nombre en una base de datos.
Ahora se crea el paquete con el nombre indicado (CONTEXT_PACKAGE). Este paquete consiste de un
procedimiento:
CREATE OR REPLACE PACKAGE CONTEXT_PACKAGE AS
PROCEDURE SET_CONTEXT;
END;
/
CREATE OR REPLACE PACKAGE BODY CONTEXT_PACKAGE IS
PROCEDURE SET_CONTEXT
IS
v_user VARCHAR2(30);
v_id NUMBER;
BEGIN
DBMS_SESSION.SET_CONTEXT('Dora','SETUP','TRUE');
v_user := SYS_CONTEXT('USERENV','SESSION_USER');
BEGIN
SELECT Cuenta INTO v_id FROM STOCK_CUENTA WHERE NombreCuenta = v_user;
DBMS_SESSION.SET_CONTEXT('Dora','USER_ID', v_id);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_SESSION.SET_CONTEXT('Dora','USER_ID', 0);
END;
DBMS_SESSION.SET_CONTEXT('Dora','SETUP','FALSE');
END SET_CONTEXT;
END CONTEXT_PACKAGE;
El corazn del cuerpo de este paquete es una sencilla consulta:
SELECT Cuenta INTO v_id FROM STOCK_CUENTA WHERE NombreCuenta = v_user;
La tabla STOCK_CUENTA contiene una registro por cada usuario ( Ana, Bob, y dems). Esta consulta toma el
nombre del usuario que se ha registrado y recupera el valor de su nmero de cuenta. Si el usuario no aparece
en la tabla se lanza una excepcin y se toma el valor 0. El valor de nmero de cuenta es asignado a una
variable de sesin denominada USER_ID:
DBMS_SESSION.SET_CONTEXT('Dora','USER_ID', v_id);
Podremos referenciar este valor de contexto en nuestros programas, y las restricciones VPD estarn basadas
en este valor de contexto.
Una vez creado el paquete, concedemos acceso pblico al mismo:
GRANT EXECUTE ON Dora.CONTEXT_PACKAGE TO PUBLIC;
/
CREATE PUBLIC SYNONYM CONTEXT_PACKAGE FOR Dora.CONTEXT_PACKAGE;
Las reglas para establecer el contexto de sesiones estn ahora listas para ser activadas, tal como se describe en
la siguiente seccin.

Oracle /183
4.1.3. Creacin de un trigger de registro.
Para poder asignar el contexto dentro de la sesin de cada usuario, debemos crear un trigger que ser
ejecutado cada vez un usuario se registre en la base de datos.
CREATE OR REPLACE TRIGGER Dora.SET_SECURITY_CONTEXT
AFTER LOGON ON DATABASE
BEGIN
Dora.CONTEXT_PACKAGE.SET_CONTEXT;
END;
Cada vez que un usuario se registre, Oracle ejecutar el procedimiento SET_CONTEXT dentro del paquete
CONTEXT_PACKAGE del usuario Dora. Este procedimiento consultar la tabla STOCK_CUENTA y ver si existe el
usuario; si es as, el contexto de sesin ser modificado para reflejar el valor de su nmero de cuenta.
Podemos probar que la configuracin establecida funciona bien consultando la funcin SYS_CONTEXT, tal
como se muestra a continuacin:
CONNECT Ana/contrasea
/
SELECT SYS_CONTEXT('USERENV', 'SESSION_USER') USUARIO,
SYS_CONTEXT('Dora', 'USER_ID') "NMERO CUENTA"
FROM DUAL;
El resultado de esta consulta debera ser el siguiente:
USUARIO NMERO CUENTA
-------------- -----------------------
ANA 1234
Con esta informacin podemos restringir el acceso a los registros en tablas basadas en este nmero de cuenta.
VPD permite restringir este acceso automticamente sin necesidad de crear vistas. Cada vez que un usuario
intente acceder a una de estas tablas, el acceso ser restringido independientemente de la herramienta usada
para el acceso. Si se registra un usuario no incluido en STOCK_CUENTA el nmero de cuenta ser asignado a
cero.
4.1.4. Creacin de polticas de seguridad.
Una vez creado un trigger de registro, para que el paquete de contexto tenga un efecto sobre la interaccin de
los usuarios con la base de datos, necesitamos crear un paquete de seguridad que acte sobre la salida del
paquete de contexto.
Primero se define la cabecera del paquete. En este ejemplo hay dos tipos de acciones soportadas para la tabla
STOCK_TRX (inserciones y selecciones), as que crearemos dos funciones dentro del paquete:
CONNECT Dora/contrasea
CREATE OR REPLACE PACKAGE SECURITY_PACKAGE AS
FUNCTION STOCK_TRX_INSERT_SECURITY(Propietario VARCHAR2, NombreObjeto VARCHAR2)
RETURN VARCHAR2;
FUNCTION STOCK_TRX_SELECT_SECURITY(Propietario VARCHAR2, NombreObjeto VARCHAR2)
RETURN VARCHAR2;
END SECURITY_PACKAGE;
Ahora se crea el cuerpo del paquete. Ambas funciones tiene el mismo patrn, dirigido a generar un predicado
que ser aplicado cada vez que un usuario consulte la tabla STOCK_TRX. Si el nombre de usuario de sesin es
el propietario de la tabla, entonces el predicado ser NULL. Para otros usuarios, se evala la variable de
contexto con el nmero de cuenta, y se pasa una condicin de limitacin a cualquier consulta. El objeto de
estas funciones es generar un predicado como WHERE Cuenta=1234 que ser aplicado cada vez que la tabla es
consultada.
CREATE OR REPLACE PACKAGE BODY SECURITY_PACKAGE IS
FUNCTION STOCK_TRX_SELECT_SECURITY(Propietario VARCHAR2, NombreObjeto VARCHAR2)
RETURN VARCHAR2
IS
Predicado VARCHAR2(2000);
BEGIN
IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'Dora') THEN
Predicado := NULL;
ELSE
Predicado := 'Cuenta = SYS_CONTEXT(''Dora'',''USER_ID'')';
END IF;

Oracle /184
RETURN Predicado;
END STOCK_TRX_SELECT_SECURITY;
FUNCTION STOCK_TRX_INSERT_SECURITY(Propietario VARCHAR2, NombreObjeto VARCHAR2)
RETURN VARCHAR2
IS
Predicado VARCHAR2(2000);
BEGIN
IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'Dora') THEN
Predicado := NULL;
ELSE
Predicado := 'Cuenta = SYS_CONTEXT(''Dora'',''USER_ID'')';
END IF;
RETURN Predicado;
END STOCK_TRX_INSERT_SECURITY;
END SECURITY_PACKAGE;
Ya que este paquete ser ejecutado por todos los usuario que tengan acceso a la tabla STOCK_TRX, se concede
el permiso de ejecutarlo, y se crea un sinnimo pblico.
GRANT EXECUTE ON Dora.SECURITY_PACKAGE TO PUBLIC;
/
CREATE PUBLIC SYNONYM SECURITY_PACKAGE FOR Dora.SECURITY_PACKAGE;
4.1.5. Aplicacin de la poltica de seguridad a las tablas.
Ahora que ya existe el paquete de seguridad, podemos relacionarlo con las tablas. Para aadir una poltica a
una tabla se usa el procedimiento ADD_POLICY del paquete SYS.DBMS_RLS, tal como se muestra a
continuacin:
BEGIN
SYS.DBMS_RLS.ADD_POLICY('Dora', 'STOCK_TRX', 'STOCK_TRX_INSERT_POLICY',
'Dora', 'SECURITY_PACKAGE.STOCK_TRX_INSERT_SECURITY', 'INSERT', TRUE);
SYS.DBMS_RLS.ADD_POLICY('Dora', 'STOCK_TRX', 'STOCK_TRX_SELECT_POLICY',
'Dora', 'SECURITY_PACKAGE.STOCK_TRX_SELECT_SECURITY', 'SELECT');
END;
El procedimiento ADD_POLICY es ejecutado dos veces. En la primera ejecucin, la funcin
STOCK_TRX_INSERT_SECURITY es especificada para ejecutarse durante el intento de insertar registros en la
tabla STOCK_TRX. En la segunda ejecucin, la funcin STOCK_TRX_SELECT_SECURITY es aplicada para
consultar la tabla STOCK_TRX. Podemos tener distintas reglas para asegurar diferentes operaciones sobre la
misma tabla. Las variables pasadas al procedimiento ADD_POLICY son el nombre de esquema, el nombre de la
tabla, un nombre para la poltica, el nombre del esquema y nombre de la funcin de seguridad, y la operacin
afectada.
4.1.6. Probando VPD.
Para ver los resultados de la poltica de seguridad, consultaremos la tabla. La tabla STOCK_TRX tiene cuatro
registros, dos para la cuenta Ana (1234) y dos para la cuenta Bob (7777). Registramos uno de estos usuarios y
consultamos la tabla:
CONNECT Ana/contrasea
/
SELECT * FROM Dora.STOCK_TRX;
El resultado ser:
CUENTA SIMBOLO PRECIO CANTIDAD TRX_FLAG
-------------- -------------- -------------- -------------- --------------
1234 ADSP 31,75 100 C
1234 ADSP 31,55 100 C
Aunque el usuario Ana no proporciona una clusula WHERE en su consulta, Oracle aplica un predicado a esta
consulta, limitando el resultado a las filas de la cuenta con valor 1234.
Si un usuario no incluido en la tabla STOCK_CUENTA intenta hacer una consulta sobre la tabla STOCK_TRX no
recibir ningn registro como resultado. Esto es as porque Oracle aplicar un predicado limitando los
resultados a las filas con la cuenta de valor 0.
Adems de las selecciones, las inserciones sern limitadas por la poltica de seguridad; un usuario slo podr
insertar filas dentro de la tabla STOCK_TRX si el valor de cuenta coincide con el contexto de usuario.

Oracle /185
4.2. Cmo implementar VPD a nivel de columna.
Desde Oracle Database 10g, podemos implementar VPD al nivel de columna. Si una columna con datos
sensibles es referenciada en una consulta, podemos aplicar una poltica de seguridad o mostrar la columna
con valores a NULL. En el VPD a nivel de columna se pueden mostrar todos los registros pero la columna
puede ser escudada para el usuario, por tanto es un mecanismo independiente del VPD a nivel de registro.
Podemos aplicar VPD a nivel de columna a una tabla o una vista.
Para usar VPD a nivel de columna debemos especificar un nombre de columna en el parmetro de entrada
sec_relevant_cols del procedimiento ADD_POLICY de SYS.DBMS_RLS. Si la poltica STOCK_TRX_SELECT_POLICY
no existe an, podemos usar el siguiente comando:
BEGIN
SYS.DBMS_RLS.ADD_POLICY (
object_schema=>'Dora',
object_name=>'STOCK_TRX',
policy_name=>'STOCK_TRX_SELECT_POLICY',
function_schema=>'Dora',
policy_function=>'SECURITY_PACKAGE.STOCK_TRX_SELECT_SECURITY',
sec_relevant_cols=>'Precio');
END;
Por defecto, los registros sern retornados segn la funcin de poltica de seguridad cuando la columna Precio
es referenciada por una consulta. Para usar la opcin de mscara sobre la columna, hay que decirle a Oracle
que retorne todos los registros asignando el parmetro sec_relevant_cols_opt a SYS.DBMS_RLS.ALL_ROWS,
seguido del parmetro sec_relevant_cols. Cuando se usa esta versin de la poltica, todos los registros sern
retornados por la consulta. Para las filas que el usuario no debera ser capaz de ver, la columna asegurada
mostrar valores nulos. El valor ser mostrado para los registros que el usuario pueda ver normalmente.
La mscara de columna se aplica slo sobre consultas, no sobre operaciones DML.
4.3. Cmo desactivar VPD.
Para quitar la funcionalidad VPD hay que dar marcha atrs a los pasos mostrados en este captulo. Quitar la
poltica de la tabla (a travs del procedimiento SYS.DBMS_RLS.DROP_POLICY), eliminar el trigger de registro, y
opcionalmente eliminar los otros paquetes.
Para eliminar una poltica se ejecuta el procedimiento DROP_POLICY. Tiene tres parmetros para el nombre del
esquema, el nombre del objeto, y el nombre de la poltica. El siguiente ejemplo elimina la poltica
STOCK_TRX_INSERT_POLICY:
SYS.DBMS_RLS.DROP_POLICY('Dora', 'STOCK_TRX', 'STOCK_TRX_INSERT_POLICY');
De forma similar, podemos eliminar la poltica STOCK_TRX_SELECT_POLICY:
SYS.DBMS_RLS.DROP_POLICY('Dora', 'STOCK_TRX', 'STOCK_TRX_SELECT_POLICY');
En este momento, las polticas son eliminadas, pero el trigger de registro seguir ejecutndose durante cada
registro de usuario. Podemos usar el comando DROP TRIGGER para eliminarlo, para que la base de datos no
tenga que realizar trabajos innecesarios.
4.4. Contenido del paquete SYS.DBMS_RLS.
El siguiente listado describe los procedimientos incluidos en el paquete SYS.DBMS_RLS.
Procedimiento Propsito
ADD_POLICY Aade una poltica a una tabla, vista o sinnimo.
DROP_POLICY Elimina una poltica de una tabla, vista o sinnimo.
REFRESH_POLICY Invalidad los cursores asociados con polticas no estticas.
ENABLE_POLICY Habilita (o deshabilita) una poltica previamente aadida a una tabla, vista o
sinnimo.
CREATE_POLICY_GROUP Crea una poltica de grupo.
ADD_GROUPED_POLICY Aade una poltica al grupo de polticas especificado.
ADD_POLICY_CONTEXT Aade el contexto para la aplicacin activa.
DELETE_POLICY_GROUP Elimina un grupo de polticas.
DROP_GROUPED_POLICY Elimina una poltica que es miembro del grupo especificado.
DROP_POLICY_CONTEXT Elimina el contexto de la aplicacin.
ENABLE_GROUPED_POLICY Habilita una poltica dentro de un grupo.
DISABLE_GROUPED_POLICY Deshabilita una poltica dentro de un grupo.

Oracle /186
REFRESH_GROUPED_POLICY Recompila el comando SQL asociado con una poltica refrescada.

4.5. Cmo usar grupos de polticas.


Podemos crear grupos de polticas, aadir polticas a un grupo, y habilitar polticas dentro de un grupo.
Podemos crear grupos que integren polticas que afecten a las mismas tablas. Si varias aplicaciones usan las
mismas tablas, podemos usar grupos para gestionar las polticas al nivel de tabla que deberan habilitarse
durante el uso de la aplicacin. Todas las polticas en el grupo pueden aplicarse en tiempo de ejecucin.
Por defecto, todas las polticas pertenecen al grupo SYS_DEFAULT. Las polticas del grupo SYS_DEFAULT
sern siempre ejecutadas dentro del grupo especificado en el contexto dado. No podemos eliminar el grupo
SYS_DEFAULT.
Para aadir un nuevo grupo de polticas se usa el procedimiento CREATE_POLICY_GROUP. Su sintaxis es:
SYS.DBMS_RLS.CREATE_POLICY_GROUP (
object_schema VARCHAR2,
object_name VARCHAR2,
policy_group VARCHAR2);
Podemos entonces aadir una poltica al grupo mediante el procedimiento ADD_GROUPED_POLICY. Su sintaxis
es:
SYS.DBMS_RLS.ADD_GROUPED_POLICY (
object_schema VARCHAR2,
object_name VARCHAR2,
policy_group VARCHAR2,
policy_name VARCHAR2,
function_schema VARCHAR2,
policy_function VARCHAR2,
statement_types VARCHAR2,
update_check BOOLEAN,
enabled BOOLEAN,
static_policy IN BOOLEAN FALSE,
policy_type IN BINARY_INTEGER NULL,
long_predicate IN BOOLEAN FALSE,
sec_relevant_cols IN VARCHAR2);
Por ejemplo,
podemos crear un grupo llamado TRXAUDIT, y entonces aadir la poltica
STOCK_TRX_SELECT_POLICY al grupo:
BEGIN
SYS.DBMS_RLS.CREATE_POLICY_GROUP('Dora','STOCK_TRX','TRXAUDIT');
SYS.DBMS_RLS.ADD_GROUPED_POLICY('Dora','STOCK_TRX','TRXAUDIT',
'STOCK_TRX_SELECT_POLICY', 'Dora', 'SECURITY_PACKAGE.STOCK_TRX_SELECT_SECURITY');
END;
Cuando la base de datos es accedida, la aplicacin inicializa el contexto conductor para especificar el grupo de
polticas a usar. En el comando CREATE CONTEXT se especifica el nombre del procedimiento a usar (para los
ejemplos previos, el contexto es asignado a travs del paquete Dora.CONTEXT_PACKAGE).
CREATE CONTEXT Dora USING Dora.CONTEXT_PACKAGE;
Dora.CONTEXT_PACKAGE ejecuta el procedimiento SET_CONTEXT para asignar el contexto de aplicacin:
DBMS_SESSION.SET_CONTEXT('Dora','SETUP','TRUE');
Para los grupos de polticas, el tercer parmetro pasado a SET_CONTEXT debe ser el nombre del grupo. Para
la aplicacin de ejemplo rescribiremos el paquete CONTEXT_PACKAGE para soportar un tercer valor de entrada
(grupo de polticas) y aadiremos al procedimiento SET_CONTEXT:
DBMS_SESSION.SET_CONTEXT('Dora','SETUP', policy_group);
Podemos eliminar una poltica del grupo mediante el procedimiento DROP_GROUPED_POLICY, desactivarla
mediante DISABLE_GROUPED_POLICY, o volver a activarla mediante ENABLE_GROUPED_POLICY.
Se usa DELETE_POLICY_GROUP para eliminar el grupo entero.
5. Trabajando con espacios de tabla.
En este captulo veremos los fundamentos del uso de tablespaces, as como los comandos necesarios para
crear y modificar tablespaces. Para estas dos operaciones es necesario tener permisos de administrador de
base de datos.

Oracle /187
5.1. Tablespaces y la estructura de las bases de datos.
La gente que trabaja con ordenadores est familiarizada con el concepto de un fichero; es un lugar en el disco
donde se almacena la informacin, y tiene un nombre. Su tamao no es normalmente fijo. Si aadimos
informacin a un fichero, ste puede aumentar ocupando ms espacio en disco, hasta el mximo posible. Este
proceso es gestionado por el sistema operativo, y normalmente involucra distribuir la informacin dentro del
fichero sobre varias pequeas secciones del disco que no necesariamente estn cerca una de otras. El sistema
operativo gestiona la conexin lgica entre estas pequeas secciones sin que tengamos que preocuparnos de
ello.
Oracle usa ficheros como parte de su esquema organizativo, pero su estructura lgica va ms all del
concepto de un fichero. Un fichero de datos (datafile) es un fichero del sistema operativo usado para guardar
datos de Oracle. Cada fichero de datos se asigna a un tablespace (una divisin lgica dentro de la base de
datos). Tablespaces incluidos normalmente en una base de datos son SYSTEM (para el diccionario de datos
interno de Oracle), SYSAUX (para objetos internos auxiliares), USERS (para los objetos de usuario), y otros
para las tablas de la aplicacin, los ndices y estructuras adicionales de la base de datos.
Los ficheros de datos pueden tener un tamao fijo o pueden asignarse para auto-extenderse cuando se llenen,
hasta un lmite definido. Para aadir ms espacio a un tablespace podemos extender manualmente nuestros
ficheros de datos o aadir nuevos ficheros de datos. Se aaden nuevos registros a tablas existentes, y estas
tablas pueden tener registros en varios ficheros de datos.
Cada tabla tiene una nica rea lgica de espacio en disco, llamada segmento, el cual pertenece a un nico
tablespace.
Cada segmento, a su vez, tiene un rea inicial de espacio en disco llamada extensin inicial. Una vez el
segmento ha ocupado su espacio se extiende a otra rea nica de espacio en disco.

5.1.1. Estructuras de Oracle.


La estructura lgica de Oracle est formada por:
Tablespaces Pertenecen slo a una base de datos y sirven para agrupar los datos de la base de datos.
Segmento Sirven para almacenar las estructuras lgicas de la base de datos (tablas, ndices, etc.).
Extensiones Divisin que se hace a cada segmento.
Bloque Oracle (O bloque de datos) Es la unidad mnima de datos para Oracle y se corresponde a una
o ms unidades de datos mnimas del sistema operativo en el que nos encontremos.
La estructura fsica est formada por:
Datafiles Son archivos en disco que sirven para almacenar los datos fsicamente (en una unidad
de disco). Cada archivo de datos pertenece slo a un tablespace. Su tamao se puede
gestionar.
Bloques La divisin mnima de los datos que hace el sistema operativo.
Concepto de tablespace.
Una base de datos se divide en unidades lgicas denominadas tablespaces. Un tablespace no es un fichero
fsico en el disco, simplemente es el nombre que tiene un conjunto de propiedades de almacenamiento que se
aplican a los objetos (tablas, ndices, secuencias, etc.) que se crean en la base de datos bajo el tablespace

Oracle /188
indicado. Un objeto de una base de datos debe estar almacenado obligatoriamente dentro de un tablespace.
Las propiedades que se asocian a un tablespace son:
Localizacin de los ficheros de datos.
Especificacin de las cuotas mximas de consumo de disco.
Control de la disponibilidad de los datos (en lnea o fuera de lnea).
Backup de datos.
Cuando un objeto se crea dentro de un cierto tablespace, este objeto adquiere todas las propiedades antes
descritas del tablespace utilizado.

En el esquema precedente podemos ver que, por ejemplo, la tabla ARTICULO se almacena dentro del
tablespace A, y que por lo tanto tendr todas las propiedades del tablespace A, que pueden ser:
Sus ficheros de datos estn en $ORACLE_HOME/datos/datos_tablespace_A.
Los objetos no pueden ocupar ms de 10Mb de espacio de base de datos.
En cualquier momento se puede poner fuera de lnea todos los objetos de un cierto tablespace.
Se pueden hacer copiar de seguridad slo de ciertos tablespaces.
Si nos fijamos, se puede apreciar que es posible tener una tabla en un tablespace, y los ndices de esa tabla en
otro tablespace. Esto es debido a que los ndices no son ms que objetos independientes dentro de la base de
datos, como lo son las tablas. Y al ser objetos independientes, pueden estar en tablespaces independientes.
En el esquema tambin vemos que hay un tablespace Temporal. Este tablespace representa las propiedades
que tendrn los objetos que la base de datos cree temporalmente para sus clculos internos (normalmente
para ordenaciones y agrupaciones). El tablespace RO difiere de los dems en que es un tablespace de solo
lectura (Read Only), y que por lo tanto todos los objetos en l contenidos pueden recibir rdenes de consulta
de datos, pero no de modificacin de datos. Estos tablespaces puede residir es soportes de slo lectura, como
pueden ser CDROM's, DVD's, etc. Cuando se crea un tablespace, ste se crea de lectura/escritura. Despus
se puede modificar para que sea de solo lectura.
Un tablespace puede estar en lnea o fuera de ella (Online u Offline), esto es, que el tablespace completo est
a disposicin de los usuarios o est desconectado para restringir su uso. Cualquier objeto almacenado dentro
de un tablespace no podr ser accedido si el tablespace est fuera de lnea.
Concepto de fichero de datos (datafile).
Un datafile es la representacin fsica de un tablespace. Son los "archivos de datos" donde se almacena la
informacin fsicamente. Un datafile puede tener cualquier nombre y extensin (siempre dentro de las
limitaciones del sistema operativo), y puede estar localizado en cualquier directorio del disco duro, aunque su
localizacin tpica suele ser CARPETA_DE_INSTALACIN_DE_ORACLE/Database.
Un datafile tiene un tamao predefinido en su creacin (por ejemplo 100Mb) y ste puede ser alterado en
cualquier momento. Cuando creamos un datafile, ste ocupa tanto espacio en disco como hayamos indicado
en su creacin, aunque internamente est vaco. Oracle hace esto para direccionar espacio continuo en disco y
evitar as la fragmentacin. Conforme se vayan creando objetos en ese tablespace, se ir ocupando el espacio
direccionado.
Un datafile est asociado a un solo tablespace y un tablespace est asociado a uno o varios datafiles.

Oracle /189
En el esquema previo podemos ver como el Tablespace A est compuesto (fsicamente) por tres datafiles
(DATOS_1.ORA, DATOS_2.ORA y DATOS_3.ORA). Estos tres datafiles son los ficheros fsicos que soportan los
objetos contenidos dentro del tablespace A.
Aunque siempre se dice que los objetos estn dentro del tablespace, en realidad las tablas estn dentro del
datafile, pero tienen las propiedades asociadas al tablespace. Cada uno de los datafiles utilizados est
ocupando su tamao en disco (50 Mb los dos primeros y 25 Mb el ltimo), aunque en realidad slo
contengan dos objetos y estos objetos no llenen el espacio que est asignado para los datafiles.
Los datafiles tienen una propiedad llamada AUTOEXTEND, que se si est activa se encarga de que el datafile
crezca automticamente (segn un tamao indicado) cada vez que se necesite espacio y no exista.
Al igual que los tablespaces, los datafiles tambin pueden estar en lnea o fuera de ella.
Concepto de Segmento.
Un segmento es aquel espacio lgico direccionado por la base de datos dentro de un datafile para ser utilizado
por un solo objeto. As, una tabla (o cualquier otro objeto) est dentro de su segmento, y nunca podr salir de
l, ya que si la tabla crece, el segmento tambin crece.
Fsicamente, todo objeto en base de datos no es ms que un segmento en un datafile. Se puede decir que un
segmento es a un objeto de base de datos, como un datafile a un tablespace: el segmento es la representacin
fsica del objeto en la base de datos (el objeto no es ms que una definicin lgica).

Podemos ver como el espacio que realmente se ocupa dentro del datafile es el segmento y que cada segmento
pertenece a un objeto.
Existen tres tipos de segmentos (principalmente):
- Segmentos de tipo TABLE: aquellos que contienen tablas.
- Segmentos de tipo INDEX: aquellos que contienen ndices.
- Segmentos de tipo ROLLBACK: aquellos se usan para almacenar informacin de la transaccin activa.
Concepto de extensin.
Para cualquier objeto de base de datos que tenga cierta ocupacin en disco, es decir, cualquier objeto que
tenga un segmento relacionado, existe el concepto de extensin. Extensin es un espacio de disco que se
direcciona de una sola vez, un segmento que se direcciona en un momento determinado de tiempo.
El concepto de extensin es un concepto fsico, unas extensiones estn separadas de otras dentro del disco.
Ya dijimos que todo objeto tiene su segmento asociado, pero lo que no dijimos es que este segmento, a su
vez, se compone de extensiones. Un segmento, puede ser direccionado de una sola vez (10 Mb de golpe), o
de varias veces (5 Mb hoy y 5 Mb maana). Cada uno de las veces que se direcciona espacio se denomina
extensin.

Oracle /190
En el esquema vemos como el objeto (tabla) FACTURA tiene un segmento en el datafile A-1, y este segmento
est compuesto de 3 extensiones. Una de estas extensiones tiene un color distinto. Esto es porque existen dos
tipos de extensiones:
- INITIAL (extensiones iniciales): estas son las extensiones que se direccionan en el momento de la
creacin del objeto. Una vez que un objeto est creado, no se puede modificar su extensin inicial.
- NEXT (siguientes o subsiguientes extensiones): toda extensin direccionada despus de la creacin del
objeto. Si la INITIAL EXTENT de una tabla est llena y se est intentando insertar ms filas, se intentar
crear una NEXT EXTENT (siempre y cuando el datafile tenga espacio libre y tengamos cuota de ocupacin
suficiente).
Sabiendo que las extensiones se crean en momentos distintos de tiempo, es lgico pensar que unas
extensiones pueden estar fragmentadas de otras. Un objeto de base de datos no reside todo junto dentro del
bloque, sino que residir en tantos bloque como extensiones tenga. Por eso es crtico definir un buen tamao
de extensin inicial, ya que, si es lo suficientemente grande, el objeto nunca estar desfragmentado.
Si el objeto tiene muchas extensiones y stas estn muy separadas en disco, las consultas pueden retardarse
considerablemente, ya que las cabezas lectoras tienes que dar saltos constantemente. El tamao de las
extensiones (tanto las INITIAL como las NEXT), se definen durante la creacin del objeto y no puede ser
modificado despus de la creacin.
Oracle recomienda que el tamao del INITIAL EXTENT sea igual al tamao del NEXT EXTENT.
Concepto de bloque de datos.
Un bloque de datos es el ltimo eslabn dentro de la cadena de almacenamiento. El concepto de bloque de
datos es un concepto fsico, ya que representa la mnima unidad de almacenamiento que es capaz de manejar
Oracle. Igual que la mnima unidad de almacenamiento de un disco duro es la unidad de asignacin, la
mnima unidad de almacenamiento de Oracle es el bloque de datos.
En un disco duro no es posible que un fichero pequeo ocupe menos de lo que indique la unidad de
asignacin, as si la unidad de asignacin es de 4 Kb, un fichero que ocupe 1 Kb, en realidad ocupa 4 Kb.
Siguiendo con la cadena, cada segmento (o cada extensin) se almacena en uno o varios bloques de datos,
dependiendo del tamao definido para la extensin, y del tamao definido para el bloque de datos.
El tamao de las unidades de asignacin del SO se define durante el particionado del disco duro (mediante las
herramientas FDISK, FIPS, etic.), y el espacio de los bloques de datos de Oracle se define durante la
instalacin y no puede ser cambiado.
Como es lgico, el tamao de un bloque de datos tiene que ser mltiplo del tamao de una unidad de
asignacin, es decir, si cada unidad de asignacin ocupa 4 K, los bloques de datos pueden ser de 4K, 8K,
12K para que en el SO ocupen 1, 2, 3 unidades de asignacin.
5.1.2. Contenido de los tablespace.
Podemos consultar la vista del diccionario de datos USER_TABLESPACES para ver los tablespaces disponibles
en la base de datos. Los tablespace son creados por usuarios con permisos mediante el comando CREATE
TABLESPACE. La sintaxis ms simple de este comando es:
CREATE TABLESPACE nombre_tablespace DATAFILE nombre_datafile tamao_fichero ;
Los administradores de base de datos especifican el mtodo de asignacin de espacio del tablespace cuando lo
crean. El siguiente ejemplo crea un tablespace donde el espacio inicial es de 100MB, pero este fichero puede
extenderse automticamente si es necesario:
CREATE TABLESPACE Users_2
DATAFILE '/U01/ORADATA/Users_2_01.dbf'
SIZE 100M AUTOEXTEND ON;
Podemos especificar tambin ms de un fichero de datos en la creacin del tablespace. Por ejemplo:
CREATE TABLESPACE Users_3

Oracle /191
DATAFILE '/U01/ORADATA/Users_3_01.dbf' SIZE 100M,
'/U01/ORADATA/Users_3_02.dbf' SIZE 250M;
Al crearse el tablespace tambin se crean los ficheros de datos especificados.
La columna Contents de la vista USER_TABLESPACES muestra el tipo de los objetos soportados en cada
tablespace. Lo siguiente muestra un listado de ejemplo para una instalacin en Oracle Database 11g:
SELECT TABLESPACE_NAME, CONTENTS FROM USER_TABLESPACES;
TABLESPACE_NAME CONTENTS
-------------------------- ------------------
SYSTEM PERMANENT
UNDOTBS1 UNDO
SYSAUX PERMANENT
TEMP TEMPORARY
USERS PERMANENT
En este ejemplo, los tablespace SYSTEM, SYSAUX y USERS soportan objetos permanentes (tablas, ndices y
otros objetos de usuario). El tablespace TEMP soporta slo segmentos temporales (segmentos creados y
gestionados por Oracle para soportar operaciones de ordenacin). El tablespace UNDOTBS1 soporta
administracin de segmentos de deshacer.
Cuando creamos una tabla sin especificar un tablespace, la tabla ser almacenada en nuestro tablespace por
defecto. Podemos ver el tablespace por defecto mediante la vista del diccionario de datos USER_USERS:
SELECT DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE FROM USER_USERS;
DEFAULT_TABLESPACE TEMPORARY_TABLESPACE
----------------------------- ---------------------------------
USERS TEMP
En este ejemplo, el tablespace por defecto es USERS y el tablespace temporal es TEMP. Estas asignaciones
pueden ser modificadas mediante el comando ALTER USER.
Aunque USERS es nuestro tablespace por defecto, podemos no tener ninguna cuota en el tablespace. Para ver
cunto espacio tenemos concedido en un tablespace podemos consultar la vista USER_TS_QUOTAS, tal como
se muestra a continuacin:
SELECT * FROM USER_TS_QUOTAS;
TABLESPACE_NAME BYTES MAX_BYTES BLOCKS MAX_BLOCKS
-------------------------- ----------- ---------------- ----------- ------------------
USERS 131072 -1 16 -1
En este caso, los valores MAX_BYTES y MAX_BLOCKS (el espacio mximo que podemos usar) est asignados a
1. Si este valor es negativo quiere decir que no tenemos lmites en la cuota del tablespace. En este ejemplo, el
usuario slo tiene 16 bloques en 131.072 bytes. Ya que un 1KB son 1.024 bytes, el usuario tiene 128KB
asignados en el tablespace USERS.
El espacio en los tablespace puede gestionarse localmente. Y como alternativa, el espacio puede ser
gestionado por diccionario (los registros de gestin de espacio son mantenidos en el diccionario de datos). En
general, la gestin local de tablespaces es sencilla de administrar. Podemos mostrar el tipo de gestin
mediante la columna Extent_Management de la vista USER_TABLESPACES:
SELECT TABLESPACE_NAME, EXTENT_MANAGEMENT FROM USER_TABLESPACES;
TABLESPACE_NAME EXTENT_MAN
--------------------------- ---------------------
SYSTEM LOCAL
UNDOTBS1 LOCAL
SYSAUX LOCAL
TEMP LOCAL
USERS LOCAL
En un tablespace gestionado localmente, el mapa de espacio para el tablespace se mantiene en las cabeceras
de los ficheros de datos del tablespace. Para ver los ficheros de datos asignados al tablespace, el administrador
de la base de datos puede consultar la vista DBA_DATA_FILES del diccionario de datos; no hay una vista
equivalente para usuarios sin permisos.
Los valores por defecto para almacenar son especficos del sistema operativo. Podemos consultar la vista
USER_TABLESPACES para ver el tamao de bloque y los tamaos por defecto para la extensin inicial, el

Oracle /192
tamao de la siguiente extensin, el nmero mnimo de extensiones, el nmero mximo nmero de
extensiones y el incremento para los objetos.
SELECT Tablespace_Name, Block_Size, Initial_Extent, Next_Extent,
Min_Extents, Max_Extents, Pct_Increase
FROM USER_TABLESPACES;
Para sobrescribir los valores por defecto podemos usar la clusula STORAGE cuando creamos una tabla o
ndice. El siguiente ejemplo aplica todas las opciones de almacenamiento al crear una tabla.
CREATE TABLE Test1 (...)
TABLESPACE Users_2
STORAGE ( INITIAL 20K NEXT 30K MINEXTENTS 1 MAXEXTENTS 10
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
OPTIMAL 7K BUFFER_POOL DEFAULT);
A menos que haya objetos con requerimientos de espacio extraordinarios, deberamos evitar tamaos
personalizados para cada una de nuestras tablas o ndices. Si no especificamos una clusula STORAGE cuando
creamos un objeto, se usarn los valores por defecto de su tablespace. Si no especificamos una clusula
TABLESPACE, el objeto ser almacenado en el tablespace por defecto.
Podemos consultar el espacio libre en un tablespace mediante la vista USER_FREE_SPACE del diccionario de
datos. USER_FREE_SPACE mostrar una fila por cada extensin libre dentro del tablespace, as como su exacta
localizacin y longitud.
5.1.3. Espacio de RECYCLEBIN en los tablespaces.
Desde Oracle Database 10g, los objetos borrados no liberan su espacio asignado a menos que especifiquemos
la clusula PURGE cuando los borramos con el comando DROP. Por defecto, los objetos mantienen su espacio,
permitiendo que ms tarde los recuperemos mediante el comando FLASHBACK TABLE TO BEFORE DROP.
El espacio actualmente usado por los objetos borrados es registrado en cada vista RECYCLEBIN del usuario (o,
para el DBA, la vista DBA_RECYCLEBIN). Podemos ver cmo se utilizan muchos bytes en cada tablespace, y
entonces usar el comando PURGE para purgar las entradas antiguas desde el RECYCLEBIN. Aqu hay un
ejemplo:
SELECT SPACE --nmero de bloque todava asignados
FROM RECYCLEBIN
WHERE TS_NAME = 'USERS';
5.1.4. Tablespaces de solo-lectura.
Los DBA's pueden modificar un tablespace mediante el comando ALTER TABLESPACE. Los tablespaces se
pueden modificar para ser de solo lectura:
ALTER TABLESPACE USERS READ ONLY;
O pueden ser modificados para ser de solo escritura:
ALTER TABLESPACE USERS READ WRITE;
Los datos de un tablespace de solo lectura no pueden ser modificados. Aunque los usuarios sin permisos no
pueden ejecutar estos comandos, deberamos ser conscientes de que ellos pueden cambiar cmo se
almacenan fsicamente nuestros datos. Si podemos mover los datos que no cambian a nuestro propio
tablespace, podemos designar el tablespace entero como de slo lectura. La utilizacin de tablespaces de slo
lectura simplifica el esfuerzo de copias de respaldo y recuperacin.
Nota. Podemos borrar objetos en un tablespace de solo lectura.
El estado de slo lectura de los tablespaces se muestra mediante la columna Status de la vista
USER_TABLESPACES del diccionario de datos, tal como se muestra en el siguiente ejemplo:
ALTER TABLESPACE USERS READ ONLY;
/
SELECT Status FROM USER_TABLESPACES WHERE Tablespace_Name = 'USERS';
STATUS
----------------
READ ONLY
ALTER TABLESPACE USERS READ WRITE;
/
SELECT Status FROM USER_TABLESPACES WHERE Tablespace_Name = 'USERS';
STATUS

Oracle /193
----------------
ONLINE
5.1.5. Tablespaces nologging.
Podemos desactivar la creacin de entradas en el registro de deshacer para objetos especficos. Por defecto,
Oracle genera entradas en el registro para todas las transacciones. Si queremos saltarnos esta funcionalidad
(imaginemos que estamos cargando datos y podemos recrearlos completamente para todas las transacciones)
podemos especificar que la carga de objetos o el tablespace se mantenga en modo "nologging".
Podemos ver el estado de "logging" actual de un tablespace consultando la columna Logging de la vista
USER_TABLESPACES.
El siguiente ejemplo crea un tablespace en modo "logging" y despues lo modifica al modo "nologging":
CREATE TABLESPACE TS1 DATAFILE 'C:/OraData/Users_01.dbf' SIZE 10M LOGGING;
/
ALTER TABLESPACE TS1 NOLOGGING;
5.1.6. Tablespaces temporales.
Cuando ejecutamos un comando que realiza una operacin de ordenacin o agrupacin, Oracle puede crear
un segmento temporal para gestionar los datos. El segmento temporal es creado dentro de un tablespace
temporal, y el usuario que ejecuta el comando no tiene que administrar estos datos. Oracle crear
dinmicamente el segmento temporal y liberar su espacio cuando la instancia finalice o se reinicie. Si no hay
espacio libre disponible y los ficheros de datos del tablespace temporal no puede auto-extenderse, el comando
fallar. Cada usuario de la base de datos tiene asociado un tablespace temporal (puede haber un nico
tablespace compartido para todos los usuarios). Un tablespace temporal se asigna al nivel de base de datos, as
que todos los nuevos usuarios tendrn el mismo tablespace temporal a no ser que se especifique uno
diferente durante el comando CREATE USER o ALTER USER.
Desde Oracle Database 10g, podemos crear varios tablespaces temporales y agruparlos. Se asignan
tablespaces temporales a un grupo mediante la clusula TABLESPACE GROUP del comando CREATE TEMPORARY
TABLESPACE o ALTER TABLESPACE. Podemos entonces especificar el grupo como tablespace por defecto de
usuario. Los grupos de tablespaces pueden ayudarnos a soportar operaciones en paralelo para ordenaciones.
El siguiente ejemplo crea dos tablespaces dentro del mismo grupo:
CREATE TEMPORARY TABLESPACE TS_1
DATAFILE 'D:\TEMP\TEmp_01.dbf' SIZE 10M
TABLESPACE GROUP TSGrupo1;
/
CREATE TEMPORARY TABLESPACE TS_2
DATAFILE 'D:\TEMP\TEmp_02.dbf' SIZE 15M
TABLESPACE GROUP TSGrupo1;
5.1.7. Tablespaces para el sistema de deshacer.
Podemos usar la gestin automtica de deshacer (Automatic Undo Management, AUM) para poner todos los
datos de deshacer dentro de un mismo tablespace. Cuando creamos una tablespace de deshacer, Oracle
gestiona el almacenamiento, retencin y utilizacin del espacio para que podamos recuperar los datos.
Cuando se asigna un tiempo de retencin (en el fichero de parmetros de inicializacin de la base de datos),
Oracle har el mejor esfuerzo para retener todos los datos de deshacer confirmados en la base de datos
durante el nmero de segundos especificados. Con esta asignacin, cualquier consulta que tome menos
tiempo que el tiempo de retencin no debera causar un error si el tablespace de deshacer tiene el tamao
apropiado. Mientras la base de datos esta ejecutndose, los DBA's pueden cambiar el valor del parmetro
UNDO_RETENTION mediante el comando ALTER SYSTEM:
ALTER SYSTEM SET UNDO_RETENTION = 60;
Desde Oracle Database 10g, podemos garantizar que los datos de deshacer son retenidos, an sobre el costo
de las transacciones actuales en la base de datos. Cuando creamos el tablespace de deshacer debemos
especificar RETENTION GUARANTEE como parte de nuestro comando CREATE DATABASE o CREATE UNDO
TABLESPACE. Debemos tener cuidado con esta opcin, porque podemos forzar que las transacciones fallen
para garantizar la retencin de antiguos datos de deshacer en el tablespace de deshacer.
5.1.8. Soporte de FLASHBACK DATABASE.
Desde Oracle Database 10g, podemos usar el comando FLASHBACK DATABASE para revertir una base de
datos entera a un punto anterior del tiempo. Los DBA's pueden configurar los tablespaces para excluirlos de
esta opcin (el comando ALTER TABLESPACE FLASHBACK OFF le dice a Oracle que excluya la escritura de los

Oracle /194
datos modificados despus de una transaccin al rea de base de datos flashback). Por ejemplo podemos
hacer esto con el tablespace USER_1:
ALTER TABLESPACE USER_1 FLASHBACK OFF;
5.1.9. Tablespaces transportables.
Un tablespace transportable puede ser "despegado" de una base de datos y "pegado" en otra base de datos.
Para ser transportable, un tablespace (o un conjunto de tablespaces) debe ser auto-contenido. El conjunto de
tablespaces no puede contener ningn objeto que referencie otros objetos en otros tablespaces. Por lo tanto,
si transportamos un tablespace que contenga ndices, debemos mover el tablespace que contiene las tablas
bases de los ndices como parte del mismo conjunto de tablespaces transportables. Lo mejor es tener
organizados y distribuidos nuestros objetos en tablespaces, as ser fcil generar un conjunto auto-contenido
de tablespaces para transportar.
Para transportar tablespaces necesitamos genera un conjunto de tablespaces, copiar y mover este conjunto a
la nueva base de datos, y pegar el conjunto en la nueva base de datos. Ya que esto implica operaciones con
permisos debemos ser administradores privilegiados para ejecutarlas. Por ejemplo, podemos crear y poblar un
tablespace de slo lectura con datos histricos en un entorno de prueba y luego transportarlo a una base de
datos de produccin, an entre plataformas.
Cmo generar un conjunto de tablespaces transportables.
Un conjunto de tablespaces transportables contiene todos los ficheros de datos de los tablespaces que sern
movidos, as como una exportacin de los metadatos de estos tablespaces. Podemos opcionalmente elegir si
incluiremos restricciones de integridad referencial como parte del conjunto transportable. Si elegimos esta
opcin el conjunto de tablespaces transportables se incrementar para incluir las tablas requeridas para
mantener las claves relacionadas. La integridad referencial es opcional porque podemos tener las mismas
tablas de cdigo en varias bases de datos. Por ejemplo, podemos mover un tablespace desde una base de
datos de prueba a una base de datos de produccin. Si tenemos una tabla PAISES en la base de datos de
prueba, entonces podemos tener tambin una tabla PAISES idntica en la base de datos de produccin. Si las
tablas de cdigos son idnticas en las dos bases de datos, no necesitamos transportar esta parte de las
restricciones de integridad referencial. Podemos transportar el tablespace y entonces re-ensamblar la
integridad referencial en la base de datos destino sobre el tablespace que ha sido movido, simplificando as la
creacin del conjunto transportable.
Para determinar si un conjunto de tablespaces es auto-contenido, se puede ejecutar el procedimiento
DBMS_TTS.TRANSPORT_SET_CHECK. Este procedimiento toma dos parmetros de entrada: el conjunto de
tablespaces y un modificador booleano asignado a TRUE si queremos considerar la integridad referencial.
Nota. Solo los usuarios con el rol EXECUTE_CATALOG_ROLE pueden ejecutar este procedimiento.
Este rol solo es asignado inicialmente al usuario SYS.
En el siguiente ejemplo, no se considera la integridad referencial para la combinacin de los tablespaces
AGG_DATA y AGG_INDEXES:
EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('AGG_DATA,AGG_INDEXES', FALSE);

Nota. No podemos transportar los tablespaces SYSTEM, SYSAUX o los temporales.


Si hay cualquier violacin de auto-contencin en el conjunto especificado, Oracle poblar la vista
TRANSPORT_SET_VIOLATIONS del diccionario de datos. Si no hay violaciones la vista estar vaca.
Una vez seleccionado un conjunto auto-contenido, haremos los tablespaces de solo lectura, tal como se
muestra a continuacin:
ALTER TABLESPACE AGG_DATA READ ONLY;
ALTER TABLESPACE AGG_INDEXES READ ONLY;
A continuacin, exportamos los metadatos para los tablespaces, usando los parmetros de exportacin
TRANSPORT_TABLESPACE y TABLESPACES con la herramienta EXP:
EXP USERID=usuarioPrivilegiado/contrasea TRANSPORT_TABLESPACE=Y
TABLESPACES=(AGG_DATA,AGG_INDEXES) CONSTRAINTS=N GRANTS=Y TRIGGERS=N

Nota. Para conectarnos como SYSDBA, podemos no especificar el usuario en la lnea de comandos,
y cuando se solicite el usuario debemos entrar / AS SYSDBA.
Como se muestra en este ejemplo, podemos especificar si los triggers, restricciones y permisos son
exportados con los metadatos de los tablespaces. Ahora podemos copiar los ficheros de datos de los

Oracle /195
tablespaces a un rea independiente. Si es necesario podemos reponer los tablespaces en el modo lectura-
escritura en su base de datos actual.
Despus de haber generado el conjunto de tablespaces transportables, podemos mover sus ficheros
(incluyendo la exportacin) a un rea a la cual pueda acceder la base de datos destino.
Cmo pegar el conjunto de tablespaces transportable.
Una vez que el conjunto transportable ha sido movido a un rea accesible desde la base de datos destino,
podemos pegar el conjunto dentro de la base de datos destino. Primero se usa la herramienta de importacin
IMP para importar los metadatos exportados:
IMP TRANSPORT_TABLESPACE=Y DATAFILES=(AGG_DATA.DBF, AGG_INDEXES.DBF)
En la importacin debemos especificar los ficheros de datos que son parte del conjunto transportable.
Podemos opcionalmente especificar los tablespaces (mediante el parmetro TABLESPACES) y los propietarios
de los objetos (mediante el parmetro OWNERS).
Despus de que la importacin se complete, todos los tablespaces en el conjunto transportable son dejados
en el modo de solo lectura. Podemos utilizar el comando ALTER TABLESPACE READ WRITE para cambiar este
modo.
ALTER TABLESPACE AGG_DATA READ WRITE;
ALTER TABLESPACE AGG_INDEXES READ WRITE;
Ntese que no podremos cambiar el propietario de los objetos transportados. Los tablespaces transportables
soportan movimiento muy rpido de grandes conjuntos de datos.
Nota. Desde Oracle Database 10g, los sistemas operativos origen y destino pueden ser diferentes.
Los ficheros de datos sern convertidos mediante el comando de RMAN CONVERT TABLESPACETO
PLATAFORM.

5.2. Planificando el uso de nuestro tablespace.


Con todas las opciones vistas previamente, Oracle puede soportar entornos muy complejos. Podemos
mantener conjunto de solo lectura de tablas de datos histricas junto a tablas de transacciones activas.
Podemos poner las tablas ms usada en ficheros de datos localizados en los discos ms rpidos. Podemos
particionar tablas y almacenar cada particin en tablespaces distintos. Con todas estas opciones disponibles
deberamos establecer unas reglas bsicas para nuestra arquitectura de tablespaces. Este plan debera ser parte
de nuestro esfuerzo inicial de diseo y as aprovecharnos de las ventajas de estas funcionalidades disponibles.
5.2.1. Separar tablas de actividad y estticas.
Las tablas activamente usadas por transacciones tienen consideraciones de espacio que difieren
significativamente de las tablas estadsticas de consulta. Las tablas estticas puede que nunca sean modificadas
o movidas; las tablas de actividad pueden necesitar ser administradas activamente, movidas o reorganizadas.
Para simplificar la administracin de las tablas estticas podemos aislarlas en tablespaces dedicados. Dentro
de las tablas ms activas puede haber divisiones remotas (alguna de ellas puede ser extremadamente crtica
para el rendimiento de la aplicacin, y podemos decidir moverlas a otro tablespace).
Llevando este acercamiento un poco ms lejos, podemos separar las particiones activas y estticas de tablas e
ndices. Idealmente, esta separacin nos permitir enfocar nuestros esfuerzos sobre los objetos que tengan un
impacto ms directo sobre el rendimiento mientras eliminamos el impacto de uso de otros objetos sobre el
entorno inmediato.
5.2.2. Separar ndices y tablas.
Los ndices pueden ser administrados separadamente de las tablas (podemos crear o borrar ndices mientras la
tabla base permanece sin cambiar). Debido a que sus espacios son administrados independientemente, los
ndices deben ser almacenados en tablespaces dedicados. Entonces deberamos ser capaces de crear y
reconstruir ndices sin preocuparnos del impacto de estas operaciones sobre el espacio disponible en nuestras
tablas.
5.2.3. Separar objetos grandes y pequeos.
En general, las tablas pequeas tienden a ser tablas estticas de consulta (como una lista de pases, por
ejemplo). Oracle proporciona opciones para afinar tablas pequeas (como una cach) que no son apropiadas
para tablas grandes (las cuales tienen su propio conjunto de opciones). Ya que los administradores de estos
tipos de tablas pueden ser muy diferentes, deberamos intentar separarlas. En general, separar tablas activas y
estticas tendr en cuenta tambin este objetivo.
5.2.4. Separar tablas de aplicacin de objetos principales.
Los dos conjuntos de objetos principales de los que tenemos que ser consciente son los objetos

Oracle /196
fundamentales de Oracle y los objetos del negocio. Los objetos fundamentales de Oracle se almacenan en los
tablespaces por defecto (SYSTEM, SYSAUX, los tablespaces temporales y los tablespaces de deshacer). No
debemos crear ningn objeto de la aplicacin en estos tablespaces o bajo ningn esquema proporcionado con
Oracle.
Dentro de nuestra aplicacin podemos tener algunos objetos que son fundamentales para el negocio y
pueden ser reutilizados por varias aplicaciones. Ya que estos objetos pueden necesitar ser indexados y
gestionados en cuentas para las necesidades de varias aplicaciones, deberan mantenerse aparte de otros
objetos de nuestra aplicacin.
Agrupando los objetos en la base de datos de acuerdo a las categoras descritas aqu pueden verse muy
simplista, pero es una parte crtica para el despliegue sucesivo de una aplicacin de base de datos escalable. Lo
mejor es planificar la distribucin del espacio en discos, para que sea ms sencilla la implementacin, afinado
y administracin de las estructuras de base de datos. Adems, los administradores de base de datos pueden
gestionar los tablespaces separadamente (usndolos fuera de lnea, respaldndolos, o aislndolos en sus
actividades de entrada-salida).
6. Usar SQL*Loader para cargar datos
En vez de usar comandos INSERT para insertar datos en las tablas, podemos crear un fichero que contenga
los datos y utilizar la utilidad SQL*Loader para cargar los datos.
SQL*Loader carga datos desde archivos externos dentro de tablas de Oracle. SQL*Loader usa dos ficheros
principales: un fichero de datos, el cual contiene la informacin de los datos a cargar, y un fichero de control,
el cual contiene informacin del formato de los datos, los registros y campos dentro del fichero, el orden en
el cual deben ser cargados, y si es necesario, los nombres de los diversos ficheros que sern usados para datos.
Podemos combinar la informacin del fichero de control dentro del fichero de datos mismo, aunque
normalmente son dos ficheros separados para hacer ms fcil reutilizar el fichero de control.
Cuando se ejecuta, SQL*Loader crear automticamente un fichero de log y un fichero "malo" (bad). El
fichero de log registra el estado de la carga, como el nmero de registros procesados y el nmero de registros
aceptados. El fichero "malo" contendr todos los registros que fueron rechazados durante la carga debido a
errores de los datos, como valores repetidos en columnas de clave primaria.
Dentro del fichero de control podemos especificar comandos adicionales para gobernar el criterio de carga. Si
estos criterios no son cumplidos por una fila, la fila ser escrita a un archivo de "descarte". Los ficheros de
log, "malo" y de "descarte" tienen la extensin .log, .bad, y .dsc, respectivamente. Los ficheros de control
tienen normalmente la extensin .ctl.
SQL*Loader es una potente herramienta para cargar datos por varias razones:
Es altamente flexible, permitiendo manipular los datos que estn siendo cargados.
Podemos usar SQL*Loader para romper un nico dato grande dentro de varios conjuntos de datos
durante el proceso de validacin, reduciendo as significativamente el tamao del proceso de transaccin.
Podemos usar la opcin de carga Direct Path para realizar cargas muy rpidas.
6.1. El fichero de control.
El fichero de control le dice a Oracle cmo leer y cargar los datos. El fichero de control le dice a SQL*Loader
dnde encontrar los datos de origen para la carga y las tablas dentro de las cuales cargar los datos, adems de
cualquier otra regla que debamos aplicar durante el proceso de carga. Estas reglas pueden incluir restricciones
para descartar (similares a la clusula WHERE de las consultas) e instrucciones para combinar varias filas fsicas
de un archivo de entrada en una nica fila durante una insercin. SQL*Loader usar el fichero de control para
crear los comandos de insercin ejecutados para cargar los datos.
El fichero de control es creado al nivel de sistema operativo, usando un editor de texto que permita guardar
archivos de texto plano. Dentro del fichero de control los comandos no tienen que tener ningn
requerimiento de formato rgido, pero estandarizando la sintaxis de nuestros comandos permitir ms tarde el
mantenimiento del fichero de control.
El listado siguiente muestra un ejemplo de fichero de control para cargar datos dentro de una tabla LIBRO:
LOAD DATA
INFILE 'libros.dat'
INTO TABLE LIBRO
(Codigo POSITION(01:03) INTEGER EXTERNAL,
Titulo POSITION(05:100) CHAR "LTRIM(RTRIM(:Titulo))",

Oracle /197
Autor POSITION(101:120) CHAR "LTRIM(RTRIM(:Autor))",
Categoria POSITION(121:140) CHAR "LTRIM(RTRIM(:Categoria))")
En este ejemplo, los datos son cargados desde un fichero llamado libros.dat dentro de la tabla LIBRO. El
fichero libros.dat contiene los datos de las cuatro columnas de la tabla LIBRO distribuidos por lneas, con
espacios en blanco necesarios para que cada columna comience en una posicin determinada de cada lnea.
De esta forma, la columna Autor siempre comenzar en la posicin 101 de cada lnea, incluso si el valor de
Titulo tiene menos de 100 caracteres. Aunque este formato provoca un archivo grande, puede simplificar el
proceso de carga. No hay que dar ninguna longitud para los campos, la posicin inicial y final de cada
columna determina la longitud mxima de cada campo.
La clusula INFILE determina el nombre del fichero de datos, y la clusula INTO TABLE especifica la tabla
dentro de la cual se cargarn los datos. En este ejemplo, cada columna es listada teniendo en cuenta la
posicin donde residen los datos en cada registro fsico del fichero. Este formato permite cargar datos aunque
las columnas de datos del origen no casen en el orden de las columnas de la tabla. Adems, en este ejemplo se
normalizan los datos eliminando los espacios en blancos innecesarios (mediante las funciones LTRIM y
RTRIM).
Los tipos de datos que podemos especificar son:
CHAR
VARCHAR
VARCHARC
DATE
EXTERNAL INTEGER
EXTERNAL FLOAT
EXTERNAL DECIMAL
EXTERNAL ZONED
Para realizar la carga, el usuario que la ejecute debe tener el permiso INSERT sobre la tabla LIBRO.
6.1.1. Cargando datos de longitud variable.
Si las columnas de nuestro fichero de entrada tienen longitudes variables, podemos usar los comandos de
SQL*Loader para decirle a Oracle cmo determinar cundo acaba un valor. En el siguiente ejemplo se usan
comas para separar los datos de entrada:
LOAD DATA
INFILE 'libros.dat'
BADFILE '/user/load/libros.bad'
TRUNCATE
INTO TABLE LIBRO
FIELDS TERMINATED BY ","
(Codigo,Titulo, Editor, Categoria, Fecha)
O bien:
LOAD DATA
INFILE 'libros.dat'
BADFILE '/user/load/libros.bad'
TRUNCATE
INTO TABLE LIBRO
(Codigo INTEGER EXTERNAL TERMINATED BY ",",
Titulo CHAR TERMINATED BY ",",
Editor CHAR TERMINATED BY ",",
Categoria CHAR TERMINATED BY ","
Fecha DATE "DD-MM-YYYY" )

Nota. Debemos asegurarnos de usar un delimitador que no forme parte de los valores que sern
cargados. En este ejemplo se usa una coma, as que ninguno de los datos de libro debe incluir una
coma, sino ser interpretada como delimitador del valor.
En este ejemplo, la clusula FIELDS TERMINATED BY le dice a SQL*Loader que, durante la carga, cada valor
de columna terminar con una coma. Como alternativa podemos expecificar en cada campo el caracter
terminador. De esta forma, cada lnea de datos podr tener una longitud distinta.
En este ejemplo se ha proporcionado el nombre de un archivo "malo" mediante la clusula BADFILE. En
general, se especifica el nombre del archivo "malo" cuando requerimos redirigir el archivo a un directorio
diferente.

Oracle /198
Este ejemplo tambin muestra el uso de la clusula TRUNCATE. Cuando este fichero sea ejecutado por
SQL*Loader, la tabla LIBRO ser truncada antes del inicio de la carga. La orden TRUNCATE no puede ser
anulada, as que deberemos usar con cuidado esta opcin. Adems de TRUNCATE, podemos usar las siguientes
opciones:
APPEND Aade filas a la tabla.
INSERT Aade filas a una tabla vaca. Si la tabla no est vaca, la carga se aborta con un error.
REPLACE Vaca la tabla y entonces aade las nuevas fila. El usuario debe tener el permiso DELETE sobre la
tabla.
6.2. Comienzo de la carga.
Para ejecutar los comando del fichero de control necesitamos ejecutar SQL*Loader con los parmetros
apropiados. SQL*Loader se inicia a travs del comando SQLLDR en una consola del sistema operativo (en
UNIX se usa sqlldr).
Nota. El ejecutable SQL*Loader puede consistir del nombre SQLLDR seguido de un nmero de
versin. Hay que consultar la documentacin especfica de Oracle para el nombre exacto. Para
Oracle Database 11g, el fichero ejecutable debera llamarse SQLLDR.
Cuando se ejecute SQLLDR necesitamos especificar el fichero de control, nombre usuario/contrasea, y otra
informacin de carga, tal como se muestra en la siguiente tabla. Podemos separar los argumentos de SQLLDR
con comas. Se escribe la palabra clave, un signo igual ( =) y el argumento apropiado.
Palabra clave Descripcin
Userid Nombre de usuario y contrasea para la carga, separados con una barra.
Control Nombre del fichero de control.
Log Nombre del fichero de log.
Bad Nombre del fichero "malo".
Discard Nombre del fichero de descartes.
Discardmax Nmero mximo de filas a descartar antes de parar de cargar. El valor por defecto
es permitir todos los descartes.
Skip Nmero de filas lgicas en el fichero de entrada que sern saltadas antes de
empezar a cargar datos. Normalmente se usa durante recargas. El valor por
defecto es cero. Se utiliza dentro del argumento OPTIONS:
OPTIONS(SKIP=1)
Load Nmero de filas lgicas a cargar. El valor por defecto es todas.
Errors Nmero de errores permitidos. El valor por defecto es 50.
Rows Nmero de filas que se confirmarn a la vez. Se usa este parmetro para romper el
tamao de transaccin durante la carga. El valor por defecto para rutas
convencionales es de 64; el valor por defecto para cargas Direct Path es todas las
filas.
Bindsize Tamao de cadenas de rutas enlazadas, en bytes. El valor por defecto depende del
sistema operativo.
Silent Suprime mensajes durante la carga.
Direct Usa carga Direct Path. El valor por defecto es FALSE.
Parfile Nombre del fichero de parmetros que contiene especificaciones de parmetros de
carga adicionales.
Parallel Activa la carga en paralelo. El valor por defecto es FALSE.
File Fichero para asignar extensiones desde (para carga paralela).
Skip_Unusable_Indexes Permite cargas dentro de tablas que tienen ndices en estados no usables. El valor
por defecto es FALSE.
Skip_Index_Maintenance Detiene el mantenimiento de ndice para cargas Direct Path, dejndolos en estados
no usables. El valor por defecto es FALSE.
Readsize Tamao del bfer de lectura; el valor por defecto es de 1MB.
External_table Usa una tabla externa para la carga; el valor por defecto es NOT_USED; y otros
valores vlidos son GENERATE_ONLY y EXECUTE.
Columnarrayrows Nmero de filas para cadenas de columnas Direct Path; el valor por defecto es de
5.000.
Streamsize Tamao en bytes del bfer del canal Direct Path; por defecto es de 256000.
Multithreading Un indicador de que debera usarse multiproceso durante Direct Path.

Oracle /199
Resumable Un indicador TRUE/FALSE para habilitar o deshabilitar operaciones recuperables
en la sesin actual; el valor por defecto es FALSE.
Resumable_name Identificador de texto para la operacin recuperable.
Resumable_timeout Tiempo de espera para operaciones recuperables; el valor por defecto es de 7200
segundos.
Si se omite la palabra clave userid y no se proporcionan credenciales en el primer argumento, se debe
preguntar por ellas. Si se pone una barra despus del signo igual, se usar una cuenta identificada
externamente. Tambin podemos usar una cadena de especificacin de base de datos Oracle Net para
registrarnos dentro de una base de datos remota. Por ejemplo, nuestro comando puede comenzar con
sqlldr userid=usernm/mypass@dev
La palabra clave silent le dice a SQLLDR que suprima cierta informacin:
HEADER suprime la cabecera SQL*LOADER.
FEEDBACK suprime la regeneracin en cada punto de confirmacin.
ERRORS suprime el registro (en el archivo de log) de cada fila que provoque un error.
DISCARDS suprime el registro (en el archivo de log) de cada fila que sea descartada.
PARTITIONS desactiva la escritura de estadsticas por particin en el archivo de log.
ALL suprime todo lo precedente.
Si queremos incluir varias de estas opciones, debemos separarlas con comas dentro de parntesis. Por
ejemplo, podemos suprimir la cabecera y la informacin de errores de la siguiente manera:
sqlldr . . . silent=(HEADER,ERRORS)

Nota. Los comandos del fichero de control sobrescriben cualquiera de las opciones explicitadas en
la lnea de comandos.
Como ejemplo cargaremos un simple conjunto de datos dentro de la tabla LIBRO, la cual tiene tres columnas
(Titulo, Autor, Categoria). Se crea un fichero de texto plano llamado libros.txt. Los datos a cargar sern dos
lneas del archivo:
Archivo libros.txt
Libro uno, autor uno, ADULTO
Libro dos, autor dos, JUVENIL
Cada lnea en el archivo se separa con un retorno de carro. Dentro de cada lnea los datos se han separado
con comas. En este caso no queremos eliminar los datos previamente cargados en la tabla LIBRO, as que el
fichero de control tendr el siguiente contenido:
Archivo libros.ctl
LOAD DATA
INFILE 'libros.txt'
APPEND
INTO TABLE LIBRO
FIELDS TERMINATED BY ","
(Titulo, Autor, Categoria)
Se guarda el archivo como libros.ctl, en el mismo directorio que el fichero de datos. A continuacin, se ejecuta
SQLLDR dicindole a Oracle que use el fichero de control. Este ejemplo asume que la tabla LIBRO existe
dentro del esquema empleado:
sqlldr empleado/contrasea control=libros.ctl log=libros.log
Registros lgicos y fsicos.
Varias de las opciones del comando SQLLDR se refieren a registros lgicos. Un registro lgico es un registro
que se inserta dentro de la base de datos. Dependiendo de la estructura del fichero de entrada, varios registros
fsicos pueden ser combinados para crear un nico registro lgico.
Por ejemplo, el fichero de entrada puede contener:
Un libro, Un autor, ADULTO
En este caso debera existir una relacin uno-a-uno entre el registro fsico y el registro lgico que es creado.
Pero el fichero de datos podra tambin contener:
Un libro,
Un autor,
ADULTO

Oracle /200
Para combinar estos datos necesitamos especificar reglas de continuacin. En este caso, los valores de las
columnas son distribuidos en lneas separadas, as que un conjunto de registros fsicos se corresponden con
un registro lgico. Para combinarlos se usa la clusula CONCATENATE dentro del fichero de control. En este
caso hay que especificar CONCATENATE 3 para crear un nico registro lgico a partir de tres registros fsicos.
La lgica para crear un nico registro lgico a partir de varios registros fsicos puede ser mucho ms compleja
que una simple concatenacin. Podemos usar la clusula CONTINUEIF para especificar las condiciones que
indiquen la continuacin. Incluso podemos manipular los datos de entrada para crear varios registros lgicos
de un nico registro fsico (a travs de varias clusulas INTO TABLE).
Podemos usar SQL*Loader para generar varias inserciones desde un nico registro fsico. Por ejemplo,
supongamos que los datos de entrada estn desnormalizados, incluyendo valores para una ciudad y la
cantidad de lluvia cada a lo largo el da, en el formato ( Ciudad, Precipitacion1, Precipitacion2, Precipitacion3). El
fichero de control debera re-ensamblar lo siguiente (se indica la posicin de los datos):
...
INTO TABLE PRECIPITACION
WHEN Ciudad != ''
(Ciudad POSITION(1:5) CHAR, Precipitacion POSITION(6:10) INTEGER EXTERNAL) -- 1 Fila --
INTO TABLE PRECIPITACION
WHEN CITY != ''
(Ciudad POSITION(1:5) CHAR, Precipitacion POSITION(11:16) INTEGER EXTERNAL) -- 2 Fila --
INTO TABLE PRECIPITACION
WHEN CITY != ''
(Ciudad POSITION(1:5) CHAR, Precipitacion POSITION(16:21) INTEGER EXTERNAL) -- 3 Fila --
Ntese que cada clusula INTO TABLE opera con cada fila fsica. En este ejemplo, se generan tres filas lgicas
en la tabla PRECIPITACION por cada fila fsica. Tambin podramos haber insertado filas en varias tablas.
6.3. Sobre la sintaxis del fichero de control.
Dentro de la clusula LOAD (que especifica el nmero de filas lgicas a cargar) podemos especificar si la carga
es recuperable (RECOVERABLE) o irrecuperable (UNRECOVERABLE). La clusula UNRECOVERABLE slo se aplica
en cargas Direct Path.
Adems de usar la clusula CONCATENATE, podemos usar la clusula CONTINUEIF para controlar la manera
en la cual los registros fsicos son ensamblados dentro de registro lgicos. La clusula THIS referencia al
registro fsico actual, mientras que la clusula NEXT referencia el siguiente registro fsico. Por ejemplo,
podemos crear un tem de continuacin de dos caracteres al inicio de cada registro fsico. Si este registro debe
ser concatenado al registro precedente, se asigna este valor iguala a '**'. Entonces se puede usar la clusula
CONTINUEIF NEXT(1:2)='**' para crear un nico registro lgico. El tem de continuacin '**' no ser parte del
registro combinado.
La sintaxis para la clusula INTO TABLE incluye una clusula WHEN. Este clusula WHEN sirve como un filtro
que se aplica a cada registro antes de su insercin. Por ejemplo, podemos especificar:
WHEN Categoria='ADULTO'
Para cargar slo aquellos libros con una categora determinada. Cualquier fila que no pase la condicin ser
escrita al fichero de descartes. La clusula WHEN slo admite expresiones con los comparadores =, <> y != (es
decir, slo pueden realizarse comparaciones por igualdad o desigualdad). Se pueden encadenar varias
condiciones mediante el operador AND, pero no mediante el operador OR.
Se usa la clusula TRAILING NULLCOLS si estamos cargando registros de longitud variable para los cuales la
ltima columna no siempre tiene un valor. Gracias a este clusula, SQL*Loader generar valores nulos para
estas columnas.
Como se ha visto previamente, podemos usar la clusula FIELDS TERMINATED BY para cargar datos de
longitud variable. En vez de ser terminados por un caracter, los campos pueden ser terminados con espacios
en blanco o encapsulados entre caracteres o opcionalmente encapsulados por otros caracteres. Por ejemplo, la
siguiente entrada carga el campo Autor y asigna los valores en maysculas durante la insercin. Si el valor est
en blanco, se inserta un valor nulo:
Autor POSITION(10:34) CHAR TERMINATED BY WHITESPACE
NULLIF Autor=BLANKS "UPPER(:Autor)"
Cuando se cargan valores de tipo DATE, podemos especificar la mscara de formato. Por ejemplo, si tenemos
una columna llamada Fecha y los datos estn en el formato Mon-DD-YYYY en las primeras once posiciones de la
fila, podemos especificar la carga de este campo de la siguiente manera:

Oracle /201
Fecha POSITION (1:11) DATE "Mon-DD-YYYY"
Dentro de la clusula INTO TABLE podemos usar la palabra clave RECNUM para asignar un nmero de registro
a cada registro lgico tal como es ledo desde el fichero de datos, y este valor puede ser insertado dentro de
una columna designada de la tabla. La palabra clave CONSTANT permite asignar un valor constante a una
columna durante la carga. Para columnas de caracteres, se encierra el valor constante entre comillas simples.
Si se usa la palabra clave SYSDATE, la columna seleccionada ser poblada con la fecha actual del sistema. Por
ejemplo:
FechaInsercion SYSDATE
Si usamos la opcin SEQUENCE, SQL*Loader mantendr una secuencia de valores durante la carga. A medida
que los registros son procesados, el valor de secuencia ser incrementado por el incremento especificado. Si
las filas fallan durante la insercin, los valores de secuencia no sern reutilizados. Si usamos la palabra clave
MAX dentro de la opcin SEQUENCE, los valores de secuencia usarn el valor siguiente al mximo actual de la
columna como valor inicial para la secuencia. La siguiente lnea muestra cmo usar la opcin SEQUENCE:
Columna_secuencial SEQUENCE(MAX,1)
Tambin podemos especificar el valor de inicio y el de incremento para una secuencia, que sern usados
cuando insertemos. El siguiente ejemplo inserta valores empezando con el valor 100 e incrementando de 2 en
2. Si una fila es rechazada durante la insercin, el valor de secuencia ser saltado.
Columna_secuencial SEQUENCE(100,2)
Si almacenamos nmeros en columnas de tipo VARCHAR2, deberamos evitar usar la opcin SEQUENCE para
estas columnas. Un problemas es, por ejemplo, si nuestra tabla ya contiene valores de 1 a 10 en una columna
de tipo VARCHAR2; entonces el mximo valor dentro de esta columna ser '9' (el valor string ms grande) y no
'10'.
Los ficheros de control SQL*Loader pueden soportar lgica y reglas del negocio complejos. Por ejemplo,
nuestros datos de entrada para columnas con valores monetarios pueden implicar decimales; 9990 debera ser
insertado como 99,90. En SQL*Loader, podemos insertar esto realizando los clculos durante la carga de
datos:
Cantidad_monetaria POSITION (20:28) EXTERNAL DECIMAL(9) ":cantidad/100"
6.4. Administracin de la carga de datos.
Cargar grandes volmenes de datos es una operacin por lotes. Las operaciones por lotes no deberan
realizarse concurrentemente con las transacciones pequeas prevalentes en muchas aplicaciones de bases de
datos. Si tenemos muchos usuarios concurrentes ejecutando pequeas operaciones sobre una tabla,
deberamos planificar las operaciones por lotes sobre dicha tabla para que ocurran cuando pocos usuarios
accedan a la tabla.
Oracle mantiene lecturas consistentes en las consultas de usuarios. Si ejecutamos un trabajo de SQL*Loader
sobre la tabla al mismo tiempo que otros usuarios estn consultando la tabla, Oracle mantendr internamente
instantneas de la tabla para que los usuarios vean los datos tal como estaban cuando realizaron la consulta.
Para minimizar la cantidad de trabajo, Oracle debe funcionar de modo que mantenga lectura consistente (y
reducir al mnimo la degradacin causada por esta sobrecarga), y planifique los trabajos de carga de larga
duracin para que se realicen cuando hay pocas acciones ocurriendo en la base de datos. En particular, debe
evitar los conflictos con otros accesos a la misma tabla.
Si diseamos nuestro proceso de carga de datos ser ms sencillo de mantener y reutilizar. Debemos
establecer normas para la estructura y formato de los ficheros de datos de entrada. Estandarizando los
formatos de datos de entrada ser ms simple reutilizar viejos archivos de control para las cargas de datos.
Para recurrentes planificaciones de cargas en la misma tabla, nuestro objetivo debera ser el de reutilizar el
mismo archivo de control cada vez. Despus de cada carga, tendremos que repasar y mover los ficheros de
log, filas errneas, datos y filas descartadas para no realizar sobre-escrituras accidentales.
Dentro del fichero de control se pueden usar comentarios para indicar funciones de proceso especiales que
deban realizarse. Para crear un comentario dentro del fichero de control, se comienza la lnea con dos
guiones, tal como se muestra a continuacin:
-- Limitar la carga a empleados de LA:
WHEN Ubicacion='LA'
Si tenemos comentado apropiadamente nuestro fichero de control incrementaremos la capacidad de
reutilizarlo durante futuras cargas.
6.4.1. Cargas de datos repetitivas.
La carga de datos no siempre trabaja exactamente como se planific. Estn involucradas muchas variables en

Oracle /202
la carga de datos, y no todas ellas estn siempre bajo nuestro control. Por ejemplo, el propietario de los datos
de origen puede cambiar el formato de los datos, invalidando parte de nuestro fichero de control. Las reglas
del negocio pueden cambiar, forzando cambios adicionales. Las estructuras de datos y el espacio disponible
pueden cambiar, lo que afecta a la habilidad de cargar datos.
En un caso ideal, una carga de datos se completar totalmente o fallar totalmente. Sin embargo, en muchos
casos, una carga de datos ocurrir parcialmente, haciendo el proceso de recuperacin ms dificultoso. Si
alguno de estos registros ha sido insertado dentro de la tabla, entonces intentar reinsertarlos provocar una
violacin de clave primaria. Si estamos generando la clave primaria durante la insercin (a travs de la opcin
SEQUENCE), entonces estos registros pueden no fallar la segunda vez (y por tanto sern insertados dos veces).
Para determinar cundo una carga falla se usa el fichero de log. El fichero de log registrar los puntos de
confirmacin as como los errores encontrados. Todos los registros rechazados deberan estar en el archivo
"malo" o en el archivo de descartes. Podemos reducir al mnimo el esfuerzo de recuperacin forzando que la
carga falle si se encuentras muchos errores. Para forzar que la carga aborte antes de que se encuentren un
gran nmero de errores se usan la palabra clave ERRORS del comando SQLLDR. Tambin podemos usar la
palabra clave DISCARDMAX para limitar el nmero de descartes permitidos antes de abortar la carga. Si se
asigna ERRORS a 0, el primer error causar que la carga falle.
Qu pasa si la carga falla despus de que 100 registros sean insertados? Tenemos dos opciones: identificar y
borrar los registros insertados y reaplicar la carga entera, o saltarse lo registros insertados. Podemos usar la
palabra clave SKIP de SQLLDR para saltarse los primeros 100 registros durante el proceso de carga. La carga
continuar en el registro 101 (que habr sido corregido). Si no podemos identificar las filas que han sido
cargadas en la tabla, necesitaremos usar la opcin SKIP durante el proceso de recarga.
Las asignaciones apropiadas para ERRORS y DISCARDMAX dependen de la carga. Si tenemos control completo
sobre el proceso de carga, y los datos son apropiadamente "limpiados" antes de ser extrados a un fichero de
carga, podemos tener muy poca tolerancia a errores y descartes. Por otra parte, si no tenemos control sobre el
origen del fichero de datos de entrada, necesitaremos asignar ERRORS y DISCARDMAX a un valor alto para
permitir que la carga se complete. Despus de que la carga se haya completado necesitaremos revisar el
fichero de log, corregir los datos del fichero "malo", y recargar los datos usando el fichero "malo" original
como el nuevo fichero de entrada. Si los registros han sido incorrectamente descartados, necesitaremos hacer
cargas adicionales usando el fichero de descartes original como el nuevo fichero de entrada.
6.5. Ajustar la carga de datos.
Adems de ejecutar el proceso de carga de datos en momentos con poco trnsito, podemos hacer otras cosas
para mejorar el rendimiento de la carga. Los siguientes pasos afectan al entorno de base de datos y deben ser
coordinados con el administrador de base de datos. No debera permitirse afinar una carga de datos porque
tiene un impacto negativo sobre la base de datos o sobre los procesos del negocio que soporta.
Primero, la carga de datos en lotes puede ocurrir mientras la base de datos est en modo NOARCHIVELOG.
Mientras est en modo NOARCHIVELOG, la base de datos no permite que uno de sus archivos genere ficheros
de deshacer antes de modificarlo. Eliminando el proceso de archivado mejoramos el rendimiento de las
transacciones. Ya que los datos estn siendo cargados desde un archivo, podemos recrear los datos cargados
ms tarde recargando el fichero de datos en vez de recuperarlos desde un archivo de deshacer.
Sin embargo, hay una caracterstica potencialmente significativa cuando desactivamos el modo ARCHIVELOG.
No permite realizar una recuperacin en un punto dado del tiempo a menos que el archivado est habilitado.
Si realizamos transacciones que no sean por lotes en la base de datos, probablemente necesitaremos ejecutar
la base de datos en modo ARCHIVELOG todas las veces, incluyendo durante nuestras cargas. An ms, cambiar
entre el modo ARCHIVELOG y NOARCHIVELOG requiere que cerremos la instancia de base de datos. Si
cambiamos la instancia a modo NOARCHIVELOG, realizamos nuestra carga de datos, y entonces cambiamos la
instancia a modo ARCHIVELOG, deberemos realizar una copia de respaldo de la base de datos inmediatamente
despus del reinicio.
En vez de ejecutar toda la base de datos en modo NOARCHIVELOG, podemos desactivar el archivado para
nuestro proceso de carga de datos usando la palabra clave UNRECOVERABLE con SQL*Loader. La opcin
UNRECOVERABLE desactiva la escritura de entradas en los ficheros de deshacer para las transacciones de la
carga de datos. Deberamos usar slo esta opcin si queremos recrear las transacciones desde los ficheros de
entrada en el caso de que sea necesario para futuras recuperaciones. La opcin UNRECOVERABLE est slo
disponible para cargas Direct Path.
Ms que controlar las actividades de deshacer al nivel del proceso de carga, podemos controlarlas al nivel de

Oracle /203
la tabla o particin. Si definimos un objeto como NOLOGGING, entonces inserciones al nivel de bloque
realizadas por SQL*Loader Direct Path y el comando INSERT /*+ APPEND */ no generarn entradas de
deshacer. Inserciones al nivel de bloque requieren espacio adicional, y no reutilizan bloques existentes bajo la
marca de agua de la tabla.
Si nuestro sistema operativo tiene varios procesadores, podemos tomar la ventaja de varios CPU's realizando
una carga de datos paralela. La opcin PARALLEL de SQLLDR usa procesos de carga de datos de concurrencia
mltiple para reducir la sobrecarga del tiempo requerido para cargar los datos.
Adems de estas posibilidades, deberamos trabajar con nuestro administrador de base de datos para hacer
seguro el entorno de la base de datos y que las estructura son las apropiadas para cargar datos. El esfuerzo de
ajuste debera incluir lo siguiente:
Preasignar espacio para la tabla, para minimizar extensiones dinmicas durante las cargas.
Asignar suficientes recursos de memoria para las reas de memoria compartida.
Canalizar los procesos de escritura de datos creando varios procesos de escritura de base de datos
(DBWR).
Quitar cualquier trigger innecesario durante la carga de datos. Si es posible, desactivar o eliminar los
triggers antes de la carga, y realizar las operaciones de los triggers sobre los datos cargados manualmente
despus de que hayan sido cargados.
Eliminar o desactivar cualquier restriccin innecesaria sobre la tabla. Podemos usar SQL*Loader para
desactivar y reactivar dinmicamente restricciones.
Eliminar ndices sobre las tablas. Si los datos han sido apropiadamente limpiados antes de la carga,
entonces validaciones de unicidad y clave fornea no sern necesarias durante la carga. Eliminar ndices
antes de la carga incrementa significativamente el rendimiento.
6.5.1. Cargas Direct Path.
SQL*Loader genera un gran nmero de comandos de insercin. Para evitar la sobrecarga asociada con el uso
de numerosas inserciones, podemos usar la opcin Direct Path en SQL*Loader. La opcin Direct Path crea
bloques de datos preformateados e inserta estos bloques dentro de la tabla. Como resultado, el rendimiento
de nuestra carga puede mejorarse dramticamente. Para usar la opcin Direct Path debemos no realizar
ninguna funcin sobre los valores que estn siendo ledos desde el fichero de entrada.
Cualquier ndice sobre la tabla que est siendo cargada ser ubicado dentro de un estado temporal DIRECT
LOAD (se puede consultar el estado del ndice desde USER_INDEXES). Oracle mover los antiguos valores del
ndice a un ndice temporal. Una vez que la carga se completa, los valores antiguos sern combinados con los
nuevos valores para crear el nuevo ndice, y Oracle eliminar el ndice temporal. Cuando el ndice es otra vez
vlido, su estado es cambiado a VALID. Para minimizar la cantidad de espacio necesario para el ndice
temporal podemos preordenar los datos por las columnas del ndice. El nombre del ndice para el cual los
datos son preordenados debera especificarse a travs de la clusula SORTED INDEXES en el fichero de
control.
Para usar la opcin Direct Path se especifica
DIRECT=TRUE
en la lnea del comando SQLLDR o se incluye esta opcin en el fichero de control.
Si usamos la opcin Direct Path, podemos usar la palabra clave UNRECOVERABLE para incrementar el
rendimiento de la carga de datos. Esto instruye a Oracle para que no genere entradas de deshacer durante la
carga. Si necesitamos recuperar la base de datos en un punto posterior, necesitaremos reejecutar la carga de
datos para recuperar los datos de la tabla. Todas las cargas convencionales son recuperables, y todas las cargas
Direct Path son recuperables por defecto.
Las cargas Direct Path son ms rpidas que las cargas convencionales, y las cargas Direct Path no
recuperables son ms rpidas todava. Ya que las cargas no recuperables impactan en nuestras operaciones de
recuperacin, necesitamos pesar el coste de este impacto frente a los beneficios de rendimiento. Si nuestro
entorno de hardware tiene recursos adicionales disponibles durante la carga, podemos usar la opcin de carga
Direct Path paralela para dividir el trabajo de carga de datos en varios procesos. Las operaciones Direct Path
paralelas pueden completar el trabajo de carga ms rpido que una carga Direct Path simple.
En vez de usar la opcin PARALLEL, podemos particionar la tabla.
Desde SQL*Loader podemos cargar una nica particin, y podemos ejecutar varios trabajos de SQL*Loader
simultneamente para poblar las particiones de una tabla particionada. Este mtodo requiere ms trabajo de
administracin de base de datos (para configurar y manejar las particiones), pero da ms flexibilidad en la
paralelizacin y planificacin de las tareas de carga.

Oracle /204
Podemos tomar las ventajas de las funcionalidades de carga multihilo para cargas Direct Path para convertir
columnas de arrays a bferes de stream y realizar cargas mediante bferes de stream en paralelo. Se usa el
parmetro STREAMSIZE y la bandera MULTITHREADING para habilitar esta caracterstica.
Las cargas Direct Path pueden impactar en el espacio requerido para los datos de la tabla. Ya que la carga
Direct Path inserta bloques de datos, no sigue el mtodo habitual para asignar espacio dentro de una tabla.
Los bloques son insertados al final de la tabla, despus de la gran marca de agua, el cual es el bloque ms alto
dentro de la tabla en el cual han sido escrito datos. Si insertamos 100 bloques dentro de una tabla y entonces
eliminamos todos sus registros, la gran marca de agua de la tabla estar asignada al bloque 100. Si entonces
realizamos una carga de datos convencional, los registros sern insertados dentro de los bloques ya asignados.
Si intentamos realizar una carga Direct Path, Oracle insertar los nuevos bloques de datos despus del bloque
100, incrementando potencialmente el espacio asignado a la tabla. El nico modo de bajar la gran marca de
agua de una tabla es truncndola (lo cual elimina todos los registros y no podemos recuperarlos) o borrndola
y recrendola.
6.6. Funcionalidades adicionales.
Adems de las funcionalidades vistas en este captulo, SQL*Loader soporta tipos de datos Unicode y
expandidos. SQL*Loader puede cargar tipos de datos enteros y decimales empaquetados entre plataformas
con diferentes rdenes de byte y aceptar zonas basadas en EBCDIC o datos decimales codificados en
formato IBM. SQL*Loader tambin ofrece soporte para cargar columnas XML, tipos de objetos con
subtipos y Unicode (caracteres UTF16). SQL*Loader tambin proporciona soporte nativo para fechas, horas
e intervalos de tiempo. Si una tarea SQL*Loader falla, podremos reanudarla desde donde fall usando las
opciones RESUMABLE, RESUMABLE_NAME y RESUMABLE_TIMEOUT. Por ejemplo, si el segmento en el cual la
tarea de carga est escribiendo no puede extenderse, podemos desactivar la tarea de carga, solucionar el
problema de espacio y reanudar la tarea. Nuestra habilidad para realizar estas operaciones depende de la
configuracin de la base de datos.
Podemos acceder a ficheros externos como si fuesen tablas internas de la base de datos. Esta funcionalidad
de tablas externas permite potencialmente evitar cargar grandes volmenes de datos dentro de la base de
datos. (Vase el captulo dedicado a tablas externas.)
7. Importar y exportar con Data Pump
Desde Oracle Database 10g se incluye Data Pump, que proporciona utilidades para la extraccin e
importacin de datos basadas en servidor. Esta funcionalidad incluye cambios significativos en la arquitectura
y funcionalidad respecto a las utilidades originales de importacin y exportacin. Data Pump permite parar y
reiniciar tareas, ver el estado de las tareas que se estn ejecutando y restringir los datos que son exportados e
importados.
Nota. Data Pump puede usar los ficheros generados por la utilidad original Export, pero la utilidad
original Import no puede usar los ficheros generados por Data Pump Export.
Data Pump se ejecuta como un proceso de servidor, beneficiando a los usuarios de varias maneras. El
proceso cliente que inicia la tarea puede desconectarse y ms tarde re-enlazarse a la tarea. El rendimiento es
mejor (en comparacin con Export/Import) porque los datos no necesitan ser procesados por un programa
cliente.
Las extracciones y cargas Data Pump pueden ser paralelizadas, ganando as en rendimiento.
7.1. Creando un directorio.
Data Pump requiere que creemos directorios para los ficheros de datos y ficheros log que sern creados y
ledos. Se usa el comando CREATE DIRECTORY para crear un directorio dentro de Oracle que apuntar a un
directorio externo. Los usuarios que accedern a ficheros Data Pump deber tener permisos READ y WRITE
sobre el directorio.
Nota. Antes de empezar, hay que verificar que el directorio externo existe y que el usuario que usar
el comando CREATE DIRECTORY tiene el permiso de sistema CREATE ANY DIRECTORY.
El siguiente ejemplo crea un directorio llamado DTPUMP y concede accesos READ y WRITE al esquema
Empleado:
CREATE DIRECTORY DTPUMP AS 'E:\DTPUMP';
GRANT READ ON DIRECTORY DTPUMP TO Empleado, SYSTEM;

Oracle /205
GRANT WRITE ON DIRECTORY DTPUMP TO Empleado, SYSTEM;
Los esquemas Empleado y SYSTEM pueden ahora usar el directorio DTPUMP para tareas Data Pump.
7.2. Opciones de Data Pump Export.
Oracle proporciona una utilidad, EXPDP, que sirve como interfaz para Data Pump. La siguiente tabla muestra
los parmetros de lnea de comandos para EXPDP cuando es creada una tarea.
Parmetro Descripcin
ATTACH Conecta una sesin clienta a una tarea de Data Pump Export que se est
ejecutando actualmente.
CONTENT Filtros que son exportados: DATA_ONLY, METADATA_ONLY o ALL.
DIRECTORY Especifica el directorio destino para el fichero de log y el fichero de volcado
asignado.
DUMPFILE Especifica el nombre y directorio para ficheros de volcado (dump).
ESTIMATE Determina el mtodo usado para estimar el tamao del fichero de volcado
(BLOCKS o STATISTICS).
ESTIMATE_ONLY Valor Y/N usado para instruir a Data Pump sobre si los datos deberan ser
exportados o estimados.
EXCLUDE Especifica el criterio para excluir objetos y datos que sern exportados.
FILESIZE Especifica el tamao mximo de fichero para cada fichero de volcado
exportado.
FLASHBACK_SCN SCN de la base de datos para flashback durante la exportacin.
FLASHBACK_TIME Fecha de la base de datos para flashback durante la exportacin.
FULL Le dice a Data Pump que exporte todos los datos y metadatos en un modo de
exportacin "Full".
HELP Muestra una lista de comandos y opciones disponibles.
INCLUDE Especifica el criterio por el cual los objetos y datos sern exportados.
JOB_NAME Especifica el nombre de la tarea; el valor por defecto es generado por el
sistema.
LOGFILE Nombre y directorio opcional para el fichero de log de exportacin.
NETWORK_LINK Especifica el enlace de base de datos origen para la tarea de Data Pump
Export a una base de datos remota.
NOLOGFILE Valor Y/N usado para suprimir la creacin del fichero de log.
PARALLEL Asigna el nmero de trabajadores para la tarea de Data Pump Export.
PARFILE Nombres del fichero de parmetros que se usa, si hay alguno.
QUERY Filtras registros desde las tablas durante la exportacin.
SCHEMAS Nombres de los esquemas a ser exportados por el modo de exportacin
"Schema".
STATUS Muestra detalles del estado de la tarea Data Pump.
TABLES Lista las tablas y particiones que sern exportadas para el modo de exportacin
"Table".
TABLESPACES Lista los tablespaces a ser exportados.
TRANSPORT_FULL_CHECK Especifica si el tablespace que es exportado debera primero ser verificado
como un conjunto autnomo.
TRANSPORT_TABLESPACES Especifica un modo de exportacin "Transportable Tablespace".
VERSION Especifica la versin de los objetos de base de datos a ser creados, y as el
fichero de volcado podr ser compatible con versiones previas de Oracle. Las
opciones son COMPATIBLE, LATEST, y el nmero de versin de la base de
datos (no menor que 10.0.0).
Como se hace referencia en esta tabla, existe cinco modos de exportacin Data Pump:
La exportacin "Full" extrae todos los datos y metadatos de la base de datos (parmetro FULL).
La exportacin "Schema" extrae los datos y metadatos para un esquema de usuario especfico (parmetro
SCHEMA).
La exportacin "Tablespace" extrae los datos y metadatos para tablespaces (parmetro TABLESPACES).
La exportacin "Table" extrae los datos y metadatos para tablas y sus particiones (parmetro TABLES).
La exportacin "Transportable Tablespace" extrae los metadatos de tablespaces especficos (parmetro
TRANSPORT_TABLESPACES).

Oracle /206
Nota. Debemos tener el permiso de sistema EXP_FULL_DATABASE para poder realizar exportacin
"Full" o exportacin "Transportable Tablespace".
Cuando realizamos una tarea, Oracle le da un nombre de tarea. Si especificamos un nombre para la tarea
mediante el parmetro JOB_NAME debemos asegurarnos de que ese nombre no entre en conflicto con el
nombre de alguna tabla o vista de nuestro esquema. Durante la tarea Data Pump, Oracle crear y mantendr
una tabla maestra durante la duracin de la tarea. Esta tabla tendr el mismo nombre que la tarea Data Pump.
Cuando una tarea se est ejecutando, podemos ejecutar los comandos siguientes mediante la interfaz de Data
Pump.
Parmetro Descripcin
ADD_FILE Aade un fichero de volcado.
CONTINUE_CLIENT Finaliza el modo interactivo y entra en el modo de logging.
EXIT_CLIENT Finaliza la sesin cliente, pero conserva ejecutndose la tarea de servidor Data Pump
Export.
HELP Muestra ayudas en lnea para la importacin.
KILL_JOB Mata la tarea actual y desenlaza las sesiones cliente relacionadas.
PARALLEL Modifica el nmero de trabajadores para la tarea Data Pump Export.
START_JOB Reinicia la tarea asociada.
STATUS Muestra detalles de estado de la tarea Data Pump.
STOP_JOB Para la tarea para reiniciarla ms tarde.
Como indican estos parmetros, podemos cambiar muchas caractersticas en la ejecucin de Data Pump
Export a travs de modo de comandos interactivos. Si el rea de volcado se ejecuta fuera de espacio,
podemos asociarnos a la tarea, aadir ficheros, y reiniciar la tarea en algn momento; no necesitamos matar la
tarea o re-ejecutarla desde el principio. Podemos mostrar el estado de la tarea en algn momento, mediante el
parmetro STATUS o mediante las vistas del diccionario de datos USER_DATAPUMP_JOBS y
DBA_DATAPUMP_JOBS o la vista V$SESSION_LONGOPS.
7.3. Iniciando una tarea de Data Pump Export.
Podemos guardar nuestros parmetros de tarea en un fichero de parmetros, referenciado a travs del
parmetro PARFILE de EXPDP. Por ejemplo, podemos crear un fichero llamado dp1.par con las siguientes
entradas:
Archivo dp1.par
DIRECTORY=DTPUMP
DUMPFILE=metadataonly.dmp
CONTENT=METADATA_ONLY
Entonces se puede iniciar la tarea Data Pump Export con:
EXPDP empleado/contrasea PARFILE=dp1.par
Oracle pasar entonces las entradas de dp1.par a la tarea de Data Pump Export. Se ejecutar por defecto un
Data Pump Export de tipo "Schema", y la salida (los metadatos listados, pero no los datos) sern escritos a un
fichero en el directorio DTPUMP definido previamente. Cuando ejecutemos el comando EXPDP, la salida ser en
el siguiente formato (hay lneas separadas por cada tipo de objeto):
Export: Release 10.1.0.1.0 on Wednesday, 26 May, 2004 17:29
Copyright (c) 2003, Oracle. All rights reserved.
Conectado a: Oracle10i Enterprise Edition Release 10.1.0.1.0
Iniciando "EMPLEADO"."SYS_EXPORT_SCHEMA_01": empleado/******** parfile=dp1.par
Procesando el tipo de objeto SCHEMA_EXPORT/SE_PRE_SCHEMA_PROCOBJACT/PROCACT_SCHEMA
Procesando el tipo de objeto SCHEMA_EXPORT/TYPE/TYPE_SPEC
Procesando el tipo de objeto SCHEMA_EXPORT/TABLE/TABLE
Procesando el tipo de objeto SCHEMA_EXPORT/TABLE/GRANT/OBJECT_GRANT
Procesando el tipo de objeto SCHEMA_EXPORT/TABLE/INDEX/INDEX
Procesando el tipo de objeto SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Procesando el tipo de objeto SCHEMA_EXPORT/TABLE/COMMENT
Procesando el tipo de objeto SCHEMA_EXPORT/VIEW/VIEW
Procesando el tipo de objeto SCHEMA_EXPORT/PACKAGE/PACKAGE_SPEC
Procesando el tipo de objeto SCHEMA_EXPORT/PACKAGE/PACKAGE_BODY
Procesando el tipo de objeto SCHEMA_EXPORT/PACKAGE/GRANT/OBJECT_GRANT

Oracle /207
Procesando el tipo de objeto SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Procesando el tipo de objeto SCHEMA_EXPORT/SE_EV_TRIGGER/TRIGGER
La tabla maestra "EMPLEADO"."SYS_EXPORT_SCHEMA_01" se ha cargado/descargado correctamente
******************************************************************************
El juego de archivos de volcado para EMPLEADO.SYS_EXPORT_SCHEMA_01 es:
E:\DTPUMP\METADATAONLY.DMP
El trabajo "EMPLEADO"."SYS_EXPORT_SCHEMA_01" ha terminado correctamente en 17:30
El fichero de salida, tal como se muestra en el listado, se denomina metadataonly.dmp. El fichero de volcado
contiene entradas XML para recrear las estructura del esquema Empleado. Durante la exportacin, Data Pump
crea y usar una tabla externa llamada SYS_EXPORT_SCHEMA_01.
Nota. Los ficheros de volcado no sobrescriben ficheros previamente existentes en el mismo
directorio.
Podemos usar varios directorios y ficheros de volcado para un nico Data Pump Export. Dentro del
parmetro DUMPFILE podemos listar varios directorios y ficheros con el siguiente formato:
DUMPFILE=directorio1:file1.dmp, directorio2:file2.dmp
Por ejemplo, si queremos realizar una copia de seguridad de la tabla VENTAS del esquema EMPLEADO dentro
del directorio referenciado por DTPUMP, podemos usar el siguiente fichero de parmetros:
DIRECTORY=DTPUMP
DUMPFILE=backup.dmp
CONTENT=ALL
TABLES=VENTAS
7.3.1. Parando y reanudando tareas que se estn ejecutando.
Despus de haber empezado una tarea Data Pump Export podemos cerrar la ventana cliente que hemos
usado para iniciar la tarea. Debido a que est basado en servidor, la exportacin continuar ejecutndose.
Podemos asociarnos a la tarea, verificar su estado y alterarla. Por ejemplo, podemos iniciar la tarea mediante
EXPDP:
EXPDP empleado/contrasea PARFILE=dp1.par
Presionando CTRL-C salimos de la pantalla de registro, y Data Pump retornar al indicador Export:
Export>
Se finaliza la operacin a travs del comando EXIT_CLIENT:
Export> EXIT_CLIENT
Podemos entonces reiniciar el cliente y asociarnos a la tarea que se est ejecutando actualmente bajo nuestro
esquema:
EXPDP empleado/contrasea ATTACH
Si hemos dado nombre a la tarea Data Pump Export, podemos especificar el nombre como parte del
parmetro ATTACH. Por ejemplo, si hemos llamado a la tarea EMPLEADO_JOB, podemos asociarnos a la tarea
con:
EXPDP empleado/contrasea ATTACH=EMPLEADO_JOB
Cuando nos asociamos a una tarea que se est ejecutando, Data Pump mostrar el estado de la tarea (sus
parmetros de configuracin bsicos y su estado actual). Podemos entonces usar el comando
CONTINUE_CLIENT para ver las entradas de log que se generen o podemos modificar la tarea que se est
ejecutando:
Export> CONTINUE_CLIENT
Podemos parar una tarea mediante la opcin STOP_JOB:
Export> STOP_JOB
Cuando la tarea se para, podemos entonces aadir ficheros de volcado adicionales en nuevos directorios, a
travs de la opcin ADD_FILE. Podemos entonces reiniciar la tarea:
Export> START_JOB
Podemos especificar una localizacin del fichero de log para la exportacin mediante el parmetro LOGFILE.
Si no especificamos un valor para LOGFILE, el fichero de log sern escrito en el mismo directorio que el
fichero de volcado.
7.3.2. Exportando para otra base de datos.
Podemos usar el parmetro NETWORK_LINK para exportar datos desde una base de datos diferente. Si nos
hemos registrado en la base de datos HQ y tenemos un enlace de base de datos en otra base de datos, Data
Dump puede usar este enlace para conectarse a la base de datos y extraer sus datos.

Oracle /208
Nota. Si la base de datos es de solo lectura, el usuario de la base de datos origen deber tener un
tablespace administrado localmente asignado como un tablespace temporal; si no es as, la tarea
fallar.
En nuestro fichero de parmetros (o en la lnea de comandos de EXPDP) debemos asignar el parmetro
NETWORK_LINK al nombre de nuestro enlace de base de datos. El Data Pump Export escribir los datos
desde la base de datos remota al directorio definido en nuestra base de datos local.
7.3.3. Uso de EXCLUDE, INCLUDE y QUERY.
Podemos excluir o incluir conjuntos de tabla desde Data Pump Export mediante las opciones EXCLUDE e
INCLUDE. Podemos excluir objetos por tipo o por nombre. Si un objeto es excluido, todos los objetos
dependientes sern tambin excluidos. El formato para la opcin EXCLUDE:
EXCLUDE= tipo_objecto [ : clusula] [, ...]

Nota. No podemos especificar EXCLUDE si especificamos CONTENT=DATA_ONLY.


Por ejemplo, para excluir el esquema Empleado de una exportacin completa, el formato para la opcin
EXCLUDE debera ser como sigue.
EXCLUDE=SCHEMA:"='Empleado'"
La opcin EXCLUDE de este ejemplo contiene una condicin limitante ( ='Empleado') dentro de las comillas
dobles. La variable clusula puede ser cualquier tipo de objeto de Oracle, incluyendo GRANT, INDEX y TABLE.
Por ejemplo, para excluir de la exportacin de todas las tablas aquellas cuyo nombre comience con 'TEMP',
podemos especificar lo siguiente:
EXCLUDE=TABLE:"LIKE 'TEMP%'"
Cuando escribimos este tipo de lnea de comando, podemos necesitar usar caracteres de escape de forma que
las marcas de comilla y otros caracteres especiales sean pasados apropiadamente a Oracle. El comando EXPDP
estar con el siguiente formato:
EXPDP empleado/contrasea EXCLUDE=TABLE:\"LIKE \'TEMP%\'\"

Nota. Podemos especificar ms de una opcin EXCLUDE dentro de la misma tarea de Data Pump
Export.
Si no se proporciona valor para clusula, todos los objetos del tipo especificado son excluidos. Para excluir
todos los ndices, por ejemplo, podemos especificar lo siguiente:
EXPDP empleado/contrasea EXCLUDE=INDEX
Para obtener un listado de los objetos que podemos filtrar, podemos consultar las siguientes vistas del
diccionario de datos: DATABASE_EXPORT_OBJECTS, SCHEMA_EXPORT_OBJECTS y TABLE_EXPORT_OBJECTS.
Si el valor de tipo_objeto es CONSTRAINT, las restricciones NOT NULL no sern excluidas. Adems, las
restricciones necesarias para crear una tabla (como la de clave primaria para tablas organizadas por ndices)
tampoco sern excluidas. Si el valor de tipo_objeto es USER, se excluye la definicin del usuario, pero los
objetos dentro del esquema del usuario sern exportados. Se usa el valor SCHEMA en tipo_objeto para excluir
un usuario y todos los objetos que le pertenecen. Si el valor de tipo_objeto es GRANT, todos los objetos de
concesin y permisos del sistema sern excluidos.
Una segunda opcin, INCLUDE, tambin est disponible. Cuando se usa INCLUDE, slo aquellos objetos que
forman parte del criterio son exportados; todos los dems objetos son excluidos. INCLUDE y EXCLUDE son
mutuamente exclusivos. El formato de INCLUDE es:
INCLUDE = tipo_objecto [ : clusula ] [, ...]

Nota. No podemos especificar INCLUDE si especificamos CONTENT=DATA_ONLY.


Por ejemplo, para exportar dos tabla y todos los procedimientos, nuestro fichero de parmetros puede incluir
estas dos lneas:
INCLUDE=TABLE:"IN ('LIBROS','AUTORES')"
INCLUDE=PROCEDURE
Qu filas sern exportadas para los objetos que cumplen los criterios EXCLUDE o INCLUDE? Por defecto,
todos los registros son exportados para cada tabla. Podemos usar la opcin QUERY para limitar los registros
que son retornados. El formato para la opcin QUERY es:
QUERY = [ esquema . ] [ nombre_tabla : ] clusula
Si no especificamos valores para las variables esquema y nombre_tabla, la variable clusula se aplicar a todas las
tablas exportadas. Debido a que clusula normalmente incluye nombres de columnas especficas, deberamos

Oracle /209
ser muy cuidadosos cuando seleccionamos las tablas a incluir en la exportacin.
Podemos especificar un valor QUERY para una nica tabla, tal como se muestra a continuacin:
QUERY=LIBROS:'"WHERE IdLibro > 2"'
Como resultado, el fichero de volcado slo contendr aquellos registros que cumplan con el criterio.
Podemos aplicar tambin estas restricciones durante la subsiguiente Data Pump Import.
7.4. Opciones para Data Pump Import.
Para importar un fichero de volcado exportado mediante Data Pump Export, se usa Data Pump Import. Al
igual que el proceso de exportacin, el proceso de importacin se ejecuta como una tarea basada en servidor
que podemos gestionar durante su ejecucin. Podemos interactuar con Data Pump Import mediante la
interfaz de lnea de comandos, un fichero de parmetros y una interfaz interactiva.
Nota. El directorio para el fichero de volcado y el fichero de log debe existir previamente.
Al igual que con Data Pump Export, se soportan cinco modos: "Full", "Schema", "Table", "Tablespace" y
"Transportable Tablespace". Si no se especifica el modo, Oracle intenta cargar todos el fichero de volcado.
La siguiente tabla describe los parmetros de la interfaz de lnea de comandos.
Parmetro Descripcin
ATTACH Asocia el cliente a una sesin del servidor y sita el modo interactivo.
CONTENT Filtros que son importados: ALL, DATA_ONLY o METADATA_ONLY.
DIRECTORY Especifica la ubicacin del fichero de volcado asignado al directorio destino
para los ficheros de log y SQL.
DUMPFILE Especifica los nombres y, opcionalmente, los directorios para el fichero de
volcado asignado.
ESTIMATE Determina el mtodo usado para estimar el tamao del fichero de volcado
(BLOCKS o STATISTICS).
EXCLUDE Excluye objetos y datos que estn siendo importados.
FLASHBACK_SCN SCN de la base de datos para "flash back" durante la importacin.
FLASHBACK_TIME Timestamp de la base de datos para "flash back" durante la importacin.
FULL Valor Y/N usado para especificar si queremos importar el fichero de volcado
completo.
HELP Muestra ayudas en lnea para la importacin.
INCLUDE Especifica el criterio para los objetos que sern importados.
JOB_NAME Especifica un nombre para la tarea; el valor por defecto es asignado por el
sistema.
LOGFILE Nombre y nombre opcional del directorio para el fichero de log.
NETWORK_LINK Especifica el enlace de base de datos origen para una tarea Data Pump de
importacin a una base de datos remota.
NOLOGFILE Valor Y/N usando para suprimir la creacin del fichero de log.
PARALLEL Asigna el nmero de trabajadores para la tarea de Data Pump Import.
PARFILE Nombre del fichero de parmetros, si se usa.
QUERY Filtros de registros para tablas durante la importacin.
REMAP_DATAFILE Cambia el nombre del fichero de datos fuente para el fichero de datos
destino en los comandos CREATE LIBRARY, CREATE TABLESPACE y
CREATE DIRECTORY durante la importacin.
REMAP_SCHEMA Importa datos exportados desde el esquema fuente dentro del esquema
destino.
REMAP_TABLESPACE Importa datos exportados desde el tablespace fuente dentro del tablespace
destino.
REUSE_DATAFILES Especifica si ficheros de datos existentes deberan reutilizarse por el
comando CREATE TABLESPACE durante el modo de importacin "Full".
SCHEMAS Nombre del esquema a ser importado en el modo de importacin "Schema".
SKIP_UNUSABLE_INDEXES Valor Y/N. Si es Y, la importacin no carga datos dentro de tablas cuyos
ndices estn en el estado "Index Unusable".
SQLFILE Nombre del fichero en el cual el DDL para la importacin ser escrito. Los
datos y metadatos no sern cargados dentro de la base de datos destino.
STATUS Muestra detalles del estado de la tarea Data Pump.
STREAMS_CONFIGURATION Valor Y/N usado para especificar si se debe importar la informacin de

Oracle /210
configuracin de streams.
TABLE_EXISTS_ACTION Instruye cmo procesar la importacin si la tabla que est siendo importada
ya existe. Puede tomar los valores SKIP, APPEND, TRUNCATE y REPLACE. El
valor por defecto es APPEND si CONTENT=DATA_ONLY; si no, el valor por
defecto es SKIP.
TABLES Lista de tablas para el modo de importacin "Table".
TABLESPACES Lista de tablespaces para el modo de importacin "Tablespace".
TRANSFORM Dirige cambios a los atributos de segmento o al almacenaje durante la
importacin.
TRANSPORT_DATAFILES Lista los ficheros de datos a ser importados durante el modo de importacin
"Transportable Tablespace".
TRANSPORT_FULL_CHECK Especifica si los tablespaces que son importados deben primero verificarse
como autnomos.
TRANSPORT_TABLESPACES Lista los tablespaces que sern importados durante el modo de importacin
"Transportable Tablespace".
VERSION Especifica la versin de los objetos de base de datos que sern creados para
que el fichero de volcado sea compatible con versiones de Oracle previas.
Las opciones son COMPATIBLE, LATEST y el nmero de versin (no menor
que 10.0.0). Slo vlido para NETWORK_LINK y SQLFILE.
La siguiente tabla describe los parmetros que son vlidos en el modo interactivo de Data Pump Import.
Parmetro Descripcin
CONTINUE_CLIENT Finaliza el modo interactivo y entra en modo de registro. La tarea ser reiniciada si est
parada.
EXIT_CLIENT Finaliza la sesin de cliente, pero contina ejecutndose la tarea de servidor Data
Pump Import.
HELP Muestra ayuda en lnea para la importacin.
KILL_JOB Mata la tarea actual y desasocia las sesiones cliente relacionadas.
PARALLEL Modifica el nmero de trabajadores para la tarea Data Pump Import.
START_JOB Reinicia la tarea asociada.
STATUS Muestra detalles de estado para la tarea Data Pump.
STOP_JOB Para la tarea para reiniciarla despus.
Muchos de los parmetros de Data Pump Import son los mismos que los disponibles para Data Pump
Export.
7.5. Iniciando una tarea de Data Pump Import.
Podemos iniciar una tarea de Data Pump Import mediante el ejecutable IMPDP proporcionado con Oracle
Database 11g. Se usan los parmetros de la lnea de comandos para especificar el modo de importacin y la
localizacin de todos los ficheros. Podemos guardar estos valores de parmetros en un fichero de parmetro
que podemos referenciar a travs de la opcin PARFILE.
En el primer ejemplo de exportacin, el fichero de parmetros llamado dp1.par contena las siguientes
entradas:
Archivo dp1.par
DIRECTORY=DTPUMP
DUMPFILE=metadataonly.dmp
CONTENT=METADATA_ONLY
La importacin crear los objetos del esquema Empleado dentro de un esquema diferente. La opcin
REMAP_SCHEMA permite importar objetos dentro de un esquema diferente al usado para la exportacin. Si
queremos cambiar el tablespace asignado para los objetos al mismo tiempo, se usa la opcin
REMAP_TABLESPACE. El formato de REMAP_SCHEMA es:
REMAP_SCHEMA= esquema_fuente : esquema_destino
Crearemos una nueva cuenta de usuario para guardar estos objetos:
CREATE USER NuevoEmpleado IDENTIFIED BY contrasea;
GRANT CREATE SESSION TO NuevoEmpleado;
GRANT CONNECT, RESOURCE TO NuevoEmpleado;
GRANT IMP_FULL_DATABASE TO NuevoEmpleado;

Oracle /211
Podemos ahora aadir la lnea REMAP_SCHEMA al fichero de parmetros:
Archivo dp1.par
DIRECTORY=dtpump
DUMPFILE=metadataonly.dmp
CONTENT=METADATA_ONLY
REMAP_SCHEMA=Empleado:NuevoEmpleado
Ahora podemos empezar la importacin. Debido a que estamos cambiando el esquema propietario para los
datos, debemos tener el permiso de sistema IMP_FULL_DATABASE. La tarea de Data Pump Import se inicia a
travs del ejecutable IMPDP. El siguiente listado muestra cmo crear la tarea de importacin usando el fichero
de parmetros dp1.par.
IMPDP system/contrasea PARFILE=dp1.par

Nota. Deben especificarse todos los ficheros de volcado a la vez que se inicia la tarea.
Oracle comenzar entonces la importacin y mostrar su progreso. Debido a que no fue especificada la
opcin NOLOGFILE el archivo de log para la importacin ser ubicado en el mismo directorio que el fichero
de volcado, y tendr el nombre import.log. Podemos comprobar el resultado de la tarea registrndonos dentro
del esquema NuevoEmpleado. El esquema NuevoEmpleado debera tener una copia de todos los objetos vlidos
que fueron previamente creados en el esquema Empleado.
Qu ocurre si una tabla que est siendo importada ya existe? En este ejemplo, con la opcin CONTENT
asignada a METADATA_ONLY, la tabla debera ignorarse por defecto. Si la opcin CONTENT estuviese asignada
a DATA_ONLY, los nuevos datos sern aadidos a la tabla existente. Para modificar este comportamiento se
usan la opcin TABLE_EXISTS_ACTION. Valores vlidos para este opcin son SKIP (ignorar), APPEND (aadir),
TRUNCATE (truncar) y REPLACE (reemplazar).
7.5.1. Parando y reiniciando las tareas.
Despus de iniciar una tarea Data Pump Import, podemos cerrar la ventana cliente que usamos para iniciar la
tarea. Ya que est basada en servidor, la importacin continuar ejecutndose. Podemos asociarnos a la tarea,
comprobar su estado y modificarla.
IMPDP system/contrasea PARFILE=dp1.par
Presionando las teclas CTRL-C regresamos a la pantalla de registro, y Data Pump regresar al indicador Import:
Import>
Podemos salir del sistema mediante el comando EXIT_CLIENT:
Import> EXIT_CLIENT
Podemos entonces reiniciar el cliente y asociarnos a la tarea que se ejecute actualmente bajo nuestro esquema:
IMPDP system/contrasea ATTACH
Si hemos dado un nombre a la tarea, podemos usarlo como parte del parmetro ATTACH para asociarnos a la
tarea. Cuando nos asociamos a una tarea, Data Pump muestra el estado de la tarea. Podemos entonces
introducir el comando CONTINUE_CLIENT para ver las entradas de log generadas, o podemos modificar la
tarea:
Import> CONTINUE_CLIENT
Podemos parar una tarea mediante la opcin STOP_JOB:
Import> STOP_JOB
Mientras la tarea est parada, podemos incrementar su paralelismo mediante la opcin PARALLEL. Y despus
podemos reiniciar la tarea:
Import> START_JOB
7.5.2. EXCLUDE, INCLUDE y QUERY.
Data Pump Import, como Data Pump Export, permite restringir el procesado de datos mediante el uso de las
opciones EXCLUDE, INCLUDE y QUERY, tal como se ha descrito previamente.
Por ejemplo, podemos elegir exportar una tabla entera pero slo importar parte de la misma (los registros que
cumplen el criterio de QUERY). Podemos elegir para exportar un esquema entero pero cuando recuperemos la
base de datos mediante importacin incluir slo las tablas necesarias. EXCLUDE, INCLUDE y QUERY
proporciona poderosas capacidades a los programadores y administradores de base de datos durante las tareas
de exportacin e importacin.
7.5.3. Transformacin de objetos importados.
Adems de cambiar o seleccionar esquemas, tablespaces, ficheros de datos y registros durante la importacin,
podemos cambiar los atributos de segmento y requerimientos de almacenaje durante la importacin mediante

Oracle /212
la opcin TRANSFORM. El formato de TRANSFORM es:
TRANSFORM = nombre_transformacin : valor [ : tipo_objeto ]
La variable nombre_transformacin puede tomar los valores SEGMENT_ATTRIBUTES o STORAGE. Se puede usar el
valor de la variable para incluir o excluir atributos de segmento (atributos fsicos, atributos de almacenaje,
tablespaces y logging). La variable tipo_objeto es opcional y, si se especifica, debe ser TABLE o INDEX.
Por ejemplo, los requerimientos de almacenamiento de objetos puede cambiar durante la
exportacin/importacin (se puede usar la opcin QUERY para limitar las filas importadas, o podemos
importar slo los metadatos sin los datos de la tabla). Para eliminar las clusulas de almacenamiento
exportadas de las tablas importadas hay que aadir lo siguiente al fichero de parmetros:
TRANSFORM=STORAGE:n:tabla
Para eliminar los tablespaces exportados y clusulas de almacenamiento de todas las tablas e ndices, se usa lo
siguiente:
TRANSFORM=SEGMENT_ATTRIBUTES:n
Cuando los objetos son importados, sern asignados a los tablespaces por defecto del usuario y usarn los
parmetros de almacenamiento de estos tablespaces por defecto.
7.5.4. Generacin de SQL.
En vez de importar los datos y objetos, podemos generar el SQL para los objetos (no los datos) y almacenarlo
en un fichero de nuestro sistema operativo. El fichero ser escrito en el directorio especificado mediante la
opcin SQLFILE. El formato de la opcin SQLFILE es:
SQLFILE=[ objeto_directorio : ] nombre_fichero

Nota. Si no se especifica un valor para la variable objeto_directorio, el fichero ser creado en el


directorio del fichero de volcado.
Lo siguiente muestra un ejemplo de fichero de parmetros para una importacin usando la opcin SQLFILE.
Ntese que la opcin CONTENT no est especificada. La salida ser escrita en el directorio dtpump.
DIRECTORY=dtpump
DUMPFILE=metadataonly.dmp
SQLFILE=sql.txt
Podemos entonces ejecutar la importacin para poblar el fichero sql.txt:
IMPDP Empleado/contrasea PARFILE=dp1.par
En el fichero sql.txt que crea la importacin, podemos ver entradas para cada tipo de objeto dentro del
esquema. El formato del fichero de salida ser similar al siguiente listado. (Para abreviar no se han incluido
todas las entradas.)
-- CONNECT Empleado
-- new object type path is: SCHEMA_EXPORT/
SE_PRE_SCHEMA_PROCOBJACT/PROCACT_SCHEMA
BEGIN
sys.dbms_logrep_imp.instantiate_schema(schema_name=>'Empleado',
export_db_name=>'ORCL', inst_scn=>'3377908');
COMMIT;
END;
/
-- new object type path is: SCHEMA_EXPORT/TYPE/TYPE_SPEC
CREATE TYPE "Empleado"."Direccion"
OID '48D49FA5EB6D447C8D4C1417D849D63A' as object
(Calle VARCHAR2(50),
Ciudad VARCHAR2(25),
Region CHAR(20),
CP NUMBER);
/
CREATE TYPE "Empleado"."Cliente"
OID '8C429A2DD41042228170643EF24BE75A' as object
(IdCliente NUMBER,
Nombre VARCHAR2(25),
Calle VARCHAR2(50),
Ciudad VARCHAR2(25),

Oracle /213
Region CHAR(20),
CP NUMBER);
/
CREATE TYPE "Empleado"."Persona"
OID '76270312D764478FAFDD47BF4533A5F8' as object
(Nombre VARCHAR2(25),
Direccion Direccion);
/
-- new object type path is: SCHEMA_EXPORT/TABLE/TABLE
CREATE TABLE "Empleado"."Cliente"
( "IdCliente" NUMBER,
"Nombre" VARCHAR2(25),
"Calle" VARCHAR2(50),
"Ciudad" VARCHAR2(25),
"Region" CHAR(20),
"CP" NUMBER
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" ;
...
La salida SQLFILE es un fichero de texto plano, as que podemos editarlo, usarlo dentro de SQL*Plus, o
aadirlo como documentacin de las estructuras de nuestra aplicacin de base de datos.
7.5.5. Comparando Data Pump Export/Import con Export/Import.
Las utilidades originales Export e Import estn todava disponibles mediante los ejecutables EXP e IMP. Como
se ha visto, poseen muchas capacidades superiores respecto a las utilidades originales. La arquitectura basada
en servidor de Data Pump conduce a beneficios de rendimiento y gestin mejorada. Sin embargo, Data Pump
no soporta capacidades de confirmacin incrementales ofrecidas por los parmetros COMMIT y BUFFER del
Import original. Tampoco Data Pump combina automticamente varias extensiones dentro de una nica
extensin durante el proceso Data Pump Export/Import; los originales Export/Import ofrecen esta
funcionalidad mediante el parmetro COMPRESS. En Data Pump podemos usar la opcin TRANSFORM para
suprimir los atributos de almacenamiento durante la importacin (una opcin que muchos usuarios del
original Export/Import puede preferir a la funcionalidad COMPRESS).
Si estamos importando mediante Data Pump dentro de una tabla existente usando las variantes APPEND o
TRUNCATE de la opcin TABLE_EXISTS_ACTION y un registro viola una restriccin activa, la carga se para y
los datos no son cargados. En el Import original, la carga habra continuado.
8. Acceso a datos remotos
Como nuestras bases de datos aumentan en tamao y nmero, es habitual la necesidad de compartir datos
entre ellas. Compartir datos requiere un mtodo para localizar y acceder a los datos. En Oracle, los datos
remotos son accedidos mediante consultas y actualizaciones realizadas a travs de enlaces de base de datos.
Los enlaces de base de datos permiten a los usuarios tratar un grupo de base de datos distribuidas como si
fuese una nica e integrada base de datos.
8.1. Enlaces de base de datos.
Un enlace de base de datos le dice a Oracle cmo ir de una base de datos a otra. Podemos especificar la ruta
de acceso de una manera ad hoc (usando el comando de copia de SQL*Plus). Si usamos frecuentemente la
misma conexin a una base de datos remota, un enlace de base de datos es lo apropiado.
8.1.1. Cmo trabaja un enlace de base de datos.
Un enlace de base de datos requiere que Oracle Net (previamente conocido como SQL*Net y Net8) se est
ejecutando sobre cada mquina (host) involucrada en el acceso remoto. Oracle Net es normalmente iniciado
por el administrador de base de datos (DBA) o el administrador del sistema. Una arquitectura simple para un
acceso remoto usando enlaces de base de datos se muestra en la siguiente figura:

Oracle /214
BASE DE Enlace de BASE DE DATOS
DATOS base de REMOTA
LOCAL datos

Host Perifrico Host Central


La figura muestra dos hosts, cada uno de los cuales ejecuta Oracle Net. Un enlace de base de datos establece
una conexin desde la primera base de datos (llamada LOCAL en el host perifrico) a la segunda base de datos
(llamada REMOTA en el host central).
Un enlace de base de datos especifica la siguiente informacin de conexin:
El protocolo de comunicacin (como TCP/IP) que se usa durante la conexin.
El host en el cual reside la base de datos remota.
El nombre de la base de datos en el host remoto.
El nombre de una cuenta vlida en la base de datos remota.
La contrasea de la cuenta.
Cuando se usa, un enlace de base de datos se registra como un usuario en la base de datos remota y se
desconecta cuando el acceso de datos remotos se completa. Un enlace de base de datos puede ser privado,
propiedad de un nico usuario, o pblico, en cuyo caso todos los usuarios de la base de datos LOCAL pueden
usar el enlace.
8.1.2. Sintaxis para enlaces de base de datos.
Podemos crear un enlace de base de datos con el siguiente comando:
CREATE [SHARED] [PUBLIC] DATABASE LINK nombre_conexion_remota
CONNECT TO {CURRENT_USER | usuario IDENTIFIED BY contrasea [ clusula de autentificacin ]}
USING 'cadena de conexin' ;
La sintaxis especfica para usar cuando creamos un enlace de base de datos depende de dos criterios:
El estado "pblico" o "privado" del enlace.
El uso de registros explcitos o por defecto de la base de datos remota.
Estos criterios y su sintaxis asociada se describen en las siguientes secciones.
Nota. Para crear un enlace privado de base de datos debemos tener el permiso de sistema CREATE
DATABASE LINK, y para crear un enlace pblico el permiso CREATE PUBLIC DATABASE LINK. La
cuenta a la cual queramos conectarnos en la base de datos remota debe tener el permiso de sistema
CREATE SESSION. Estos dos permisos se incluyen como parte del rol CONNECT de Oracle, aunque
en Oracle Database 11g este rol slo existe para compatibilidad.
Si el valor del parmetro de inicializacin GLOBAL_NAMES es TRUE, el enlace de base de datos debe tener el
mismo nombre que la base de datos a la que se conecta. Si el valor de este parmetro es FALSE y hemos
cambiado el nombre global de la base de datos, podemos especificar el nombre global.
Enlaces de base de datos pblicos frente a privados.
Un enlace de base de datos pblico est disponible para todos los usuarios de la base de datos. Por el
contrario, un enlace privado slo est disponible para el usuario que lo cre. No es posible para un usuario
conceder permiso sobre un enlace privado a otro usuario. Un enlace debe ser pblico o bien privado.
Para especificar que un enlace es pblico se usa la palabra clave PUBLIC en el comando CREATE DATABASE
LINK, tal como se muestra a continuacin:
CREATE PUBLIC DATABASE LINK Conexion_Remota
CONNECT TO Empleado IDENTIFIED BY contrasea
USING 'la cadena de conexin' ;
Si no se especifica PUBLIC el enlace es por defecto privado.
Nota. Para crear un enlace de base de datos pblico debemos tener el permiso de sistema CREATE
PUBLIC DATABASE LINK. Este permiso est incluido en el rol DBA de Oracle, aunque en Oracle
Database 11g este rol existe slo por compatibilidad.
Registro por defecto frente a registro explcito.
En lugar de la clusula CONNECT TO IDENTIFIED BY podemos usar CONNECT TO CURRENT_USER cuando
creamos un enlace. Si se usa la opcin CURRENT_USER, entonces al usar el enlace se intentar abrir una sesin

Oracle /215
en la base de datos remota que tenga el mismo nombre de usuario y contrasea que la cuenta de la base de
datos local. Esto se denomina un registro por defecto.
El siguiente listado muestra un ejemplo de un enlace creado con un registro por defecto:
CREATE PUBLIC DATABASE LINK Conexion_Remota
CONNECT TO CURRENT_USER
USING 'HQ';

Nota. El registro por defecto se conecta a la base de datos remota como un usuario global.
Cuando se use este enlace se intentar registrarse en la base de datos remota identificada por el nombre de
servicio 'HQ' usando el nombre de usuario y contrasea del usuario actual. Si el usuario actual no es vlido en
la base de datos remota, o si la contrasea es diferente, el intento de registro fallar. Este fallo provocar que
el comando SQL que use el enlace falle.
Un registro explcito debe especificar el nombre de usuario y contrasea que usar el enlace mientras se
conecte a la base de datos remota. No importa qu cuenta local use el enlace, se usar la misma cuenta
remota. El listado siguiente muestra la creacin de un enlace con una conexin explcita
CREATE PUBLIC DATABASE LINK Conexion_Remota
CONNECT TO Empleado IDENTIFIED BY contrasea
USING 'HQ';
Este ejemplo muestra un uso normal del registro explcito en un enlace de base de datos. En la base de datos
remota debe existir un usuario llamado Empleado con la contrasea correspondiente. La cuenta Empleado debe
tener concedido el acceso SELECT para las tablas especificadas, nicamente para ser usado por el enlace. El
enlace Conexion_Remota entonces proporciona acceso a la cuenta remota para todos los usuarios locales.
Sintaxis de la cadena de conexin.
Oracle Net usa un nombre de servicio para identificar conexiones remotas. Los detalles de conexin de este
nombre de servicio estn contenidos en fichero que son distribuidos en cada host de la red. Cuando se
encuentra un nombre de servicio, Oracle verifica el fichero de configuracin local de Oracle Net (llamado
tnsnames.ora) para determinar qu protocolo, nombre de host y nombre de base de datos se usar durante la
conexin. Toda la informacin de conexin se encuentra en ficheros externos.
Cuando se usa Oracle Net, debemos conocer el nombre del servicio que apunta a la base de datos remota.
Por ejemplo, si el nombre del servicio HQ especifica los parmetros de conexin para la base de datos que
necesitamos, entonces deberemos usar HQ como la cadena de conexin en el comando CREATE DATABASE
LINK. El siguiente ejemplo muestra un enlace de base de datos privado usando registro por defecto en un
nombre de servicio de Oracle Net:
CREATE DATABASE LINK Conexion_Remota
CONNECT TO CURRENT_USER
USING 'HQ';
Cuando se usa este enlace, Oracle comprueba el fichero tnsnames.ora en el host local para determinar a qu
base de datos debe conectarse.
Los ficheros tnsnames.ora de una red de base de datos deberan ser coordinados por los DBA's de las base de
datos. Una entrada tpica en el fichero tnsnames.ora (para una red que use el protocolo TCP/IP) se muestra a
continuacin:
HQ =(DESCRIPTION=
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL=TCP) (HOST=host1) (PORT=1521))
)
(CONNECT DATA=
(SERVICE_NAME = HQ.host1)
)
)
En este listado, el nombre de servicio HQ se mapea a un descriptor de conexin que le dice a la base de datos
qu protocolo usar (TCP/IP) y a qu host (host1) y base de datos (HQ) conectarse. La informacin PORT se
refiere al puerto a travs del cual el host podr ser conectado; este dato es especfico para cada servidor
(aunque Oracle Listener usa por defecto el puerto 1521). Cada protocolo incluye sus propias palabras clave,
pero todos ellos contendrn el mismo tipo de informacin.
La cadena de conexin puede tambin utilizar directamente la definicin TNS (esto posibilita que no
tengamos que modificar el fichero tnsnames.ora).

Oracle /216
CREATE DATABASE LINK nombre_del_enlace
CONNECT TO usuario IDENTIFIED BY contrasea
USING '(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP)
(HOST=localhost)
(PORT=1521) )
(CONNECT_DATA=
(SID=base_de_datos) )
)';
Usando enlaces de base de datos compartidos.
Si usamos la opcin Shared Server para nuestras conexiones de base de datos y nuestra aplicacin emplea
muchas conexiones de enlaces concurrentes, podemos beneficiarnos de usar enlaces compartidos. Un enlace
compartido usa conexiones de servidor estticas para soportar las conexiones de los enlaces. Si tenemos
varios accesos de enlaces concurrentes dentro de una base de datos remota, podemos usar enlaces
compartidos para reducir el nmero de conexiones de servidor requeridas.
Para crear un enlace compartido se usa la palabra clave SHARED en el comando CREATE DATABASE LINK.
Como se muestra en el siguiente ejemplo, tambin necesitamos especificar un esquema y contrasea para la
base de datos remota:
CREATE SHARED PUBLIC DATABASE LINK HR_Enlace_Estatico
CONNECT TO CURRENT_USER
AUTHENTICATED BY hr IDENTIFIED BY contrasea
USING 'HQ';
El enlace HR_Enlace_Estatico se crea como pblico, y usa el nombre de usuario y contrasea actuales cuando
accede a la base de datos 'HQ'. Para prevenir intentos no autorizados de usar el enlace compartido, este tipo
de enlaces requieren la clusula AUTHENTICATED BY. En este ejemplo, la cuenta usada para la autentificacin
es una cuenta de la aplicacin, pero tambin podemos usar un esquema vaco para la autentificacin. La
cuenta de autentificacin debe tener el permiso de sistema CREATE SESSION. Durante el uso del enlace
HR_Enlace_Estatico los intentos de conexin incluirn autentificacin a travs de la cuenta enlazada hr.
Si cambiamos la contrasea en la cuenta de autentificacin, necesitaremos borrar y re-crear cada enlace que la
referencie. Para simplificar el mantenimiento, lo mejor es crear una cuenta que slo sea usada para la
autentificacin de conexiones de enlaces compartidos. La cuenta debera tener slo el permiso de sistema
CREATE SESSION y no debera tener ningn otro permiso sobre ninguna tabla de la aplicacin.
Si nuestra aplicacin usa enlaces de base de datos infrecuentemente, deberamos usar enlaces tradicionales sin
la clusula SHARED. Sin esta clusula, cada conexin de enlace requerir una conexin independiente a la base
de datos remota.
8.1.3. Usando un enlace de base de datos para consultas remotas.
Si somos un usuario de la base de datos LOCAL de la figura previa, podemos acceder a los objetos de la base
de datos REMOTA a travs del enlace de base de datos. Para hacer esto, simplemente se aade el nombre del
enlace al nombre de cualquier tabla o vista que sea accesible en la cuenta remota. Cuando aadimos el
nombre del enlace a un nombre de tabla o vista, debemos precederlo con el smbolo @.
Para tablas locales referenciamos el nombre de la tabla en la clusula FROM:
SELECT * FROM Libro;
Como ejemplo, para tablas remotas usaremos el nombre de enlace CONEXIN_REMOTA. En la clusula FROM
referenciaremos el nombre de la tabla seguido de @CONEXION_REMOTA:
SELECT * FROM Libro@CONEXION_REMOTA;
Cuando se usa el enlace de esta consulta, Oracle se registra en la base de datos remota usando el nombre de
usuario y contrasea especificado en la creacin del enlace. Entonces se consulta la tabla Libro en la cuenta
remota y se retornan los datos al usuario que inici la consulta. Esto se muestra grficamente en la siguiente
figura:

SELECT * FROM Enlace de


Libro@CONEXION_REMOTA base de SELECT * FROM Libro
datos

Oracle /217
Nota. El nmero mximo de enlaces de base de datos que podemos usar en una nica consulta se
establece en el parmetro OPEN_LINKS dentro del fichero de inicializacin de parmetros de la base
de datos. Este parmetro tiene por defecto el valor 4.
Las consultas que usan enlaces de base de datos tienen algunas restricciones. Deberamos evitar enlaces en
consultas que usen las palabras claves CONNECT BY, START WITH y PRIOR. Algunas consultas que usen estas
palabras trabajarn (por ejemplo, si PRIOR no se usa fuera de la clusula CONNET BY, y START WITH no usa
una subconsulta), pero para muchos usuarios de consultas jerrquicas fallar si se usan enlaces de base de
datos.
8.1.4. Usando un enlace de base de datos para sinnimos y vistas.
Podemos crear sinnimos y vistas locales que referencien objetos remotos. Para hacer esto se referencia el
nombre del enlace de base de datos precedido del smbolo @, en cualquier parte donde se referencie una tabla
remota. El siguiente ejemplo muestra cmo hacer esto para sinnimos. El comando CREATE SYNONYM de
este ejemplo es ejecutado desde una cuenta de la base de datos local.
CREATE SYNONYM Libro_Syn FOR Libro@CONEXION_REMOTA;
En este ejemplo, un sinnimo llamado Libro_Syn se crea para acceder a la tabla Libro a travs del enlace
CONEXION_REMOTA. Cada vez que se use este sinnimo es la clusula FROM de una consulta, se consultar la
base de datos remota.
Qu ocurre si la cuenta remota a la que accede el enlace de base de datos no es propietaria de la tabla
referenciada? En este caso podemos usar cualquier sinnimo disponible en la cuenta remota (privado o
pblico). Si no existen sinnimos para una tabla para la que cuenta remota tiene permisos de acceso, debemos
especificar el nombre del propietario de la tabla en la consulta, tal como se muestra en el siguiente ejemplo:
CREATE SYNONYM Libro_Syn FOR Empleado.Libro@CONEXION_REMOTA;
En este ejemplo, la cuenta remota usada por el enlace no es propietaria de la tabla Libro, y la cuenta remota no
tiene un sinnimo llamado Libro. Sin embargo, tiene permisos sobre la tabla Libro, que es propiedad del
usuario remoto Empleado en la base de datos remota. As pues, debemos especificar el propietario y el nombre
de la tabla; ambos son interpretados en la base de datos remota.
Para usar un enlace en una vista simplemente se aade como un sufijo a los nombres de las tablas en el
comando CREATE VIEW. El siguiente ejemplo crea una vista en la base de datos local de una tabla remota
usando el enlace CONEXIN_REMOTA:
CREATE VIEW Local_Libro_View AS
SELECT * FROM Libro@CONEXION_REMOTA WHERE Titulo >'M';
Esta vista puede ahora ser tratada de la misma manera que cualquier otra vista en la base de datos local. El
acceso a esta vista puede concederse a otros usuarios, a condicin de que estos usuarios tengan acceso al
enlace CONEXIN_REMOTA.
8.1.5. Usando un enlace de base de datos para actualizaciones remotas.
La sintaxis de enlaces de base de datos para actualizaciones remotas es la misma que para consultas remotas.
Se aade el nombre del enlace al nombre de la tabla que se quiere actualizar. Por ejemplo, para cambiar la
categora de libros en la tabla remota Libro, podemos ejecutar el comando UPDATE tal como se muestra a
continuacin:
UPDATE Libro@CONEXION_REMOTA
SET Categoria = 'JUVENIL'
WHERE Categoria = 'INFANTIL';
Podemos usar subconsultas en la parte SET
del comando UPDATE. En las subconsultas podemos referenciar
tanto tablas locales como remotas aplicando la sintaxis correspondiente. Se muestra un ejemplo a
continuacin:
UPDATE Libro@CONEXION_REMOTA /* en base de datos remota */
SET Categoria =
(SELECT Categoria
FROM Libro@CONEXION_REMOTA /* en base de datos remota */
WHERE Titulo = 'Alicia')
WHERE Titulo = 'Pincho';
Si en la subconsulta no se usase el nombre de enlace, entonces se usara una tabla Libro de la base de datos
local.
8.2. Usando sinnimos para transparencia de localizacin.
Durante la vida til de una aplicacin, los datos con mucha probabilidad se movern de una base de datos a
Oracle /218
otra, de un host a otro. Por lo tanto, simplificar el mantenimiento de la aplicacin que la posicin fsica
exacta de un objeto de base de datos est protegida del usuario (y de la aplicacin).
El mejor modo de implementar esta transparencia de localizacin es usando sinnimos. En vez de escribir
aplicaciones (o informes de SQL*Plus) que contengan consultas especificando el propietario de las tablas,
como la siguiente consulta:
SELECT * FROM Empledo.Libro;
Podemos crear un sinnimo para esta tabla y entonces usar el sinnimo en la consulta, como se hace a
continuacin:
CREATE PUBLIC SYNONYM Libro FOR Empleado.Libro;
/
SELECT * FROM Libro;
La lgica requerida para encontrar los datos de esta manera ha sido trasladada de la aplicacin a la base de
datos. Mover la lgica de localizacin de la tabla a la base de datos ser un beneficio si alguna vez necesitamos
mover la tabla de un esquema a otro.
Adems de ocultar el propietario de la tabla a la aplicacin, podemos ocultar la localizacin fsica de los datos
que usan los enlaces de base de datos y sinnimos. Usando sinnimos locales para tablas remotas creamos
una capa de lgica entre la aplicacin y la base de datos. Por ejemplo, el sinnimo local Libro se define a
continuacin para referenciar una tabla localizada en otra base de datos remota sobre un host diferente. Si la
tabla se mueve en el futuro, slo necesitaremos cambiar el enlace; el cdigo de la aplicacin, cuando usa
sinnimos, no necesita ser cambiado.
CREATE PUBLIC SYNONYM Libro
FOR Libro@CONEXION_REMOTA;
Si la cuenta remota usada por el enlace no es la propietaria del objeto referenciado, tenemos dos opciones.
Primero, podemos referenciar un sinnimo disponible en la base de datos remota:
CREATE PUBLIC SYNONYM Libro
FOR Libro_Syn@CONEXION_REMOTA;
Aqu, Libro_Syn, en la cuenta remota, es un sinnimo
para la tabla Libro remota.
Segundo, podemos incluir el nombre del propietario remoto cuando creamos el sinnimo local, tal como se
muestra a continuacin:
CREATE PUBLIC SYNONYM Libro
FOR Empleado.Libro@CONEXION_REMOTA;
Estos dos ejemplo producirn la misma funcionalidad en nuestras consultas, pero hay una diferencia entre
ellas. El segundo ejemplo, que incluye el nombre del propietario, es potencialmente ms difcil de mantener
ya que no usa un sinnimo en la base de datos remota, y si el objeto remoto se mueve posteriormente
invalidar nuestro sinnimo local.
8.3. Usando la pseudo-columna USER en vistas.
La pseudo-columna USER es muy til cuando usamos mtodos de acceso remoto a datos. Por ejemplo,
podemos querer que no todos los usuarios remotos vean todos los registros de una tabla. Para resolver este
problema podemos pensar en los usuarios remotos como usuarios especiales de nuestra base de datos. Para
forzar la restriccin sobre los datos necesitamos crear una vista a la que puedan acceder cuentas remotas.
Pero, qu podemos usar en la clusula WHERE para restringir apropiadamente los registros? La pseudo-
columna USER, combinada con los nombres de usuario apropiados permite forzar estas restricciones.
La pseudo-columna USER es una "columna" que retorna el usuario actual de Oracle cuando es seleccionada,
pero no es una columna actual de la tabla. As, si una columna de la tabla contiene nombres de usuarios, estos
valores pueden compararse con el valor de la pseudo-columna USER para restringir los registros, tal como se
muestra a continuacin. En este ejemplo, se consulta la columna Nombre en cada registro. Si el valor de la
primera parte de la columna Nombre es el mismo que el nombre del usuario que realiz la consulta, se
retornarn estos registros.
CREATE VIEW Mis_Libros AS
SELECT * FROM Libro WHERE SUBSTR(Nombre, 1, INSTR(Nombre,'') - 1) = USER;
Cuando restrinjamos el acceso remoto los registros de nuestra tabla, primero debemos considerar qu
columnas seran las mejores para usar en la restriccin. Normalmente hay divisiones lgicas en los datos de
nuestra tabla, como un departamento o una regin. Por cada divisin diferente crearemos una cuenta de
usuario en nuestra base de datos local. Para este ejemplo, aadiremos la columna Region a la tabla Libro. Ahora
habilitaremos la lista de libros para varias localizaciones distribuidas en una nica tabla:

Oracle /219
ALTER TABLE Libro
ADD (Region VARCHAR2(10));
Supongamos que tenemos 4 regiones representadas en nuestra tabla Libro, y que hemos creado una cuenta de
Oracle para cada regin (asumamos que las regiones se llaman NORTE, SUR, ESTE, OESTE). Para cada una de
estas regiones se crea una base de datos. Podemos entonces crear enlaces de base de datos para que sean
usados por los usuarios especficos en nuestra base de datos local. Por ejemplo, los miembros del
departamento SUR deberan usar el enlace mostrado a continuacin:
CREATE DATABASE LINK Enlace_Sur
CONNECT TO SUR IDENTIFIED BY contrasea
USING 'HQ';
Cuando los usuarios remotos consultan a travs de los enlaces (como el enlace Enlace_Sur) son registrados
dentro de la base de datos HQ con el nombre de la regin. Por lo tanto, el valor de la columna USER para
cualquier tabla que el usuario consulte ser SUR.
Ahora creamos una vista de nuestra tabla base, comparando la pseudo-columna USER al valor de la columna
Region:
CREATE OR REPLACE VIEW Libro_Restringido
AS SELECT * FROM Libro WHERE Region = USER;
Un usuario que se conecte a travs del enlace Enlace_Sur (y por tanto se registra remotamente como el usuario
SUR) debera slo ser capar de ver los registros cuya regin sea 'SUR'.
Este tipo de restriccin tambin puede realizarse en la base de datos remota en vez de en la base de datos
donde reside la tabla. Los usuarios de la base de datos remota pueden crear vistas sobre sus bases de datos de
la siguiente forma:
CREATE OR REPLACE VIEW Sur_Libros
AS SELECT * FROM Libro@CONEXION_REMOTA WHERE Region = 'SUR';
En este caso, la restriccin sobre Region est todava vigente, pero es administrada localmente. La eleccin
entre estos dos tipos de opciones de restriccin (local o remota) se basa en el nmero de cuentas requeridas
para la restriccin. Para asegurar nuestra base de datos de produccin, deberamos limitar los permisos
concedidos a las cuentas usadas en enlaces de base de datos. Concediendo estos permisos a travs de roles, y
usando vistas (con la clusula READ ONLY o WITH CHECK OPTION) conseguimos limitar la capacidad de estas
cuentas para realizar cambios no autorizados en los datos.
8.4. Enlaces dinmicos: usando el comando de copia de SQL*Plus.
El comando de copia de SQL*Plus permite que los datos sean copiados entre bases de datos (o dentro de la
misma base de datos) a travs de SQL*Plus. Aunque nos permite seleccionar las columnas a copiar, trabaja
mejor cuando se eligen todas las columnas de la tabla. El gran beneficio de usar este comando es la habilidad
de confirmar despus de que cada conjunto de datos ha sido procesado. Esto a su vez genera transacciones
que son de un tamao manejable.
Nota. El comando de copia no ha cambiado desde Oracle8i. Este comando quedar obsoleto en
futuras versiones.
Consideremos el caso de una tabla grande, como Libro. Supongamos que la tabla Libro tiene 100.000 registros
que usan un espacio total de 100MB, y necesitamos hacer una copia de esta tabla en otra base de datos. La
opcin ms sencilla consiste en crear un enlace de base de datos y entonces usar este enlace en un comando
CREATE TABLE AS SELECT, tal como se muestra a continuacin:
CREATE DATABASE LINK CONEXION_REMOTA
CONNECT TO Empleado IDENTIFIED BY contrasea
USING 'HQ';
/
CREATE TABLE Libro AS
SELECT * FROM Libro@CONEXION_REMOTA;
El primer comando crea el enlace de base de datos, y el segundo crea una nueva tabla basada en todos los
datos de la tabla remota.
Desafortunadamente, esta opcin crea una transaccin muy larga (todos los 100.000 registros sern insertados
en la nueva tabla dentro de una nica transaccin), que pone una carga grande sobre las estructuras internas
de Oracle llamada segmentos de rollback. Los segmentos de rollback y la funcionalidad de deshacer
gestionada por el sistema almacenan la imagen previa de los datos hasta que los nuevos datos son

Oracle /220
confirmados en la base de datos. Ya que esta tabla est siendo poblada en una nica operacin de insercin,
se genera una transaccin larga que puede exceder el espacio disponible en los segmentos de rollback actuales.
Este fallo provocar que la creacin de la tabla falle.
Para romper la transaccin en entradas pequeas se usa el comando COPY de SQL*Plus, el cual tiene la
siguiente sintaxis:
COPY FROM
[usuario_remoto/contrasea_remota@cadena_de_conexin]
[TO usuario/contrasea@cadena_de_conexin]
{APPEND|CREATE|INSERT|REPLACE}
nombre_tabla
USING subconsulta;
Si la cuenta actual es la destinataria de los datos copiados, la palabra TO y el usuario, contrasea y cadena de
conexin local no son necesarios. Si la cuenta actual es el origen de los datos copiados, la informacin de la
conexin remota no es necesaria.
Para asignar el tamao de la transaccin se usa el comando SET de SQL*Plus para dar un valor al parmetro
ARRAYSIZE. Esto determina el nmero de registros que sern enviados en cada lote. El parmetro
COPYCOMMIT le dice a SQL*Plus cuntos lotes deberan ser confirmados de cada vez.
El siguiente script SQL*Plus realiza la misma copia de la tabla Libro; sin embargo, rompe la transaccin simple
en varias transacciones. En este ejemplo, los datos son confirmados despus de cada 1.000 registros. Esto
reduce el tamao de los segmentos de rollback de la transaccin de 100MB a 1MB.
SET COPYCOMMIT 1
SET ARRAYSIZE 1000
COPY FROM Empleado/contrasea@HQ -
CREATE Libro -
USING -
SELECT * FROM Libro

Nota. Excepto para la ltima lnea, cada lnea del comando COPY debe terminar con un guin
porque es un comando de SQL*Plus.
Hay varias opciones dentro del comando COPY:
Opcin Explicacin
APPEND Inserta los registros dentro de la tabla destino. Automticamente crea la tabla si no existe
previamente.
CREATE Crea la tabla y entonces inserta los registros.
INSERT Inserta los registros dentro de la tabla destino si existe; si no existe retorna un error. Cuando se usa
INSERT, deben especificarse todas las columnas en la subconsulta.
REPLACE Borra la tabla destino existente y la reemplaza con una nueva tabla con los datos copiados.
La interaccin proporcionada por el comando COPY puede ser confusa al principio. Despus de que se
complete la ltima confirmacin, la base de datos informa al usuario del nmero de registros que han sido
confirmados en el ltimo lote. No informa del nmero total de registros confirmados (a menos que se haya
confirmado un nico registro).
8.5. Conectndose a una base de datos remota.
Adems de la conexin entre base de datos descrita previamente, podemos conectarnos directamente a una
base de datos remota a travs de la herramienta SQL*PLUS de Oracle. Por lo tanto, en vez de escribir:
SQLPLUS usuario/contrasea
Y acceder a nuestra base de datos local, podemos ir directamente a una base de datos remota. Para hacer esto,
escribiremos nuestro nombre de usuario y contrasea junto con la cadena de conexin de Oracle Net para
bases de datos remotas:
SQLPLUS usuario/contrasea@HQ
Este comando nos registrar directamente en la base de datos HQ. La configuracin host para este tipo de
registro se muestra en la siguiente figura.

Oracle /221
Oracle Database +
Oracle Net
Base de datos HQ

Herramientas Oracle + Oracle Net SQL>


SQLPULS usuario/contrasea@HQ

Host Perifrico Host Central


El host perifrico tiene la herramientas de Oracle (como SQL*Plus) y est ejecutando Oracle Net, y el host
central ejecuta Oracle Net y una base de datos de Oracle. Puede haber o no una base de datos en el host
perifrico; especificando la cadena de conexin a la base de datos remota se fuerza a Oracle a ignorar
cualquier base de datos local.
9. Vistas materializadas.
Para aumentar el rendimiento de una aplicacin, podemos hacer copias locales de tablas remotas que usan
datos distribuidos, o crear tablas de resumen basadas en operaciones de agrupacin. Oracle proporciona las
vistas materializadas para almacenar copias de datos o agregaciones. Se pueden usar las vistas materializadas
para replicar todo o parte de una nica tabla, o para replicar el resultado de una consulta a travs de varias
tablas; el refresco de los datos replicados pueden hacerlo automticamente la base de datos cada cierto
intervalo de tiempo.
9.1. Funcionalidad.
Las vistas materializadas son copias (tambin conocidas como rplicas) de datos, basadas en consultas. En su
forma ms simple, una vista materializada puede ser obtenida a partir de una tabla creada por un comando
como el siguiente:
CREATE TABLE Local_Libros AS
SELECT * FROM Libros@REMOTE_CONNECT;
En este ejemplo, se crea una tabla llamada Local_Libros en la base de datos local y se puebla con los datos de
una base de datos remota (definida por el enlace de base de datos llamado REMOTE_CONNECT). Una vez
creada la tabla Local_Libros, los datos debern ser sincronizados con la tabla maestra
(Libros@REMOTE_CONNECT). Tambin los usuarios locales debern poder actualizar Local_Libros, sin tener que
preocuparse de las complicaciones de sincronizacin con la tabla maestra.
A pesar de estos problemas de sincronizacin, hay ventajas en replicar los datos de este modo. Al crear copias
locales de datos remotos podemos mejorar el rendimiento de consultas distribuidas, particularmente si los
datos de la tabla maestra no cambian frecuentemente. Podemos usar tambin el proceso de creacin de la
tabla local para restringir las filas retornadas, restringir las columnas retornadas o generar nuevas columnas.
sta es una estrategia comn en entornos de tomas de decisiones, en los cuales se usan consultas complejas
para peridicamente reunir datos dentro de tablas resumen para usar durante anlisis.
Las vistas materializadas automatizan la replicacin de datos y los procesos de refresco. Cuando se crea una
vista materializada, se establece un intervalo de refresco para planificar refrescos y replicar datos. Se pueden
evitar actualizaciones locales, y se pueden usar refrescos basados en transacciones. Este tipo de refrescos
envan desde la base de datos maestra slo aquellas filas que han cambiado.
9.2. Permisos requeridos.
Para crear una vista materializada debemos tener los permisos necesarios para crear los objetos subyacentes
que se usarn.
9.2.1. Permisos de sistema.
Debemos tener el permiso CREATE MATERIALIZED VIEW, as como los permisos CREATE TABLE o CREATE
ANY TABLE. Adems debemos tener el permiso de sistema UNLIMITED TABLESPACE o una cuota de espacio
suficiente en un tablespace local. Para crear una vista materializada refrescada-ante-confirmacin debemos
tener tambin el permiso de sistema ON COMMIT REFRESH sobre cualquier tabla involucrada de la que no
seamos propietario, o el permiso de sistema ON COMMIT REFRESH.
Las vistas materializadas de tablas remotas requieren consultas de tablas remotas; por lo tanto, debemos tener
permisos para usar un enlace de base de datos que acceda a la base de datos remota. El enlace que usemos
Oracle /222
puede ser pblico o privado. Si el enlace es privado necesitamos tener el permiso de sistema CREATE
DATABASE LINK para crear el enlace de base de datos.
Si estamos creando vistas materializadas para tener las ventajas de la funcionalidad de "rescritura de consulta"
(en la cual el optimizador elige dinmicamente tomar los datos de la vista materializada en vez de la tabla
subyacente), debemos tener el permiso QUERY REWRITE. Si las tablas estn en otro esquema de usuario
debemos tener el permiso GLOBAL QUERY REWRITE. Si la vista materializada es creada con la opcin ON
COMMIT REFRESH, debemos tener el permiso de sistema ON COMMIT REFRESH o el permiso de objeto ON
COMMIT REFRESH sobre cada tabla fuera de nuestro esquema.
9.2.2. Permisos de tabla.
Cuando se crean vistas materializadas podemos referenciar tablas en bases de datos remotas mediante enlaces
de base de datos. La cuenta que usa el enlace en la base de datos remota debe tener acceso a las tablas y vistas
usadas por el enlace. No podemos crear vistas materializadas basadas en objetos propiedad del usuario SYS.
Dentro de una base de datos local, podemos conceder el permiso SELECT sobre una vista materializada a
otros usuarios locales. Ya que las vistas materializadas son slo para leer (aunque puedan ser actualizables), no
son necesarios permisos adicionales. Si creamos una vista materializada actualizable, debemos conceder el
permiso UPDATE tanto a la vista como a la tabla local subyacente.
9.3. Solo-lectura contra actualizable.
Una vista materializada de solo lectura no puede trasladar cambios en los datos a la tabla origen en la que est
basada. Una vista materializada actualizable puede enviar cambios a la tabla origen.
Aunque parece que la distincin est clara, las diferencias subyacentes entre estos dos tipos de vistas
materializadas no son tan simples. Una vista materializada de solo lectura se implementa como un comando
CREATE TABLE AS SELECT. Cuando ocurre una transaccin dentro de la tabla origen, la transaccin es enviada
a la vista materializada de solo lectura. As, el mtodo por el cual las filas en la vista materializada cambian est
controlado (las filas de la vista materializada slo cambian despus de un cambio en la tabla origen).
En una vista materializada actualizable hay menos control sobre el mtodo por el cual cambian las filas en la
vista. Las filas pueden ser cambiadas segn los cambios en la tabla origen, o se pueden cambiar las filas
directamente en la vista. Por lo tanto, necesitamos enviar filas desde la tabla origen a la vista materializada y
viceversa. Ya que existen varios mtodos de cambios, existen varios orgenes (mencionado como
configuracin de multi-origen). Durante la transferencia de registros desde la vista a la tabla origen,
necesitamos decidir cmo resolver conflictos. Por ejemplo, qu pasa si un registro con ID=1 es eliminado en
la vista materializada, mientras que en el sitio origen se crea un registro en otra tabla que referencia (mediante
integridad referencial) el registro con ID=1? No podemos eliminar el registro con ID=1 de la tabla origen
mientras exista un registro "hijo" relacionado. Cmo planificar la resolucin de estos conflictos?
Las vistas materializadas de solo lectura evitan la necesidad de resolver este tipo de conflictos ya que fuerzan
que todas las transacciones ocurran en la tabla origen. Esto puede limitar nuestra funcionalidad, pero es una
solucin apropiada para la mayora de necesidades de replicacin. Si necesitamos una replicacin multi-origen
vanse las reglas de la gua de replicacin avanzada.
9.4. Sintaxis de creacin de vistas materializadas.
La sintaxis bsica de creacin de vistas materializadas se muestra a continuacin.
CREATE MATERIALIZED VIEW [usuario.]nombre Cabecera
[ ORGANIZATION INDEX clusula_iot]
[ { { clusulas de atributos de segmento }
| CLUSTER cluster (columna [, columna] ...) }
[ {clusula de particionado | clusula paralelo | clusula construccin } ]
Parmetros de
| ON PREBUILT TABLE [ {WITH | WITHOUT} REDUCED PRECISION ] ]
almacenamiento
[ USING INDEX
[ { clusulas atributos fsicos | clusula tablespace }
[ clusula atributos fsicos | clusula tablespace ]
| USING NO INDEX ]
[ clusula refresco ] Opciones de refresco
[ FOR UPDATE ] [{DISABLE | ENABLE} QUERY REWRITE]
consulta
AS subconsulta;
El comando CREATE MATERIALIZED VIEW tiene cuatro secciones mayores. La primera seccin es la cabecera,
en la cual se indica el nombre de la vista materializada:

Oracle /223
CREATE MATERIALIZED VIEW [usuario.]nombre
La vista ser creada en nuestra cuenta (esquema) a menos que especifiquemos un nombre de usuario en la
cabecera.
En la segunda seccin se especifican los parmetros de almacenamiento. Estos parmetros se aplican a la
tabla que ser creada en la base de datos local. Si los datos han sido ya replicados en una tabla local podemos
usar la clusula PREBUILT TABLE para decirle a Oracle que use esta tabla como una vista materializada.
Nota. Podemos especificar los parmetros de almacenamiento para ser usados por el ndice que es
automticamente creado sobre la vista materializada.
En la tercera seccin se asignan las opciones de refresco. La sintaxis para esta clusula es la siguiente:
{ REFRESH
{ { FAST | COMPLETE | FORCE }
| ON { DEMAND | COMMIT }
| { START WITH | NEXT } DATE
| WITH { PRIMARY KEY | ROWID }
| USING
{ DEFAULT [ MASTER | LOCAL ] ROLLBACK SEGMENT
| [ MASTER | LOCAL ] ROLLBACK SEGMENT segmento_Rollback
}
[ DEFAULT [ MASTER | LOCAL ] ROLLBACK SEGMENT
| [ MASTER | LOCAL ] ROLLBACK SEGMENT segmento_Rollback
]...
}
[ { FAST | COMPLETE | FORCE }
| ON { DEMAND | COMMIT }
| { START WITH | NEXT } DATE
| WITH { PRIMARY KEY | ROWID }
| USING
{ DEFAULT [ MASTER | LOCAL ] ROLLBACK SEGMENT
| [ MASTER | LOCAL ] ROLLBACK SEGMENT segmento_Rollback
}
[ DEFAULT [ MASTER | LOCAL ] ROLLBACK SEGMENT
| [ MASTER | LOCAL ] ROLLBACK SEGMENT segmento_Rollback
]...
]...
| NEVER REFRESH
}
La opcin REFRESH especifica el mecanismo que Oracle debe usar cuando se refresque la vista materializada.
Las tres opciones disponibles son FAST, COMPLETE y FORCE. El refresco FAST est slo disponible si Oracle
puede hacer corresponder las filas de la vista directamente con las filas de la tabla(s) origen; Oracle usa tablas
llamadas registros de vistas materiaplizadas para enviar filas especficas desde la tabla origen a la vista
materializada. El refresco COMPLETE trucan los datos y re-ejecuta la consulta base de la vista materializada
para repoblarla. La opcin FORCE le dice a Oracle que use un refresco rpido si es posible; si no es posible usa
un refresco completo. Si hemos creado una vista materializada simple pero queremos usar el refresco
completo, debemos especificar REFRESH COMPLETE en el comando.
Dentro de esta seccin podemos especificar el mecanismo usado para relacionar valores en la vista
materializada con la tabla origen (si deben usarse valores RowId o la clave primaria). Por defecto, se usan las
claves primarias.
Si la consulta origen para la vista referencia una combinacin o una nica tabla podemos usar la opcin ON
COMMIT para controlar la replicacin de los cambios. Si se usa ON COMMIT, los cambios sern enviados desde
el origen a la rplica cuando los cambios son confirmados sobre la tabla origen. Si especificamos ON DEMAND,
el refresco ocurrir cuando ejecutemos manualmente un comando REFRESH.
La cuarta seccin es la consulta que usar la vista materializada:
[ FOR UPDATE ] [{DISABLE | ENABLE} QUERY REWRITE]
AS subconsulta ;
Si especificamos FOR UPDATE, la vista ser actualizable; si no, ser de solo lectura. La mayora de vistas
materializadas son rplicas de slo lectura de la tabla origen. Si usamos vistas actualizables debemos tener en

Oracle /224
cuenta las replicaciones en los dos sentidos y la resolucin de conflictos en los datos.
Nota. La consulta que forma el origen de la vista materializada no debera usar las pseudo-columnas
USER y SYSDATE.

El siguiente ejemplo crea una vista materializada de solo lectura llamada LOCAL_LIBRO en la base de datos
local, basada en una tabla remota llamada LIBRO que es accesible mediante el enlace CONEXIN_REMOTA. La
vista es ubicada en el tablespace USERS.
CREATE MATERIALIZED VIEW LOCAL_LIBRO
TABLESPACE USERS
REFRESH FORCE
START WITH SYSDATE NEXT SYSDATE+7
WITH PRIMARY KEY
AS
SELECT * FROM LIBRO@CONEXION_REMOTA;
Oracle responde con
Vista materializada creada.
El comando del ejemplo precedente crear una vista materializada de slo lectura llamada LOCAL_LIBRO. La
tabla subyacente ser creada en el tablespace USERS. Podemos poner los registros de la vista materializada en
tablespaces aparte de los que soportan la vista materializada. Se ha especificado la opcin de refresco FORCE
porque no existen registros de la vista materializada sobre la tabla origen; Oracle intentar usar un refresco
rpido pero slo usar un refresco completo hasta que se cree el registro de vista materializada. La consulta
asociada a la vista especifica que toda la tabla LIBRO, sin modificaciones, ser copiada a la base de datos local.
A la vez que la vista materializada LOCAL_LIBRO es creada, su tabla subyacente es poblada con los datos de
LIBRO. A partir de ese momento la vista materializada ser refrescada cada 7 das. Los parmetros de
almacenamiento no indicados sern aplicados por defecto segn el tablespace USERS.
El siguiente ejemplo crea una vista materializada llamada LOCAL_CATEGORIA_COUNT en una base de datos
local, basada en una tabla remota llamada LIBRO en una base de datos accedida mediante el enlace
CONEXION_REMOTA.
CREATE MATERIALIZED VIEW LOCAL_CATEGORIA_COUNT
TABLESPACE USERS
REFRESH FORCE
START WITH SYSDATE NEXT SYSDATE+7
AS
SELECT NombreCategoria, COUNT(*) CountPorCat
FROM LIBRO@CONEXION_REMOTA
GROUP BY NombreCategoria;
La consulta de esta vista materializada cuenta el nmero de libros en cada categora de la tabla remota LIBRO.
Hay unos pocos importantes puntos a notar acerca de estos dos ejemplos previos:
La consulta de agrupacin usada en la vista materializada LOCAL_CATEGORIA_COUNT podra ser realizada
en SQL*Plus usando la vista LOCAL_LIBRO. Esto es, la operacin de agrupacin puede hacerse fuera de la
vista materializada.
Ya que LOCAL_CATEGORIA_COUNT usa una clusula GROUP BY, es una vista compleja si slo puede usar el
refresco completo. LOCAL_LIBRO, como vista simple, puede usar refresco rpido.
Estas dos vistas materializadas de ejemplo referencian la misma tabla. Ya que una de las vista replica todas las
columnas y filas de la tabla origen, la segunda vista puede parecer redundante. Sin embargo, algunas veces el
segundo tipo de vista, la compleja, es el ms utilizado de los dos. Cmo es esto as? Primero, recordemos
que estas vistas materializadas son usadas para servir consultas necesarias para usuarios locales. Si estos
usuarios siempre realizan operaciones de agrupacin en sus consultas, y las columnas de agrupacin son fijas,
entonces LOCAL_CATEGORIA_COUNT puede ser ms til. Segundo, si el volumen de transaccin de la tabla
origen LIBRO es muy alto, o la tabla LIBRO es muy pequea, puede no haber diferencias en los tiempo de
refresco rpido y completo. Las vistas materializadas ms apropiadas son las que resultan ms productivas
para los usuarios.
9.4.1. Tipos de vistas materializadas.
Las vistas materializadas mostradas en los ejemplos previos ilustran sobre dos tipos de vistas materializadas.
En el primero, la vista materializada crea una copia local de datos remotos, sin agrupacin. En el segundo, se
aplica una agrupacin. En ambas vistas podemos ampliar la consulta base para incluir combinaciones de

Oracle /225
tablas. Lo diferencia importante en este caso es el uso de agrupacin en el segundo ejemplo.
Un tercer tipo de vista materializada es una vista materializada anidada (una vista materializada cuya definicin
es la base para otra vista materializada).
El tipo de vista materializada tendr importancia en nuestra habilidad de realizar refrescos rpidos. Un
refresco rpido actualizar la vista slo con las filas que han cambiado en las tablas origen desde el ltimo
refresco. Si no podemos realizar un refresco rpido, tendremos que usar un refresco completo, el cual es
normalmente ms expansivo en trminos de tiempo y recursos. Los refrescos rpidos requieren el uso de
registros de vista materializada sobre todas las tabla referenciadas en la consulta base de la vista.
Si la vista contiene una agrupacin, un refresco rpido ser posible si la consulta contiene todo el grupo por
columnas y debe haber un COUNT(*) y COUNT(columna) sobre cualquier columna del GROUP BY.
Si la vista materializada contiene slo combinaciones pero no agrupaciones, el refresco rpido es posible
despus de cualquier insercin, actualizacin o borrado sobre las tablas base. Las columnas RowID para cada
tabla debe estar presente en la lista del SELECT de la consulta base, y todas las tablas referenciadas deber tener
registros de vista materializada.
Debido a que hay que enviar los cambios incrementales desde las tablas referenciadas a la vista materializada,
los refrescos rpidos normalmente representan el camino ms rpido para actualizar los datos de nuestras
vistas materializadas.
9.4.2. Vistas materializadas basadas en RowID y en clave primaria.
Podemos basar las vistas materializadas tanto sobre los valores de la clave primaria como sobre los valores de
RowID de las tablas base. Debemos decidir entre estas opciones segn varios factores:
Estabilidad del sistema. Si el sitio origen no es estable, entonces podemos necesitar realizar
recuperaciones de base de datos que involucren a las tablas origen de la vista. Cuando se usan las utilidades
de Oracle Data Pump Export e Import para realizar recuperaciones, los valores RowID de las filas
cambiarn. Si el sistema requiere frecuentes exportaciones e importaciones, deberamos usar vistas basadas
en clave primaria.
Tamao de la tabla de registro de vista materializada. Oracle permite almacenar los cambios de las tablas
origen en tablas separadas llamadas registros de vista materializada. Si la clave primaria consiste de varias
columnas, esta tabla de registro para una vista basada en clave primaria puede ser considerablemente ms
grande que la vista basada en RowID.
Integridad referencial. Para usar vistas basadas en clave primaria, debemos definir una clave primaria
sobre la tabla origen. Si no podemos definir una clave primaria debemos usar vistas basadas en RowID.
9.4.3. Usando tablas predefinidas.
Cuando creamos vistas materializadas podemos especificar BUILD IMMEDIATE para poblar la vista
materializada inmediatamente o BUILD DEFERRED para poblar la vista ms tarde (a travs de un refresco).
Si necesitamos gestionar con cuidado las transacciones que pueblan inicialmente la vista materializada,
podemos crear una tabla que tenga la misma estructura que la vista materializada a poblar. Cuando la tabla
est completamente cargada y apropiadamente indexada, se usa la clusula ON PREBUILT TABLE del comando
CREATE MATERIALIZED VIEW. La tabla y la vista materializada deben tener el mismo nombre, y la tabla debe
tener las misma columnas y tipos de datos (podemos especificar precisiones reducidas para acomodar
diferencias en precisin). La tabla puede contener columnas adicionales no gestionadas.
Una vez que la tabla ha sido registrada como una vista materializada, podemos mantenerla mediante
refrescos, y el optimizador puede usarla en operaciones de "rescritura de consultas". Para que la "rescritura de
consulta" trabaje apropiadamente sobre una tabla predefinida, debemos asignar el parmetro de inicializacin
QUERY_REWRITE_INTEGRITY a STALE_TOLERATED o TRUSTED.
9.4.4. Indexando tablas de vistas materializadas.
Cuando creamos una vista materializada, Oracle crea una tabla base local que contiene los datos que
satisfacen la consulta base. Ya que los datos han sido replicados con algn propsito en mente (normalmente
para mejorar el rendimiento en la base de datos o la red), es importante llevar a cabo a este objetivo despus
de que la vista materializada ha sido creada. La mejora del rendimiento para consultas se obtiene
normalmente mediante el uso de ndices. Las columnas que son frecuentemente usadas en clusulas WHERE
de consultas deberan se indexadas; si un conjunto de columnas es frecuentemente accedida en consultas,
entonces se puede crear un ndice concatenado sobre este conjunto de columnas.
Oracle no crea automticamente ndices para vistas materializadas complejas sobre columnas en vez de la
clave primaria. Necesitamos crear estos ndices manualmente. Para crear ndices en nuestra tabla base local se
usa el comando CREATE INDEX. No se aconseja crear ninguna restriccin sobre la tabla origen de la vista
Oracle /226
materializada; Oracle mantiene las relaciones basadas en restricciones sobre las tablas origen.
Ya que no se crea ningn ndice sobre las columnas que los usuarios consultan sobre la vista materializada,
deberamos crear ndices sobre la tabla local base de la vista materializada.
9.5. Usando vistas materializadas para modificar rutas de ejecucin de consultas.
Para una gran base de datos, una vista materializada puede ofrecer varios beneficios de rendimiento. Podemos
usar vistas materializadas para influir en el optimizador a cambiar la ejecucin de rutas para consultas. Esta
funcionalidad, llamada "rescritura de consulta", permite al optimizador usar una vista materializada en vez de
la tabla consultada por la vista materializada, aun si la vista materializada no es nombrada en la consulta. Por
ejemplo, si tenemos una tabla grande VENTA, podemos crear una vista materializada que sume los datos de
VENTA por regin. Si un usuario consulta la tabla VENTA para obtener la suma de datos por regin, Oracle
puede redireccionar esta consulta para que use la vista materializada en vez de la tabla VENTA. Como
resultado, podemos reducir el nmero de accesos a nuestras tablas grandes, mejorando as el rendimiento del
sistema.
Nota. Debemos especificar ENABLE QUERY REWRITE en la definicin de la vista materializada para
que la vista sea usada como parte de una operacin de rescritura de consulta.
Para usar la capacidad de rescritura de consulta efectivamente, debemos crear una dimensin que defina la
jerarqua dentro de los datos de la tabla. Para ejecutar el comando CREATE DIMENSION necesitamos tener el
permiso del sistema CREATE DIMENSION. Podemos crear una dimensin que soporte la jerarqua entre dos
tablas de ejemplo PAIS y CONTINENTE:
CREATE DIMENSION GEOGRAFIA
LEVEL IdPais IS PAIS.Pais
LEVEL IdContinente IS CONTINENTE.Continente
HIERARCHY Pais_Rollup (
IdPais CHILD OF IdContinente
JOIN KEY PAIS.Continente REFERENCES IdContinente);
Para habilitar una vista materializada para rescritura de consultas, todas las tablas origen de la vista deben
estar en el esquema de la vista, y debemos tener el permiso de sistema QUERY REWRITE. Si la vista y las tablas
estn en esquemas separados, debemos tener el permiso de sistema GLOBAL QUERY REWRITE. En general,
debemos crear vistas materializada en el mismo esquema que las tablas origen; si no es as, necesitaremos
gestionar los permisos y concesiones requeridas para crear y mantener la vista materializada.
Nota. Podemos habilitar o deshabilitar rescritura de consultas en el nivel de la sentencia SQL mediante los
modificadores REWRITE y NOREWRITE. Cuando usamos el modificador REWRITE podemos especificar vistas
materializadas que debera considerar el optimizador.
Nota. Las decisiones de rescritura de consultas estn basadas en el coste de las diferentes rutas de
ejecucin, as que nuestras estadsticas deberan mantenerse.
Para que la rescritura de consultas sea posible, debemos asignar los siguientes parmetros de inicializacin:
OPTIMIZER_MODE = ALL_ROWS o FIRST_ROWS
QUERY_REWRITE_ENABLED = TRUE
QUERY_REWRITE_INTEGRITY = STALE_TOLERATED, TRUSTED, o ENFORCED
Por defecto, QUERY_REWRITE_INTEGRITY es asignado a ENFORCED; en este modo todas las restricciones
deben ser validadas. El optimizador slo usar refrescos de datos desde vistas materializadas y slo usar estas
relaciones que estn basadas en restricciones ENABLED VALIDATED primarias, nicas, o de clave fornea. En
modo TRUSTED, el optimizador garantiza que los datos en la vista materializada sean frescos y las relaciones
declaradas en dimensiones y restricciones sean correctas. En modo STALE_TOLERATED, el optimizador
usa vistas materializadas que son vlidas pero contienen datos antiguos, as como aquellas que contienen
datos frescos.
Si asignamos QUERY_REWRITE_ENABLED a FORCE, el optimizador rescribir consultas para usar vistas
materializadas cuando el coste estimado de la consulta original sea bajo. Si ocurre la rescritura de consultas, el
plan estimado para la consulta catalogar la vista materializada como una de los objetos accedidos, con una
operacin catalogada como "MAT_VIEWREWRITE ACCESS".
Podemos usar el procedimiento DBMS_MVIEW.EXPLAIN_REWRITE para ver si la rescritura es posible para una
consulta, y qu vistas materializadas estaran involucradas. Si la consulta no puede ser rescrita, el
procedimiento documentar las razones. EXPLAIN_REWRITE tiene tres parmetros de entrada: la consulta, el

Oracle /227
nombre de una vista materializada (opcional), y una sentencia identificadora (opcional). La salida de este
procedimiento puede ser almacenada en una tabla. Oracle proporciona el comando CREATE TABLE para la
tabla de salida en un script llamado utlxrw.sql en el directorio /rdbms/admin bajo el directorio base de Oracle.
El script utlxrw.sql crea una tabla llamada REWRITE_TABLE. Se puede consultar en esta tabla el coste original,
el coste de rescritura y la decisin del optimizador. La columna Message mostrar las razones de la decisin
del optimizador.
9.6. Usando DBMS_ADVISOR.
Desde Oracle Database 10g, podemos usar el SQL Access Advisor (Consejero de Acceso SQL) para generar
recomendaciones para la creacin de ndices (y tipos de ndices) para mejorar el rendimiento de consultas de
combinacin y otras. El SQL Access Advisor puede generar recomendaciones para modificar una vista
materializada y que as soporte rescritura de consultas y refrescos rpidos. Podemos ejecutar el SQL Access
Advisor desde el Administrador de Oracle Enterprise o mediante el paquete DBMS_ADVISOR.
Nota. Para los mejores resultados del paquete DBMS_ADVISOR, deberamos reunir estadsticas sobre
todas las tablas, ndices y columnas de join para generar recomendaciones.
Para usar el SQL Access Advisor, tanto desde el Administrador de Oracle Enterprise como con
DBMS_ADVISOR, debemos seguir los siguientes pasos:
1. Crear una tarea.
2. Definir la carga de trabajo.
3. Generar recomendaciones
4. Ver e implementar recomendaciones.
Podemos crear una tarea de dos formas: ejecutando el procedimiento DBMS_ADVISOR.CREATE_TASK o
usando el procedimiento DBMS_ADVISOR.QUICK_TUNE.
La carga de trabajo consiste de una o ms sentencias SQL ms las estadsticas y atributos que se relacionan
con la sentencia. La carga de trabajo puede incluir todas las sentencias SQL de una aplicacin. El SQL Access
Advisor organiza las entradas en la carga de trabajo de a cuerdo a las estadsticas e importancia en el negocio.
La carga de trabajo se crea usando el procedimiento DBMS_ADVISOR.CREATE_SQLWKLD. Para asociar una
carga de trabajo con una tarea del consejero se usa el procedimiento DBMS_ADVISOR.ADD_SQLWKLD_REF. Si
no se proporciona una carga de trabajo, el SQL Access Advisor puede generar y usar una carga de trabajo
hipottica basada en las dimensiones definidas en nuestro esquema.
Una vez que existe una tarea y una carga de trabajo asociada con la tarea, podemos generar recomendaciones
a travs del procedimiento DBMS_ADVISOR.EXECUTE_TASK. El SQL Access Advisor considerar la carga de
trabajo y las estadsticas del sistema e intentar generar recomendaciones para afinar la aplicacin. Podemos
ver estas recomendaciones ejecutando la funcin DBMS_ADVISOR.GET_TASK_SCRIPT o mediante las vistas del
diccionario de datos. Cada recomendacin puede ser vista mediante USER_ADVISOR_RECOMMENDATIONS
(existen tambin versiones ALL_ y DBA_). Para relacionar recomendaciones con una sentencia SQL
necesitamos usar la vista USER_ADVISOR_SQLA_WK_STMTS y USER_ADVISOR_ACTIONS.
Cuando se ejecuta el procedimiento GET_TASK_SCRIPT, Oracle genera un fichero SQL ejecutable que
contendr los comandos necesarios para crear, modificar o borrar los objetos recomendados. Deberamos
revisar el script generado antes de ejecutarlo, particularmente en las especificaciones del tablespace.
9.6.1. Cmo realizar un afinado rpido.
Para afinar una nica sentencia SQL se usa el procedimiento DBMS_ADVISOR.QUICK_TUNE. El procedimiento
QUICK_TUNE tiene dos parmetros de entrada: un nombre de tarea y una sentencia SQL. Usando
QUICK_TUNE escudamos al usuario de los pasos involucrados en la creacin de cargas de trabajo y tareas
mediante DBMS_ADVISOR.
Por ejemplo, el siguiente procedimiento evala una consulta:
EXECUTE DBMS_ADVISOR.QUICK_TUNE(DBMS_ADVISOR.SQLACCESS_ADVISOR, -
'MV_TUNE','SELECT Autor FROM Libro');

Nota. El usuario que ejecute este comando necesita el permiso de sistema ADVISOR.
Las recomendaciones generadas por QUICK_TUNE pueden verse a travs de la vista
USER_ADVISOR_ACTIONS, pero es ms fcil leerlas usando el procedimiento DBMS_ADVISOR para generar un
fichero de script. La recomendacin es que una vista materializada ser creada para soportar esta consulta. Ya
que slo se proporcion una consulta, no se consideran otros aspectos de la base de datos o la aplicacin.

Oracle /228
Podemos usar el procedimiento CREATE_FILE para automatizar la generacin de un fichero que contenga el
script necesario para implementar las recomendaciones. Primero, crear un objeto DIRECTORY para contener el
fichero:
CREATE DIRECTORY SCRIPTS AS 'E:\SCRIPTS';
GRANT READ ON DIRECTORY SCRIPTS TO PUBLIC;
GRANT WRITE ON DIRECTORY SCRIPTS TO PUBLIC;
A continuacin, ejecutar el procedimiento CREATE_FILE. Tiene tres variables de entrada: el script (generado
mediante GET_TASK_SCRIPT, al cual se pasa el nombre de la tarea), el directorio de salida, y el nombre del
fichero que ser creado.
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT('MV_TUNE'), -
'SCRIPTS', 'MV_TUNE.sql');
El fichero MV_TUNE.sql creado por el procedimiento CREATE_FILE contendr comandos similares a los
mostrados a continuacin. Dependiendo de la versin especfica de Oracle las recomendaciones pueden
diferir.
Rem Username: EMPLEADO
Rem Task: MV_TUNE
Rem
set feedback 1
set linesize 80
set trimspool on
set tab off
set pagesize 60
whenever sqlerror CONTINUE
CREATE MATERIALIZED VIEW "EMPLEADO"."MV$$_021F0001"
REFRESH FORCE WITH ROWID
ENABLE QUERY REWRITE
AS SELECT PRACTICE.BOOKSHELF.ROWID C1,
"EMPLEADO"."LIBRO"."AUTOR" M1
FROM EMPLEADO.LIBRO;
begin
dbms_stats.gather_table_stats('"PRACTICE"',
'"MV$$_021F0001"',NULL,dbms_stats.auto_sample_size);
end;
/
whenever sqlerror EXIT SQL.SQLCODE
begin
dbms_advisor.mark_recommendation('MV_TUNE',1,'IMPLEMENTED');
end;
/
El procedimiento MARK_RECOMMENDATION permite anotar la recomendacin as que puede saltarse durante
la generacin del script. Acciones vlidas para MARK_RECOMMENDATION incluyen ACCEPT, IGNORE,
IMPLEMENTED y REJECT.
Podemos usar el procedimiento DBMS_ADVISOR.TUNE_MVIEW para generar recomendaciones para la
reconfiguracin de nuestras vistas materializadas. TUNE_VIEW genera dos conjuntos de resultados de salida:
para la creacin de nuevas vistas materializadas, y para remover vistas materializadas creadas previamente. El
resultado final ser un conjunto de vistas materializadas que pueden ser refrescadas rpidamente,
reemplazando vistas materializadas que no pueden ser refrescadas rpidamente.
Podemos ver la salida de TUNE_MVIEW mediante la vista del diccionario de datos USER_TUNE_MVIEW, o
podemos generar su script mediante los procedimientos GET_TASK_SCRIPT y CREATE_FILE.
9.7. Refrescando vista materializadas.
Los datos en una vista materializada puede ser replicados una vez (cuando la se crea la vista) o a intervalos. El
comando CREATE MATERIALIZED VIEW permite asignar el intervalo de refresco, delegando la responsabilidad
de la planificacin y realizacin de los refrescos a la base de datos.

Oracle /229
9.7.1. Qu cosas podemos cambiar en los refrescos?
Para ver qu cosas de los refrescos y capacidades de rescritura son posibles en nuestras vistas materializadas,
podemos consultar la tabla MV_CAPABILITIES_TABLE. Las capacidades pueden cambiar entre versiones, as
que deberamos reevaluar nuestras capacidades de refresco con cada actualizacin de Oracle. Para crear esta
tabla, hay que ejecutar el script utlxmv.sql localizado en el directorio /rdbms/admin bajo el directorio base de
Oracle.
Las columnas de MV_CAPABILITIES_TABLE son:
DESC MV_CAPABILITIES_TABLE
Name Null? Type
----------------------------------------- -------- ----------------
STATEMENT_ID VARCHAR2(30)
MVOWNER VARCHAR2(30)
MVNAME VARCHAR2(30)
CAPABILITY_NAME VARCHAR2(30)
POSSIBLE CHAR(1)
RELATED_TEXT VARCHAR2(2000)
RELATED_NUM NUMBER
MSGNO NUMBER(38)
MSGTXT VARCHAR2(2000)
SEQ NUMBER
Para poblar la tabla MV_CAPABILITIES_TABLE se ejecuta el procedimiento DBMS_MVIEW.EXPLAIN_MVIEW,
usando el nombre de la vista materializada como valor de entrada como se muestra a continuacin:
EXECUTE DBMS_MVIEW.EXPLAIN_MVIEW('local_category_count');
El script de utlxmv.sql proporciona guas de interpretacin de los valores de columna, tal como se muestra a
continuacin:
CREATE TABLE MV_CAPABILITIES_TABLE
(STATEMENT_ID VARCHAR(30), -- Client-supplied unique statement identifier
MVOWNER VARCHAR(30), -- NULL for SELECT based EXPLAIN_MVIEW
MVNAME VARCHAR(30), -- NULL for SELECT based EXPLAIN_MVIEW
CAPABILITY_NAME VARCHAR(30), -- A descriptive name of the particular
-- capability:
-- REWRITE
-- Can do at least full text match
-- rewrite
-- REWRITE_PARTIAL_TEXT_MATCH
-- Can do at least full and partial
-- text match rewrite
-- REWRITE_GENERAL
-- Can do all forms of rewrite
-- REFRESH
-- Can do at least complete refresh
-- REFRESH_FROM_LOG_AFTER_INSERT
-- Can do fast refresh from an mv log
-- or change capture table at least
-- when update operations are
-- restricted to INSERT
-- REFRESH_FROM_LOG_AFTER_ANY
-- can do fast refresh from an mv log
-- or change capture table after any
-- combination of updates
-- PCT
-- Can do Enhanced Update Tracking on
-- the table named in the RELATED_NAME
-- column. EUT is needed for fast
-- refresh after partitioned
-- maintenance operations on the table
-- named in the RELATED_NAME column

Oracle /230
-- and to do non-stale tolerated
-- rewrite when the mv is partially
-- stale with respect to the table
-- named in the RELATED_NAME column.
-- EUT can also sometimes enable fast
-- refresh of updates to the table
-- named in the RELATED_NAME column
-- when fast refresh from an mv log
-- or change capture table is not
-- possible.
POSSIBLE CHARACTER(1), -- T = capability is possible
-- F = capability is not possible
RELATED_TEXT VARCHAR(2000), -- Owner.table.column, alias name, etc.
-- related to this message. The
-- specific meaning of this column
-- depends on the MSGNO column. See
-- the documentation for
-- DBMS_MVIEW.EXPLAIN_MVIEW() for details
RELATED_NUM NUMBER, -- When there is a numeric value
-- associated with a row, it goes here.
-- The specific meaning of this column
-- depends on the MSGNO column. See
-- the documentation for
-- DBMS_MVIEW.EXPLAIN_MVIEW() for details
MSGNO INTEGER, -- When available, QSM message #
-- explaining why not possible or more
-- details when enabled.
MSGTXT VARCHAR(2000), -- Text associated with MSGNO.
SEQ NUMBER); -- Useful in ORDER BY clause when
-- selecting from this table.
Una vez ejecutado el procedimiento EXPLAIN_MVIEW podemos consultar MV_CAPABILITIES_TABLE para
determinar nuestras opciones.
SELECT Capability_Name, Msgtxt
FROM MV_CAPABILITIES_TABLE
WHERE Msgtxt IS NOT NULL;
Para la vista materializada LOCAL_LIBRO la consulta retornar:
CAPABILITY_NAME MSGTXT
---------------------------------------------- ---------------------------------------------------------------------------
PCT_TABLE relation is not a partitioned table
REFRESH_FAST_AFTER_INSERT the detail table does not have a materialized view log
REFRESH_FAST_AFTER_ONETAB_DML see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ANY_DML see the reason why REFRESH_FAST_AFTER_ONETAB_DML is
disabled
REFRESH_FAST_PCT PCT is not possible on any of the detail tables in the materialized
view
REWRITE_FULL_TEXT_MATCH query rewrite is disabled on the materialized view
REWRITE_PARTIAL_TEXT_MATCH query rewrite is disabled on the materialized view
REWRITE_GENERAL query rewrite is disabled on the materialized view
REWRITE_PCT general rewrite is not possible or PCT is not possible on any of the
detail tables
PCT_TABLE_REWRITE relation is not a partitioned table
Ya que no se especific la clusula QUERY REWRITE durante la creacin de la vista materializada, las
capacidades de rescritura de consultas estn desactivadas para LOCAL_LIBRO. Las capacidades de refresco
rpido no estn soportadas porque la tabla base no tiene un registro de vista materializada. Si cambiamos
nuestra vista materializada o la tabla base deberamos regenerar los datos en MV_CAPABILITIES_TABLE para
ver las nuevas capacidades.
Adems de la falta de registro de vista materializada hay otras restricciones que limitan nuestra habilidad de

Oracle /231
usar refrescos rpidos:
La vista materializada no debe contener referencias a expresiones no repetitivas como SysDate y RowNum.
La vista materializada no debe contener referencias a tipos de datos RAW o LONG RAW.
Para vistas materializadas basadas en joins, los RowID's de todas las tablas deben ser parte de la lista del
SELECT.
Si hay joins externos, todos los joins deben estar conectados por AND's, la clusula WHERE no debe tener
selecciones, y debe existir una restriccin UNIQUE sobre las columnas del join de la tabla del INNER JOIN.
Para vistas materializadas basadas en agrupaciones, los registros de vista materializada deben contener
todas las columnas de las tablas referenciadas, deben especificar el RowID y clusulas INCLUDING NEW
VALUES, y deben especificar la clusula SEQUENCE.

Nota. Podemos especificar una clusula ORDER BY en el comando CREATE MATERIALIZED VIEW. La
clusula ORDER BY slo afectar a la creacin inicial de la vista; y no afectar a cualquier refresco.
9.7.2. Refrescos automticos.
Consideremos la vista materializada LOCAL_LIBRO descrita previamente. La opcin de refresco, definida al
crear la vista, se muestra a continuacin:
CREATE MATERIALIZED VIEW LOCAL_LIBRO
TABLESPACE USERS
REFRESH FORCE
START WITH SYSDATE NEXT SYSDATE+7
WITH PRIMARY KEY
AS
SELECT * FROM LIBRO@CONEXION_REMOTA;
La planificacin de refresco tiene tres componentes. Primero, el tipo de refresco ( FAST, COMPLETE, NEVER, o
FORCE). Refrescos rpidos usan registros de vista materializada para enviar cambios de filas desde la tabla
origen a la vista. Refrescos completos borran todas las filas de la vista y la repueblan. La opcin FORCE le dice
a Oracle que use refresco rpido si es posible, sino se usar refresco completo.
La clusula START WITH le dice a la base de datos cundo realizar la primera replicacin de la tabla origen a la
tabla base local. Debemos evaluarla a un punto del tiempo en el futuro. Si no especificamos un tiempo para
START WITH pero especificamos un valor NEXT, Oracle usar la clusula NEXT para determinar el tiempo
inicial. Para mantener control sobre nuestra planificacin de replicacin debemos especificar un valor para la
clusula START WITH.
La clusula NEXT le dice a Oracle cunto tiempo debe esperar entre cada refresco. Ya que ser aplicada a
diferentes bases de tiempo en cada refresco, la clusula NEXT especifica una expresin de fecha en vez de una
fecha fija. En el ejemplo precedente la expresin es
NEXT SysDate+7
Cada vez que la vista materializada es refrescada, el siguiente refresco se planificar para 7 das despus.
Aunque la planificacin de refresco en este ejemplo es muy simple, podemos usar muchas funciones de
fechas de Oracle para personalizar la planificacin de refresco. Por ejemplo, si queremos refrescar cada
Domingo a partir de la fecha actual, podemos asignar la clusula NEXT a
NEXT NEXT_DAY(TRUNC(SysDate), 'DOMINGO')+12/24
Para que ocurran los refrescos automticos debemos tener al menos un proceso de refresco de fondo
ejecutndose en nuestra base de datos. El proceso de refresco se ejecuta peridicamente y mira si cualquier
vista materializada de la base de datos necesita ser refrescada. El nmero de procesos que se ejecutan en
nuestra base de datos se determina en un parmetro de inicializacin llamado JOB_QUEUE_PROCESSES. Este
parmetro debe asignarse (en nuestro fichero de parmetros de inicializacin) a un valor ms grande que cero;
para la mayora de los casos, un valor de 1 debera ser suficiente. Un proceso coordinador comienza los
procesos de la cola de tareas cuando es necesario.
Si la base de datos no est ejecutando los procesos de la cola de tareas necesitamos usar mtodos de refresco
manual.
9.7.3. Refrescos manuales.
Adems de los refrescos automticos, podemos realizar refrescos manuales de vistas materializadas. Esto
rescribe la planificacin normal de los refrescos; el nuevo valor de START WITH deber estar basado en el
momento de nuestro refresco manual.
Para refrescar una nica vista materializada se usa el procedimiento DBMS_MVIEW.REFRESH. Tiene dos

Oracle /232
parmetros principales: el nombre de la vista materializada y el mtodo a usar. En este mtodo podemos
especificar 'c' para un refresco completo, 'f' para un refresco rpido, 'p' para un refresco rpido usando
Partition Change Tracking (PCT) y '?' para forzar refresco. Por ejemplo:
EXECUTE DBMS_MVIEW.REFRESH('LOCAL_LIBRO','c');

Nota. Partition Change Tracking (PCT) ocurre cuando operaciones de mantenimiento de particin
se han realizado sobre las tablas referenciadas por la vista materializada. En PCT, Oracle realiza
refrescos re-computando las filas en la vista afectadas por particiones cambiadas en tablas de detalle,
evitando la necesidad de refrescos completos.
Si refrescamos varias vistas materializadas mediante una nica ejecucin de DBMS_MVIEW.REFRESH, debemos
listar los nombres de todas las vistas en el primer parmetro, y sus mtodos de refresco en el segundo
parmetro, tal como se muestra a continuacin:
EXECUTE DBMS_MVIEW.REFRESH( 'LOCAL_LIBRO,LOCAL_CATEGORIA', '?c' );
Podemos usar un procedimiento independiente en el paquete DBMS_MVIEW para refrescar todas las vistas
materializadas que estn planificadas para refrescarse automticamente. Este procedimiento, llamado
REFRESH_ALL, refrescar cada vista materializada independientemente. No acepta ningn parmetro:
EXECUTE DBMS_MVIEW.REFRESH_ALL_MVIEWS;
Ya que las vistas sern refrescadas mediante REFRESH_ALL consecutivamente, no sern refrescadas al mismo
tiempo. Por lo tanto, una base de datos o servidor que falle durante la ejecucin de este procedimiento puede
causar que vistas materializadas locales no estn sincronizadas con otras. Si esto ocurre, simplemente hay que
volver a ejecutar este procedimiento despus de que se recupere la base de datos. Como alternativa, podemos
crear grupos de refresco (ver siguiente seccin).
Otro procedimiento, DBMS_MVIEWS.REFRESH_ALL_MVIEWS, refresca todas las vistas materializadas que
tengan las siguientes propiedades:
La vista no ha sido refrescada desde los cambios ms recientes a la tabla origen o vistas origen de la
cuales depende.
La vista y todas las tablas o vistas origen de las cuales depende son locales.
La vista est en la vista DBA_MVIEWS.
Si creamos vistas materializadas anidadas, para asegurarnos de que sean refrescadas, podemos usar el
procedimiento DBMS_MVIEW.REFRESH_DEPENDENT.
9.8. Sintaxis para crear registros de vista materializada.
Un registro de vista materializada en una tabla que registra los cambios en las filas de la tabla origen y el
historial de replicacin de vistas materializadas. El registro de cambios en las filas puede entonces usarse
durante refrescos para enviar a las vistas materializadas slo las filas que han cambiado en el origen. Varias
vistas materializadas basadas en la misma tabla pueden usar el mismo registro de vista materializada.
La sintaxis resumida para el comando CREATE MATERIALIZED VIEW LOG se muestra a continuacin:
CREATE MATERIALIZED VIEW LOG ON [esquema .] tabla
[{ clusula de atributos fsicos
| TABLESPACE tablespace
| { LOGGING | NOLOGGING }
| { CACHE | NOCACHE }
}
[ clusula de atributos fsicos
| TABLESPACE TABLESPACE
| { LOGGING | NOLOGGING }
| { CACHE | NOCACHE }
]...
]
[ clusula paralelo ] [ clusula particionado ]
[WITH
{ OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE | ( columna [, columna ] . . . ) }
[, { OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE | (columna [,columna ] . . . ) }] . . .
]
[{ INCLUDING | EXCLUDING } NEW VALUES] ;
El comando CREATE MATERIALIZED VIEW LOG se ejecuta en la base de datos de la tabla origen, normalmente
por el propietario de la tabla origen. Los registros de vista materializada no deben crearse para tablas que slo

Oracle /233
estn involucradas con vistas complejas. No se especifica un nombre para el registro de vista materializada.
Un registro de vista materializada para la tabla LIBRO puede crearse mediante el siguiente comando, ejecutado
dentro de la cuenta del propietario de la tabla:
CREATE MATERIALIZED VIEW LOG ON LIBRO
WITH SEQUENCE, ROWID
(Titulo, Autor, Categoria)
INCLUDING NEW VALUES;
La clusula WITH SEQUENCE es necesaria para soportar la replicacin de operaciones mixtas DML a travs de
varias tablas base.
Debido a que los registros de vista materializada pueden aumentar impredeciblemente a lo largo del tiempo
en las bases de datos de produccin, deberamos considerar almacenar sus objetos asociados en tablespaces
dedicados para los registros de vista materializada.
9.8.1. Permisos de sistema requeridos.
Para crear el registro de vista materializada debemos tener los permisos del sistema CREATE TABLE y CREATE
TRIGGER. Si estamos creando el registro de vista materializada para una cuenta de usuario que no es
propietaria de la tabla origen, necesitamos tener los permisos de sistema CREATE ANY TABLE, COMMENT
ANY TABLE y CREATE ANY TRIGGER, as como el permiso SELECT sobre la tabla origen de la vista.
9.9. Modificando vistas materializadas y registros.
Podemos modificar los parmetros de almacenamiento, opciones de refresco, y planificacin de refresco para
vistas materializadas existentes. Si no estamos seguros de las opciones actuales para una instantnea, podemos
consultar la vista USER_MVIEWS del diccionario de datos.
El siguiente ejemplo muestra cmo modificar la opcin de refresco para la vista materializada LOCAL_LIBRO
usando el comando ALTER MATERIALIZED VIEW.
ALTER MATERIALIZED VIEW LOCAL_LIBRO
REFRESH COMPLETE;
Todos los futuros refrescos de LOCAL_LIBRO refrescarn la tabla base local por completo.
Para modificar una vista materializada debemos ser propietarios de la vista o tener el permiso de sistema
ALTER ANY MATERIALIZED VIEW.
Para modificar un registro de vista materializada debemos ser propietarios de la tabla, tener el permiso ALTER
para la tabla, o tener el permiso de sistema ALTER ANY TABLE.
Si creamos una vista materializada sin las clusulas RowID o SEQUENCE, podemos aadirlas despus mediante
el comando ALTER MATERIALIZED VIEW.
9.10. Eliminando vistas materializadas y registros.
Para borrar una vista materializada debemos tener los permisos de sistema requeridos para borrar tanto la
vista como todos los objetos relacionados. Necesitamos tener el permiso DROP MATERIALIZED VIEW si los
objetos estn en nuestro esquema, o el permiso DROP ANY MATERIALIZED VIEW si la vista no est en nuestro
esquema.
El siguiente comando borra la vista materializada LOCAL_CATEGORIA_COUNT:
DROP MATERIALIZED VIEW LOCAL_CATEGORIA_COUNT;

Nota. Cuando borramos una vista materializada que fue creada sobre una tabla predefinida, la tabla
todava existir pero la vista ser borrada.
Los registros de vista materializada pueden ser borrados mediante el comando DROP MATERIALIZED VIEW
LOG. Una vez que el registro de vista materializada es borrado de una tabla origen, ya no se harn refrescos
rpidos para las vistas materializadas simples basadas en la tabla. Un registro de vista materializada debera ser
borrado cuando no haya vistas materializadas simples basadas en la tabla origen. El siguiente comando borra
el registro de vista materializada que fue creado para la tabla LIBRO previamente:
DROP MATERIALIZED VIEW LOG ON LIBRO;
Para borrar el registro de vista materializada debemos tener la habilidad de borrar tanto el registro de vista
como sus objetos relacionados. Si somos el propietario del registro, debemos tener los permisos de sistema
DROP TABLE y DROP TRIGGER. Si no somos propietarios del registro necesitamos los permisos DROP ANY
TABLE y DROP ANY TRIGGER para ejecutar este comando.

Oracle /234
10. Oracle Text
Como la cantidad de texto en nuestras bases de datos aumenta, se hacen ms complejas las consultas sobre
texto de la base de datos. En vez de realizar bsquedas de strings por comparacin podemos usar las nuevas
funcionalidades de bsqueda de texto (cosas como dar peso a trminos en una bsqueda de varios trminos,
o clasificar los resultados de una bsqueda de texto).
Podemos usar Oracle Text para realizar bsquedas basadas en texto. Las capacidades de bsqueda de texto
incluyen caracteres comodn, bsquedas difusas, clasificacin por importancia, bsquedas por proximidad,
trminos con peso, y expansin de palabras.
10.1. Aadiendo texto a la base de datos.
Podemos aadir texto a una base de datos bien almacenando fsicamente el texto en una tabla o bien
almacenando punteros a ficheros externos de la base de datos. Esto es, para los libros de una estantera,
podemos almacenar trozos en la base de datos o en archivos externos. Si almacenamos los trozos en archivos
externos, entonces podemos almacenar los nombres del archivo en la base de datos
Para almacenar trozos de libros en nuestra base de datos, podemos crear la tabla TROZO_LIBRO. Para los
ejemplos de este captulo crearemos dos tablas: TROZO_LIBRO_CONTEXT y TROZO_LIBRO_CTXCAT. Ambas
tablas cargarn los mismos datos y cada una usar un tipo de ndice distinto.
CREATE TABLE TROZO_LIBRO_CONTEXT (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(25),
Fecha_Libro DATE,
Trozo VARCHAR2(4000)
);
/
INSERT INTO TROZO_LIBRO_CONTEXT VALUES (
'La montaa de luz',
'Emilio Salgari',
'01-MAY-02',
'Una muy calurosa tarde de julio de 1843, un elefante de estatura gigantesca, trepaba fatigosamente
los ltimos escalones del altiplano de Pannah, uno de los ms salvajes y al mismo tiempo ms pintorescos
de la India central.'
);
/
CREATE TABLE TROZO_LIBRO_CTXCAT (
Titulo VARCHAR2(100) PRIMARY KEY,
Autor VARCHAR2(25),
Fecha_Libro DATE,
Trozo VARCHAR2(4000)
);
/
INSERT INTO TROZO_LIBRO_CTXCAT VALUES (
'La montaa de luz',
'Emilio Salgari',
'01-MAY-02',
'Una muy calurosa tarde de julio de 1843, un elefante de estatura gigantesca, trepaba fatigosamente
los ltimos escalones del altiplano de Pannah, uno de los ms salvajes y al mismo tiempo ms pintorescos
de la India central.'
);
La columna Trozo de las tablas has sido definida como VARCHAR2(4000). Para valores grandes podemos
considerar el uso del tipo CLOB.
Podemos seleccionar el texto del trozo desde la base de datos con la siguiente consulta:
SELECT Trozo
FROM TROZO_LIBRO_CONTEXT
WHERE Titulo = 'La montaa de luz';
10.2. Consultas de texto e ndices de texto.
Las consultas de texto son diferentes de las consultas de datos porque las palabras tienen significado,

Oracle /235
relaciones con otras palabra y opuestos. Podemos querer buscar palabras que estn cerca de otras, o palabras
que estn relacionadas con otras. Estas consultas deberan ser difciles de hacer con los operadores
relacionales estndar. Al extender SQL para incluir ndices de texto, Oracle Text permite realizar consultas
muy complejas sobre el texto.
Para usar Oracle Text, necesitamos crear un ndice de texto sobre la columna en la cual se almacena el texto.
Un ndice de texto es un trmino ligeramente confuso (actualmente es una coleccin de tablas e ndices que
almacenan informacin acerca del texto guardado en la columna).
Veremos cmo crear dos tipos de ndices de texto: CONTEXT y CTXCAT. Podemos usar tambin un tercer tipo
de ndice, CTXRULE, para crear una aplicacin de clasificacin de documentos basada en contenido.
Nota. Antes de crear un ndice de texto sobre una tabla debemos crear una clave primaria para la
tabla, sin es que an no existe.
Podemos crear un ndice de texto mediante una versin especial del comando CRATE INDEX. Para un ndice
CONTEXT se especifica el tipo CTXSYS.CONTEXT en la clusula INDEXTYPE, tal como se muestra a
continuacin:
CREATE INDEX Trozo_Context_Index
ON TROZO_LIBRO_CONTEXT(Trozo)
INDEXTYPE IS CTXSYS.CONTEXT;
Cuando se crea el ndice de texto, Oracle crea varios ndices y tablas en nuestro esquema para soportar las
consultas de texto. Podemos reconstruir nuestro ndice de texto mediante el comando ALTER INDEX, tal como
se hace con otros ndices.
Podemos usar un ndice CTXCAT en lugar del tipo CONTEXT:
CREATE INDEX Trozo_Ctxcat_Index
ON TROZO_LIBRO_CTXCAT(Trozo)
INDEXTYPE IS CTXSYS.CTXCAT;
El tipo de ndice CTXCAT soporta sincronizacin transaccional de datos entre la tabla base
(TROZO_LIBRO_CTXCAT) y sus ndices de texto. Con ndices CONTEXT necesitamos actualizar manualmente el
ndice de texto despus de cada cambio en la tabla base. Los ndices de tipo CTXCAT no generan valores de
"puntuacin" durante las consultas de texto (como s lo hacen los ndices CONTEXT), pero la sintaxis de
consulta es ms larga.
10.2.1. Consultas de texto.
Una vez creado un ndice de texto sobre la columna Trozo de la tabla TROZO_LIBRO_CONTEXT, las
capacidades de bsqueda de texto se incrementa dramticamente. Ahora podemos mirar por cualquier libro
que contenga la palabra 'elefante':
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'elefante') > 0;

Nota. En esta bsqueda no se tienen en cuenta las maysculas y minsculas de la palabra buscada.
La funcin CONTAINS tiene dos parmetros (el nombre de la columna y el string de bsqueda) y comprueba
el ndice de texto para la columna Trozo. Si la palabra "elefante" es encontrada en el texto de la columna Trozo,
entonces la base de datos retorna un valor de puntuacin mayor que 0. La puntuacin es una valoracin de
cmo los registros retornados casan con el criterio especificado por la funcin CONTAINS.
Si creamos un ndice CTXCAT, debemos usar la funcin CATSEARCH en vez de CONTAINS. La funcin
CATSEARCH tiene tres parmetros: el nombre de columna, el string de bsqueda, y el nombre del conjunto de
ndice. (Los conjuntos de ndices son descritos posteriormente en este captulo.) En este ejemplo no hay
ningn conjunto de ndice, as que el parmetro se asignar a NULL:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'elefante', NULL) > 0;
CATSEARCH no computa puntuaciones, pero usa la sintaxis >0 por una cuestin de compatibilidad con la
funcin CONTAINS.
Cuando una funcin como CONTAINS o CATSEARCH se usa en una consulta, la porcin de texto de la
consulta es procesada por Oracle Text. El resto de la consulta es procesado de forma regular. Los resultados
de la consulta de texto y el procesamiento de la consulta normal son combinados para retorna un nico
conjunto de registros.

Oracle /236
10.2.2. Expresiones de consultas de texto disponibles.
Oracle Text sera muy limitado si slo se dedicara a buscar coincidencia de palabras. Oracle Text ofrece
muchas capacidades de bsqueda que podemos usar para personalizar nuestras consultas. Muchas de estas
capacidades se aplican mediante las funciones CONTAINS y CATSEARCH, las cuales slo operan en la clusula
WHERE de una consulta SELECT, y nunca en comandos INSERT, UPDATE o DELETE.
Los operadores dentro de CONTAINS y CATSEARCH permiten realizar las siguientes bsquedas de texto:
Coincidencia exacta de palabas o frases.
Coincidencia exacta de varias palabras, usando lgica booleana para combinar bsquedas.
Bsquedas basadas en cmo unas palabras estn cerca de otras.
Bsqueda de palabras que tienen la misma palabra "raz".
Coincidencias difusas de palabras.
Bsquedas de palabras que suenan como otras.
10.2.3. Buscando la coincidencia exacta de una palabra.
La siguiente consulta sobre las tablas TROZO_LIBRO retorna el ttulo de todos los trozos que incluyen la
palabra 'India':
REM Mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India') > 0;
REM Mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'India', NULL) > 0;
Dentro de las llamadas a la funcin, el operador > es denominado un operador de umbral. La consulta
precedente puede ser leda de la siguiente manera:
Selecciona todos los valores de la columna Titulo
Dentro de la tabla TROZO_LIBRO_CONTEXT
Donde la puntuacin para la bsqueda de texto de la columna Trozo
Para una bsqueda exacta de la palabra 'India' exceda un valor de umbral cero
El anlisis de umbral compara la puntuacin (la puntuacin interna calculada por Oracle cuando se realiza la
bsqueda de texto) con el valor de umbral. Los valores de umbral para bsquedas individuales estn en el
rango 0 a 10. Para ndices CONTEXT podemos mostrar esta puntuacin como parte de la consulta.
Para mostrar la puntuacin del texto buscado, se usa la funcin SCORE, la cual tiene un nico parmetro (una
etiqueta que asignamos a la puntuacin dentro del texto buscado):
SELECT Titulo, SCORE(10)
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India', 10) > 0 ;
TITULO SCORE(10)
------------------------------ --------------
La montaa de luz 3
En esta consulta, los parmetros de la funcin CONTAINS se modifican para incluir una etiqueta (10) para
realizar la operacin de bsqueda. La funcin SCORE muestra la puntuacin de la bsqueda de texto asociada
con la etiqueta. La puntuacin es un clculo interno basado en cmo el texto indexado coincide con el
criterio.
En ndices CONTEXT podemos usar la funcin SCORE en la lista del SELECT o en un GROUP BY o en un ORDER
BY.
10.2.4. Buscando por coincidencia exacta en varias palabras.
Para buscar por varias palabras podemos usar lgica booleana (con operadores AND y OR) para combinar los
resultados de varia bsquedas de texto en una nica consulta. Podemos tambin buscar por varios trminos
en la misma llamada a la funcin y dejar que Oracle resuelva el resultado de la bsqueda.
Por ejemplo, si queremos buscar por libros que tengan las palabras "India" y "elefante" en el texto del trozo,
podemos usar la siguiente consulta:
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT

Oracle /237
WHERE CONTAINS(Trozo, 'India AND elefante') > 0;
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT TITLE
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'India AND elefante', NULL) > 0;

Nota. Esta bsqueda no busca por la frase "India and elefante" sino que busca por cada palabra
individual del texto.
En vez de usar AND en el ndice CONTEXT, podramos usar un ampersand (&). Antes de usar este mtodo en
SQL*Plus, deberamos asignar SET DEFINE OFF para que el caracter & no sea visto como parte del nombre de
variable:
SET DEFINE OFF
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India & elefante') > 0;
Para el ndice CTXCAT, la palabra AND puede ser obviada:
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'India elefante', NULL) > 0;
Usar el caracter & o la palabra AND denotas una operacin AND (as que la funcin CONTAINS retornar un
fila slo si el texto revisado incluye ambas palabra "India" y "elefante".
Cada bsqueda debe pasar los criterios de umbral definidos por las puntuaciones de bsqueda. Si queremos
buscar por ms de dos trminos basta con aadirlos a la funcin CONTAINS o CATSEARCH:
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India AND elefante AND julio') > 0;
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(REVIEW_TEXT, 'India elefante julio', NULL) > 0;
Adems del operador AND, podemos usar el operador OR. El smbolo de OR para Oracle Text es la barra
horizontal ( | ), as que las dos siguientes consultas son procesadas idnticamente:
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India OR elefante') > 0;
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India | elefante') > 0;
El operador ACCUM proporciona otro mtodo para combinar bsquedas. ACCUM suma las puntuaciones de
bsquedas individuales y compara las puntuaciones acumuladas con el valor de umbral. El smbolo para
ACCUM es una coman (,). Por lo tanto estas dos consultas son equivalentes:
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India ACCUM elefante') > 0;
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India , elefante') > 0;
La sintaxis ACCUM es soportada por la funcin CATSEARCH pero debera no ser usada porque CATSEARCH no
calcula una puntuacin para comparar el valor de umbral.
Podemos usar Oracle Text para restar las puntuaciones de varias bsquedas antes de comparar el resultado a
la puntuacin de umbral. El operador MINUS en CONTAINS resta la puntuacin de la bsqueda del segundo

Oracle /238
trmino de la puntuacin de la resta del primer trmino. La consulta siguiente determinar la puntuacin de
bsqueda de 'India' y lo restar de la puntuacin de bsqueda de 'casa' y entonces comparar la diferencia
con la puntuacin de umbral.
En este ejemplo, el segundo trmino ('casa') no se encuentra en el texto indexado. Si el segundo trmino est
en el texto (por ejemplo 'elefante'), entonces no retornar ninguna fila.
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India MINUS casa') > 0;
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'India - casa') > 0;
Podemos usar el smbolo menos () en lugar del operador MINUS, tal como se ha mostrado en el ejemplo
previo.
Para ndices CONTEXT el operador reduce la puntuacin cuando comparamos la puntuacin de bsqueda
total con el valor de umbral, pero no elimina la fila a considerar. Para eliminar filas basadas sobre trminos de
bsqueda en ndices CONTEXT, se usa el caracter ~ como el operador NOT.
Para ndices CTXCAT, el smbolo tiene un significado diferente al de los ndices CONTEXT. Para ndices
CTXCAT, el signo le dice a Oracle Text que no retorne la fila si el trmino de bsqueda despus del guin se
encuentra (como ~ en ndices CONTEXT). Si el segundo trmino es encontrado, CATSEARCH no retornar la
fila.
Para consultas CATSEARCH podemos reemplazar el guion por la palabra NOT.
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'India - elefante', NULL) > 0;
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'Indica NOT elefante', NULL) > 0;
Podemos usar parntesis para aclarar la lgica dentro de nuestro criterio de bsqueda. Si nuestra bsqueda
usa tanto AND como OR, deberamos usar parntesis para aclarar el camino en el cual las filas deben ser
procesadas. Por ejemplo, la siguiente consulta retorna una fila si el texto de bsqueda contiene la palabra
'casa' o las palabras 'India' y 'elefante' a la vez.
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(REVIEW_TEXT, 'casa OR (India AND elefante)') > 0;
La funcin CATSEARCH no requiere la palabra AND entre 'India' y 'elefante':
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(REVIEW_TEXT, 'casa | (India elefante)', NULL) > 0;
Cuando evaluamos las puntuaciones de varias bsquedas mediante ndices CONTEXT, podemos decirle a
Oracle Text el peso de las puntuaciones de algunas bsquedas ms importantes de otras. Por ejemplo, si
queremos que la puntuacin para 'India' sea el doble cuando comparamos el puntuacin de umbral, podemos
usar el asterisco (*) para indicar el factor por el cual la puntuacin de bsqueda se multiplicar.
La siguiente consulta doblar la puntuacin de bsqueda para 'India' cuando lo evaluemos en una condicin
OR:
SELECT Titulo, SCORE(10)
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(REVIEW_TEXT, 'India*2 OR elefante*1', 10) > 5;

Nota. El operador EQUIV trata dos trminos de bsqueda como el mismo durante la puntuacin de
bsqueda. EQUIV (el cual puede ser reemplazado por =) puede ser til en combinaciones con los
operadores que comparan puntuaciones de bsqueda.

Oracle /239
10.2.5. Bsqueda por coincidencia de una frase.
Cuando buscamos por coincidencia en una frase, debemos especificar la frase como parte del string de
bsqueda. Si la frase incluye una palabra reservada (como "and", "or", o "minus"), necesitamos usar los
caracteres de escape mostrados en esta seccin para que la bsqueda sea ejecutada apropiadamente. Si la frase
buscada incluye una palabra reservada de Oracle Text, entonces debemos usar las llaves { y } para encerrarla.
La siguiente consulta busca por cualquier prrafo que incluya la frase "muy calurosa tarde".
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'muy calurosa tarde') > 0;
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT TITLE
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(REVIEW_TEXT, '"muy calurosa tarde"', NULL) > 0;
La siguiente consulta busca la frase "transactions and finances". La palabra "and" es encerrada entre llaves.
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'transactions {and} finances') > 0;
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, '"transactions {and} finances"', NULL) > 0;
Podemos encerrar toda la frase entre llaves, en cuyo caso cualquier palabra reservada dentro de la frase ser
tratada como parte del criterio de bsqueda, tal como muestra el siguiente ejemplo:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, '{transactions and finances}') > 0;
10.2.6. Bsqueda de palabras que estn cerca de otras.
Podemos usar capacidades de bsqueda por proximidad para realizar una bsqueda basada en cmo trminos
cerrados estn cerca dentro del mismo documento. Una bsqueda de proximidad retorna una puntuacin alta
para palabras que estn cercas de las otras, y retorna una puntuacin baja para palabras que estn apartadas. Si
las palabras continan una a la otra, la bsqueda de proximidad retorna una puntuacin de 100.
Para usar bsqueda de proximidad a travs de ndices CONTEXT se usa la palabra NEAR, como en el siguiente
ejemplo:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'elefante NEAR estatura')>0;
Podemos reemplazar el operador NEAR por el smbolo de punto y coma (;).
En las consultas con ndice CONTEXT podemos especificar el mximo nmero de palabras entre los trminos
buscados. Por ejemplo, para palabras dentro de una separacin de 10 palabras de otra, podemos usar la
cadena de bsqueda 'NEAR((India, elefante),10)'.
10.2.7. Usando caracteres comodn durante bsquedas.
En los ejemplos previos de este captulo, las consultas seleccionan valores de texto que coinciden
exactamente con los criterios especificados. Podemos usar caracteres comodines para ampliar la lista de
trminos de bsqueda vlidos durante nuestra consulta.
Al igual que con las expresiones regulares usadas con el operador LIKE, hay dos caracteres comodines
disponibles:
% representa cualquier cadena de texto de cero o ms caracteres de cualquier longitud.
_ representa un carcter.
La siguiente consulta busca por todas las coincidencias de texto para palabras que comienzan con los
caracteres "escalo":
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'escalo%') > 0;
La siguiente consulta limita la expansin del string de texto exactamente a tres caracteres. En lugar del signo

Oracle /240
% se usan tres guiones de subrayado (_ _ _).
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'escalo___') > 0;
Deberamos usar caracteres comodines cuando conozcamos algunos caracteres pertenecientes al string de
bsqueda. Si no estamos seguros del string de bsqueda, deberamos usar uno de los mtodos descritos en las
siguientes secciones: palabras races, coincidencias difusas o coincidencias SOUNDEX.
10.2.8. Buscando palabras que tienen la misma raz.
En vez de usar caracteres comodines podemos usar las capacidades de expansin por raz para ampliar la lista
de strings de texto. Dada la raz de una palabra, Oracle ampla la lista de palabras para buscar por todas las
palabras que tengan la misma raz. Unas ampliaciones simples se muestran a continuacin:
Raz Raz ampliada
casa casamentera, casanova, casado
trabajo trabajador, trabajoso
historia historiador
Como "trabajo" y "trabajador" tienen la misma raz, una bsqueda de raz-ampliada usando la palabra
"trabajador" retornar el texto que contenga la palabra "trabajo".
Para usar la ampliacin de raz con una consulta necesitamos usar el signo de dlar ( $). Dentro de string de
bsqueda, el $ debe preceder inmediatamente a la palabra que queremos ampliar.
La siguiente consulta busca todos los trozos que contienen una palabra con la raz "gigante":
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(REVIEW_TEXT, '$gigante') > 0;
Cuando esta consulta se ejecuta, Oracle expande la palabra "gigante" para incluir todas las palabras con la
misma raz.
10.2.9. Bsquedas por coincidencia difusa.
Una bsqueda difusa amplia el trmino de bsqueda para incluir palabras que son fonticamente similares
pero que no necesariamente tiene la misma raz. Las bsquedas difusas son ms tiles cuando el texto
contiene erratas. Las erratas pueden estar tanto en el texto de bsqueda como en el string buscado.
Por ejemplo, la siguiente consulta no retornar el ttulo "La montaa de luz" porque no contiene la palabra
"elegante".
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'elegante') > 0;
Sin embargo, s contiene la palabra "elefante", quees muy parecida. Una bsqueda difusa retornar trozos que
contenga la palabra "elefante" aunque el trmino de bsqueda sea "elegante".
Para usar una bsqueda difusa, hay que preceder el trmino de bsqueda con un signo de interrogacin ( ?),
sin ningn espacio entre ellos. El siguiente ejemplo ilustra el uso de esta capacidad de coincidencia:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, '?elegante') > 0;
10.2.10. Bsqueda de palabras que suenan igual que otras palabras.
Las bsquedas de raz-ampliada amplan un trmino de bsqueda a varios trminos basados en una raz. Las
bsquedas difusas amplan la bsqueda a trminos basados en palabras similares en el ndice de texto. Una
tercera forma de ampliar trminos de bsqueda, SOUNDEX, amplia la bsqueda segn cmo suenan las
palabras. El mtodo de expansin SOUNDEX usa la misma lgica de coincidencia que la funcin SOUNDEX.
Para usar la opcin SOUNDEX, debemos preceder el trmino de bsqueda con una marca de exclamacin ( !).
Durante la bsqueda, Oracle evala los valores de SOUNDEX para los trminos en el ndice de texto y busca
por todas las palabras que tienen el mismo valor de SOUNDEX.
Como muestra la siguiente consulta, podemos buscar por los trozos que incluyan la palabra "fatigosamente"
usando la coincidencia fontica "fastidiosamente":
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Texto_Revidado, '!fastidiosamente') > 0;
Podemos tambin anidar operadores, permitiendo realizar ampliaciones por raz sobre los trminos

Oracle /241
retornados por una bsqueda difusa. En el siguiente ejemplo, se realiza una bsqueda difusa sobre la palabra
"alto", y el trmino retornado se ampla usando raz-ampliada:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, '$?alto') > 0;
Las opciones principales de bsqueda para CONTAINS se resumen en la siguiente tabla.
Operador Descripcin
OR Devuelve un registro si uno u otro trmino de bsqueda exceden el umbral.
| Equivalente a OR.
AND Devuelve un registro si ambos trminos de bsqueda exceden el umbral.
& Equivalente a AND.
ACCUM Devuelve un registro si la suma de las puntuaciones de los trminos de bsqueda exceden el
umbral
MINUS Devuelve un registro si la puntuacin de la primera bsqueda menos la puntuacin de la segunda
bsqueda exceden el umbral.
Equivalente a MINUS.
* Asigna diferentes pesos a la puntuacin de bsqueda.
NEAR La puntuacin se basar en cmo de cerca los trminos de bsqueda estn uno junto al otro en el
texto buscado.
; Equivalente a NEAR.
NOT Excluye el registro si el trmino despus del NOT es encontrado.
~ Equivalente a NOT.
EQUIV Trata dos trminos (term1 EQUIV term2) como el mismo durante la puntacin de bsqueda.
= Equivalente a EQUIV.
{} Encierra palabras reservadas como parte del trmino de bsqueda.
% Comodn para varios caracteres.
_ Comodn para un nico caracter.
$ Realiza expansin por raz.
? Realiza una bsqueda difusa.
! Realiza una bsqueda SOUNDEX.
() Especifica el orden en el cual el criterio de bsqueda es evaluado.
Las opciones de bsqueda para CATSEARCH se resumen en la siguiente tabla.
Operador Descripcin
| Devuelve un registro si uno de los trminos de bsqueda es encontrado.
AND Devuelve un registro si cada trmino de bsqueda es encontrado.
- Si hay espacios alrededor del guin, CATSEARCH retorna filas que contiene el trmino que
precede al guin y que no contienen el trmino que sigue al guin. Un guin sin espacios es
tratado como un caracter regular.
NOT Equivalente al guin.
"" Encierra frases.
() Especifica el orden en el cual el criterio de bsqueda es evaluado.
* Comodn para varios caracteres. Puede estar al final del trmino o en el medio de los caracteres.
10.2.11. Usando el operador ABOUT.
En Oracle Text podemos buscar sobre temas de documentos. La bsqueda temtica est integrada con la
bsqueda de trminos de texto. Podemos usar el operador ABOUT para buscar trminos que tienen que ver
con el tema del documento en vez de trminos especficos dentro del documento. Aqu hay un ejemplo:
REM mtodo CONTAINS para ndices CONTEXT:
SELECT Titulo
FROM TROZO_LIBRO_CONTEXT
WHERE CONTAINS(Trozo, 'ABOUT(Medicina)') > 0;
REM mtodo CATSEARCH para ndices CTXCAT:
SELECT Titulo
FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH(Trozo, 'ABOUT(Medicina)', NULL) > 0;

Oracle /242
10.2.12. Sincronizacin de ndice.
Por defecto, cuando usamos ndices CONTEXT, tenemos que gestionar los contenidos del ndice de texto; los
ndices de texto no sern actualizados cuando la tabla base sea actualizada. En cuanto un valor del campo
Trozo sea actualizado, el ndice de texto dejar de estar sincronizado con la tabla base. Para sincronizar el
ndice hay que ejecutar el procedimiento CTX_DDL. SYNC_INDEX, tal como se muestra a continuacin:
EXECUTE CTX_DDL.SYNC_INDEX('Trozo_Context_Index');

Nota. Debemos conceder el permiso EXECUTE sobre el paquete CTX_DDL al usuario para soportar
estas actividades de mantenimiento.
Desde Oracle Database 10g, los ndices CONTEXT pueden mantenerse automticamente, en el momento de
confirmacin de cambios, o en intervalos especificados. Como parte del comando CREATE INDEX para un
ndice CONTEXT, podemos usar la clusula SYNC:
[[METADATA] SYNC (MANUAL | EVERY "intervalo" | ON COMMIT)]
Aqu hay un ejemplo:
DROP INDEX Trozo_Context_Index;
/
CREATE INDEX Trozo_Context_Index
ON TROZO_LIBRO_CONTEXT(Trozo)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('SYNC (ON COMMIT)');
10.3. Conjuntos de ndices.
Histricamente, los problemas con consultas de ndices de texto han ocurrido cuando otros criterios son
usados sobre el texto de bsqueda como parte de la clusula WHERE. Por ejemplo, cundo se aplican
clusulas WHERE sobre columnas no de texto?, antes o despus de que la bsqueda de texto se complete?, y
cmo se ordena los resultados apropiadamente? Para mejorar las capacidades de mezclar consultas podemos
usar conjuntos de ndices. Los ndices dentro del conjunto pueden ser sobre columnas relacionales
estructuradas o columnas de texto.
Para crear un conjunto de ndices se usa el paquete CTX_DDL para crear el conjunto de ndices y aadirle
ndices. Cuando creamos un ndice de texto podemos entonces especificar el conjunto de ndices. Por
ejemplo, para crear un conjunto de ndices llamado Trozos, se usa el procedimiento CREATE_INDEX_SET:
EXECUTE CTX_DDL.CREATE_INDEX_SET('Trozos');
Ahora podemos aadir ndices al conjunto mediante el procedimiento ADD_INDEX. Primero aadiremos unos
estndar, ndices no de texto:
EXECUTE CTX_DDL.ADD_INDEX('Trozos', 'Autor');
EXECUTE CTX_DDL.ADD_INDEX('Trozos', 'Fecha_Libro');
Ahora crearemos un ndice de texto CTXCAT. Se especifica CTXSYS.CTXCAT como tipo de ndice, y el conjunto
de ndices en la clusula PARAMETERS:
CREATE INDEX Trozo_CtxCat_Indice
ON TROZO_LIBRO_CTXCAT(Trozo)
INDEXTYPE IS CTXSYS.CTXCAT
PARAMETERS ('INDEX SET Trozos');
Ahora podemos ordenar nuestros resultados por el resultado de la bsqueda del conjunto de ndices
combinados:
SELECT * FROM TROZO_LIBRO_CTXCAT
WHERE CATSEARCH( Trozo, 'julio',
'Autor=''Emilio Salgari''
ORDER BY Fecha_Libro DESC') > 0;
Para resolver esta consulta, Oracle Text usar el conjunto de ndices, permitiendo ordenar los resultados
apropiadamente, por fecha. Ntese que se han utilizado dos comillas seguidas para encapsular 'Emilio Salgari',
para que de esta forma sean convertidas a una comilla simple cuando la consulta se ejecute.
Los conjuntos de ndices pueden contener hasta 99 ndices de tipos NUMBER, DATE, CHAR y VARCHAR2. Las
columnas en un ndice del conjunto no pueden exceder de 30 bytes (as que en este ejemplo, la columna Titulo
no puede ser indexada como parte del conjunto de ndices). Las columnas de los ndices no pueden contener
valores nulos.
Desde Oracle Database 10g, Oracle Text incluye una facilidad de trazado para ayudar a identificar cuellos de
botella en la indexacin y consultas. Se usa el procedimiento CTX_OUTPUT.ADD_TRACE para habilitar el
Oracle /243
trazado. Las trazas disponibles incluyen el tiempo gastado sobre los diferentes componentes de la bsqueda,
el nmero de octetos ledos, y el nmero de filas procesadas.
11. Uso de tablas externas
Podemos usar la funcionalidad de tablas externas para acceder a ficheros externos como si fuesen tablas
dentro de la base de datos. Cuando creamos una tabla externa podemos definir su estructura y localizacin
dentro de Oracle. Cuando consultamos la tabla, Oracle lee la tabla externa y retorna los resultados tal como si
los datos estuviesen almacenados dentro de la base de datos. Lo mejor es que, aunque los datos estn fuera de
la base de datos, no necesitamos conocer el proceso de carga dentro de la base de datos.
Las tablas externas tiene lmites (no podemos actualizar o borrar sus registros dentro de Oracle, y no
podemos indexarlas). Debido a que son parte de nuestra aplicacin de base de datos, tendremos que incluirlas
como parte de nuestros procesos de copias de respaldo y recuperacin. A pesar de estas complicaciones, las
tablas externas pueden ser una potente adicin a nuestra arquitectura de base de datos. Desde Oracle
Database 10g, podemos usar tablas externas para descargar datos desde tablas a ficheros externos mediante
dispositivos de acceso ORACLE_DATAPUMP.
11.1. Accediendo a datos externos.
Para acceder a ficheros externos dentro de Oracle debemos primero usar el comando CREATE DIRECTORY
para definir un objeto DIRECTORY que apunte a la ubicacin de los ficheros externos. Los usuarios que
accedan a los ficheros externos deben tener el permiso READ sobre el directorio.
Nota. Antes de empezar, debemos verificar que el directorio externo existe y que el usuario que
publicar el comando CREATE DIRECTORY tenga el permiso de sistema CREATE ANY DIRECTORY.
El siguiente ejemplo crea un directorio llamado LIBRO_DIR y concede accesos READ y WRITE al esquema
Empleado:
CREATE DIRECTORY LIBRO_DIR AS 'e:\oracle\external';
GRANT READ ON DIRECTORY LIBRO_DIR TO Empleado;
GRANT WRITE ON DIRECTORY LIBRO_DIR TO Empleado;
El usuario Empleado puede ahora leer ficheros del directorio e:\oracle\external
como si estuviera dentro de la
base de datos. Al tener permiso de escritura, el usuario puede crear ficheros de log, descartes y "malos"
dentro del directorio.
La siguiente lista genera dos ficheros para datos de ejemplo (uno para LIBRO y otro para AUTOR). Ntese que
el comando SPOOL no usa el nombre de directorio creado, sino que hay que especificar la ruta fsica del
directorio.
CONNECT Empleado/contrasea
SET PAGESIZE 0 NEWPAGE 0 FEEDBACK OFF
SPOOL e:\oracle\external\libro_dump.lst
SELECT Titulo || '~' || Autor || '~' || Categoria || '~' || Valoracion || '~'
FROM LIBRO
ORDER BY Titulo;
SPOOL OFF
SPOOL e:\oracle\external\autor_dump.lst
SELECT Titulo || '~' || Autor || '~'
FROM AUTOR
ORDER BY Titulo;
SPOOL OFF

Nota. El comando SPOOL de SQL*Plus permite redirigir la salida a un fichero de texto. Los datos
no se materializarn en el fichero de texto hasta que se ejecute SPOOL OFF.
Adems de los datos, los ficheros de salida contendrn la consulta en las lneas iniciales y una lnea final con
"SQL> SPOOL OFF". Para simplificar los ejemplos, deberamos manualmente editar los ficheros al nivel del
sistema operativo y eliminar estas lneas extra.
Si otro usuario debe acceder a los datos de los ficheros libro_dump.lst y autor_dump.lst, debemos concederle el
permiso READ sobre el directorio LIBRO_DIR:
GRANT READ ON DIRECTORY LIBRO_DIR TO otroUsuario;
Tambin los ficheros mismos deber ser legibles por el usuario de Oracle al nivel del sistema operativo.

Oracle /244
11.2. Creando una tabla externa.
Ahora que hay datos externos disponibles y accesibles, podemos crear una estructura de tabla que acceda a
ellos. Para hacer esto necesitamos usar la clusula ORGANIZATION EXTERNAL del comando CREATE TABLE.
Dentro de esta clusula podemos especificar la estructura de datos, tal como se hace en el fichero de control
de SQL*Loader.
11.2.1. Usando el controlador ORACLE_LOADER.
El siguiente listado muestra la creacin de la tabla LIBRO_EXT, basada en los datos del fichero libro_dump.lst
creado previamente.
SET FEEDBACK ON HEADING ON NEWPAGE 1 PAGESIZE 60
CREATE TABLE LIBRO_EXT (
Titulo VARCHAR2(100),
Autor VARCHAR2(20),
Categoria VARCHAR2(20),
Valoracion NUMBER(2)
) ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY LIBRO_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY "~" (
Titulo CHAR(100),
Autor CHAR(20),
Categoria CHAR(20),
Valoracion INTEGER EXTERNAL (2)
)
)
LOCATION ('libro_dump.lst')
);
Oracle responder con:
Tabla creada.
Aunque ningn dato ha sido creado dentro de la base de datos de Oracle. De forma similar podemos crear
una tabla basada en el fichero autor_dump.lst:
CREATE TABLE AUTOR_EXT (
Nombre VARCHAR2(20),
Nacionalidad VARCHAR2(50)
) ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY LIBRO_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY "~" (
Nombre CHAR(20),
Nacionalidad CHAR(50)
)
)
LOCATION ('autor_dump.lst')
);
Oracle realizar slo validacin superficial cuando la tabla externa es creada. No veremos la mayor parte de
los errores hasta que intentemos consultar la tabla. La sintaxis para los parmetros de acceso es muy
especfica, y errores menores en la definicin de acceso (incluyendo el orden de la clusula) pueden evitar que
todas las filas sean accedidas.
Podemos verificar el contenido de las tablas externas consultndolas y comparndolas con las tablas fuentes:
SELECT Titulo FROM LIBRO;
SELECT Titulo FROM LIBRO_EXT;
Podemos combinar la tabla "interna" AUTOR con su contrapartida externa, AUTOR_EXT, para verificar que no
hay registros perdidos o aadidos:
SELECT *

Oracle /245
FROM AUTOR A
WHERE NOT EXISTS
(SELECT 'X' FROM AUTOR_EXT AE WHERE A.Nombre = AE.Nombre);
Como resultado, esta consulta no retornar ningn registro.
La tabla AUTOR_EXT apunta al fichero autor_dump.lst. Si modificamos los datos en el fichero, los datos
consultados sobre AUTOR_EXT cambiarn.
Podemos consultar la vista USER_EXTERNAL_TABLES del diccionario de datos para informarnos sobre
nuestras tablas externas, incluyendo el directorio por defecto y definiciones de acceso.
DESC USER_EXTERNAL_TABLES
Name Null? Type
----------------------------------------- -------- --------------------
TABLE_NAME NOT NULL VARCHAR2(30)
TYPE_OWNER CHAR(3)
TYPE_NAME NOT NULL VARCHAR2(30)
DEFAULT_DIRECTORY_OWNER CHAR(3)
DEFAULT_DIRECTORY_NAME NOT NULL VARCHAR2(30)
REJECT_LIMIT VARCHAR2(40)
ACCESS_TYPE VARCHAR2(7)
ACCESS_PARAMETERS VARCHAR2(4000)
PROPERTY VARCHAR2(10)
Por ejemplo, la tabla AUTOR_EXT usa LIBRO_DIR como directorio por defecto como mostrara la siguiente
consulta:
SELECT DEFAULT_DIRECTORY_NAME, ACCESS_PARAMETERS
FROM USER_EXTERNAL_TABLES
WHERE TABLE_NAME = 'AUTOR_EXT';
DEFAULT_DIRECTORY_NAME ACCESS_PARAMETERS
------------------------------------ ---------------------------------------------
LIBRO_DIR RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY "~"
(Nombre CHAR(20),
Nacionalidad CHAR(50))
La vista USER_EXTERNAL_TABLES no muestra el nombre del fichero externo (o ficheros) que la tabla
referencia. Para ver esta informacin podemos consultar la vista USER_EXTERNAL_LOCATIONS:
SELECT * FROM USER_EXTERNAL_LOCATIONS;
TABLE_NAME LOCATION DIR DIRECTORY_NAME
------------------- --------------------------- ------ ------------------------
LIBRO_EXT libro_dump.lst SYS LIBRO_DIR
AUTOR_EXT autor_dump.lst SYS LIBRO_DIR
11.2.2. Usando el controlador ORACLE_DATAPUMP.
Podemos descargar datos desde tablas de la base de datos a ficheros externos mediante dispositivos de acceso
ORACLE_DATAPUMP. La sintaxis para utilizar el controlador de acceso ORACLE_DATAPUMP es la siguiente:
CREATE TABLE Tabla_externa
ORGANIZATION EXTERNAL (
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY objeto_directory
LOCATION ( 'fichero_externo' )
)
AS
SELECT id, nombre, direccion FROM Cliente ;
Con esta sintaxis no estamos creando realmente una tabla en la base de datos. En realidad, estamos creando
metadatos en el diccionario de datos que se pueden utilizar para acceder a datos externos. Dentro del
directorio referenciado por objeto_directory se crea un archivo con el nombre fichero_externo que contendr
los datos procedentes de la consulta utilizada para crear la tabla. Esta tabla puede ser consultada de la forma
habitual:
SELECT * FROM Tabla_externa;

Oracle /246
Podemos mover el archivo fichero_externo a otro sistema y crear una tabla externa para leer los datos:
CREATE TABLE Import_Tabla_externa (
id number,
nombre VARCHAR2(50),
direccion VARCHAR2(150)
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY objeto_directory
LOCATION ('fichero_externo')
);
11.2.3. Opciones de creacin de tablas externas.
Dentro de la clusula ORGANIZATION EXTERNAL hay cuatro sub-clusulas: TYPE, DEFAULT DIRECTORY,
ACCESS PARAMETERS, y LOCATION. Cuando creamos una tabla externa podemos estas clusulas para
personalizar el modo cmo Oracle ve los datos externos.
La clusula TYPE.
La sintaxis para el componente TYPE es:
( [TYPE tipo_dispositivo_acceso ] propiedades_datos_externos )
[REJECT LIMIT { entero | UNLIMITED }]
Para las tablas externas, el dispositivo de acceso es la API usada para transformar los datos externos. Se usa el
tipo ORACLE_LOADER para tablas externas de solo lectura, u ORACLE_DATAPUMP si queremos usar Data Pump
para tablas externas de lectura/escritura. Debemos especificar el dispositivo de acceso ORACLE_DATAPUMP si
usamos la clusula AS subconsulta para descargar datos desde una base de datos y entonces los recargamos. El
tipo de dispositivo de acceso ORACLE_LOADER es el de por defecto.
Nota. Ya que el dispositivo de acceso es parte del software de Oracle, slo los ficheros accesibles
por la base de datos pueden ser accedidos como tablas externas.
Despus de la declaracin de TYPE, podemos asignar un valor de lmite de rechazo ( REJECT LIMIT). Por
defecto, ninguna fila puede ser rechazada (cualquier problema con una fila causar que el comando SELECT
retorne un error). Generaremos otra copia de los datos de LIBRO en otro fichero:
SET PAGESIZE 0 NEWPAGE 0 FEEDBACK OFF
SPOOL e:\oracle\external\libro_dump_2.lst
SELECT Titulo || '~' || Autor || '~' || Categoria || '~' || Valoracion || '~' FROM LIBRO
/
SPOOL OFF
Ahora crearemos una nueva tabla que referencie este fichero, dicindole a Oracle que se salte las dos primeras
filas (SKIP 2) y que permita un error (REJECT LIMIT 1). Esto permitir saltarse las dos primeras lneas (con el
comando SELECT y la barra /) y evitar que la ltima lnea (SQL> SPOOL OFF) provoque un error:
SET FEEDBACK ON HEADING ON NEWPAGE 1 PAGESIZE 60
CREATE TABLE LIBRO_EXT_2 (
Titulo VARCHAR2(100),
Autor VARCHAR2(20),
Categoria VARCHAR2(20),
Valoracion NUMBER(2)
) ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY LIBRO_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
SKIP 2
FIELDS TERMINATED BY "~" (
Titulo CHAR(100),
Autor CHAR(20),
Categoria CHAR(20),
Valoracion INTEGER EXTERNAL (2)
)
)

Oracle /247
LOCATION ('libro_dump_2.lst')
) REJECT LIMIT 1 ;
Podemos ahora verificar el nmero de filas de la tabla:
SET FEEDBACK ON HEADING ON NEWPAGE 1 PAGESIZE 60
SELECT COUNT(*) FROM LIBRO_EXT_2;
La clusula DEFAULT DIRECTORY.
La clusula DEFAULT DIRECTORY especifica el objeto directorio que ser usado para todos los ficheros de
datos para los cuales no se especifica otro directorio. Si usamos varios ficheros externos localizados en varios
directorios podemos nombrar uno de ellos como el directorio por defecto y especificar los otros mediante su
nombre en la clusula LOCATION. Debemos usar nombres de objetos DIRECTORY (como LIBRO_DIR) en la
clusula LOCATION, no la ruta completa del directorio.
Parmetros de acceso.
La clusula ACCESS PARAMETERS le dice a Oracle cmo mapear las filas del fichero con la tabla. Su sintaxis se
muestra a continuacin:

Dentro de la clusula ACCESS PARAMETERS primero le decimos a Oracle cmo crear un registro (si su
longitud es fija o variable, y cmo estn delimitadas las filas). Si tenemos varias filas en una nica lnea,
podemos usar una cadena como un separador entre fila. Debido a que los datos externos pueden venir de
bases de datos diferentes de Oracle, Oracle soporta varios juegos de caracteres y tamaos de strings.
Como con SQL*Loader, podemos especificar una clusula WHEN para limitar qu registros son
seleccionados. En el siguiente listado se crea la tabla LIBRO_EXT_3, con una clusula WHEN para limitar slo a
los libros con categora 'ADULTO'.
CREATE TABLE LIBRO_EXT_3 (
Titulo VARCHAR2(100),
Autor VARCHAR2(20),
Categoria VARCHAR2(20),
Valoracion NUMBER(2)
) ORGANIZATION EXTERNAL (

Oracle /248
TYPE ORACLE_LOADER
DEFAULT DIRECTORY LIBRO_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
LOAD WHEN Categoria = 'ADULTO'
SKIP 2
FIELDS TERMINATED BY "~" (
Titulo CHAR(100),
Autor CHAR(20),
Categoria CHAR(20),
Valoracion INTEGER EXTERNAL(2)
)
)
LOCATION ('libro_dump_2.lst')
) REJECT LIMIT 1 ;
LIBRO_EXT_3 accede al mismo fichero que LIBRO_EXT_2, pero slo mostrar los registros de categora
'ADULTO'.
Al igual que con SQL*Loader, podemos crear un fichero de log, un fichero "malo" y un fichero de descarte.
Las filas que fallen la condicin WHEN sern escritos en el archivo de descartes. Las filas que fallen las
condiciones de los parmetros de acceso sern escritos en el fichero "malo", y los detalles de carga sern
escritos en el fichero de log. Para todos los tres tipos de ficheros podemos especificar un objeto DIRECTORY
con el nombre de archivo y as podemos escribir la salida a otro directorio distinto del directorio de entrada.
Podemos especificar NODISCARDFILE, NOBADFILE y NOLOGFILE para evitar que estos ficheros sean creados.
Dentro de la clusula ACCESS PARAMETERS podemos especificar las definiciones de campo y delimitadores
como:
FIELDS TERMINATED BY "~" (
Titulo CHAR(100),
Autor CHAR(20),
Categoria CHAR(20),
Valoracion INTEGER EXTERNAL(2)
)
Podemos usar la clusula MISSING FIELD VALUES ARE NULL para asignar valores para columnas nulas, pero
debemos tener cuidado cuando usemos esta opcin. Por ejemplo, la tabla AUTOR tiene valores nulos en su
columna Nacionalidad. La creacin de la tabla externa para AUTOR_EXT se muestra a continuacin:
SET PAGESIZE 0 NEWPAGE 0 FEEDBACK OFF
SPOOL e:\oracle\external\autor_dump.lst
SELECT Nombre || '~' || Nacionalidad || '~' FROM AUTOR ORDER BY Nombre
/
SPOOL OFF
SET FEEDBACK ON HEADING ON NEWPAGE 1 PAGESIZE 60
CREATE TABLE AUTOR_EXT (
Nombre VARCHAR2(50),
Nacionalidad VARCHAR2(100)
) ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY LIBRO_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
SKIP 2
FIELDS TERMINATED BY "~"
MISSING FIELD VALUES ARE NULL (
Nombre CHAR(50),
Nacionalidad CHAR(100)
)
)
LOCATION ('autor_dump.lst')
) REJECT LIMIT 1 ;

Oracle /249
Pero esto no es correcto. Si seleccionamos los valores de Nombre de la tabla AUTOR_EXT, veremos que los
valores incluyen lo siguiente:
SELECT Nombre FROM AUTOR_EXT WHERE Nombre LIKE 'S%';
Nombre
------------------------------------
Sax Rohmer
Sheridan Le Fanu
SQL> SPOOL OFF
Debido a la clusula MISSING FIELD VALUES ARE NULL, la lnea "SQL> SPOOL OFF" del final del fichero fue
leda como un valor de nombre de autor, con la nacionalidad a valor NULL. Esto ilustra el problema con la
codificacin de excepciones en nuestras definiciones de cargado. En muchos casos, nuestra integridad de
datos mejorar forzando que fallen filas (siendo enviadas al fichero "malo" o de descartes) y evaluando las
filas falladas aparte.
La clusula Location.
En la clusula LOCATION podemos especificar el fichero de datos usado como origen de datos para la tabla.
Podemos nombrar varios ficheros en esta clusula si todos existen en objetos DIRECTORY para los cuales el
usuario tiene permisos READ. El siguiente ejemplo combina dos ficheros independientes de LIBRO para
ilustrar la habilidad de combinar varios ficheros en una nica tabla externa.
CREATE TABLE LIBRO_EXT_4 (
Titulo VARCHAR2(100),
Autor VARCHAR2(20),
Categoria VARCHAR2(20),
Valoracion NUMBER(2)
) ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY LIBRO_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
SKIP 2
FIELDS TERMINATED BY "~" (
Titulo CHAR(100),
Autor CHAR(20),
Categoria CHAR(20),
Valoracion INTEGER EXTERNAL(2)
)
)
LOCATION ('libro_dump_2.lst', 'libro_dump.lst')
) REJECT LIMIT 1 ;
Elorden de los ficheros es importante; SKIP 2 se aplica al primer fichero, no al segundo.
11.3. Modificacin de tablas externas.
Podemos modificar las definiciones de una tabla externa para cambiar el modo en cmo Oracle interpreta el
fichero plano. Las opciones disponibles se detallan a continuacin.
Parmetros de acceso.
Podemos cambiar los parmetros de acceso sin borrar y recrear la definicin de la tabla externa, preservando
permisos, definicin del fichero y as. Por ejemplo, a continuacin se muestra cmo incrementar el nmero
de registros a saltarse en la tabla LIBRO_EXT_4:
ALTER TABLE LIBRO_EXT_4
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
SKIP 10
FIELDS TERMINATED BY "~" (
Titulo CHAR(100),
Autor CHAR(20),
Categoria CHAR(20),
Valoracion INTEGER EXTERNAL(2)
)

Oracle /250
);
Aadir columna.
Podemos usar la clusula ADD COLUMN del comando ALTER TABLE para aadir una columna a la tabla externa,
usando la misma sintaxis usada para tablas estndar.
Directorio por defecto.
Podemos usar la clusula DEFAULT DIRECTORY del comando ALTER TABLE para cambiar el directorio por
defecto para los ficheros externos accedidos por la tabla. El directorio debe ser creado mediante el comando
CREATE DIRECTORY.
Quitar columna.
Podemos usar la clusula DROP COLUMN del comando ALTER TABLE para quitar columnas de la tabla externa,
usando la misma sintaxis que la usada para tablas estndar. Los datos del fichero permanecern sin cambiar.
Localizacin.
Podemos cambiar los ficheros accedidos por la tabla externa mediante la clusula LOCATION del comando
ALTER TABLE. Podemos usar esta opcin para aadir nuevos ficheros a la lista o cambiar el orden en el cual
son accedidos.
Modificar columna.
Podemos usar la clusula MODIFY COLUMN del comando ALTER TABLE para modificar una columna de la tabla
externa, usando la misma sintaxis que la usada para tablas estndar.
Paralelismo.
Podemos usar la clusula PARALLEL del comando ALTER TABLE para cambiar el grado de paralelismo de la
tabla externa, usando la misma sintaxis que la usada para tablas estndar.
Proyectar columna.
La clusula PROJECT COLUMN del comando ALTER TABLE le dice a los dispositivos de acceso cmo validar
filas en consultar consecutivas. Si usamos la opcin PROJECT COLUMN REFERENCED, el dispositivo de acceso
slo procesar las columnas seleccionadas por la consulta. Si entonces consultamos un conjunto diferente de
columnas de la tabla externa, el resultado puede ser inconsistente con los resultados de la primera consulta. Si
se usa la opcin PROJECT COLUMN ALL, el dispositivo de acceso procesar todas las columnas definidas sobre
la tabla externa, resultando en un conjunto consistente de resultados. La opcin PROJECT COLUMN
REFERENCED es la de por defecto.
Lmite de rechazo.
Podemos usar la clusula REJECT LIMIT del comando ALTER TABLE para cambiar el nmero permitido de filas
rechazadas por la tabla externa. Aqu hay un ejemplo:
ALTER TABLE LIBRO_EXT_3 REJECT LIMIT 5;
Renombrar.
Podemos usar la clusula RENAME TO del comando ALTER TABLE para cambiar el nombre de la tabla externa,
usando la misma sintaxis que para las tablas estndar. Aqu hay un ejemplo:
ALTER TABLE LIBRO_EXT_3 RENAME TO BE3;
11.4. Limitaciones, beneficios y usos potenciales de las tablas externas.
Las tablas externas tienen limitaciones que pueden hacerlas inapropiadas para algunas aplicaciones que
procesan transacciones en lnea. No podemos realizar ninguna operacin de actualizacin o borrado sobre las
tablas externas. Cuanto ms dinmica es la tabla, menos apropiados son los ficheros externos. Podemos
cambiar los ficheros dinmicamente con operaciones al nivel del sistema operativo. Si nuestra aplicacin
genera slo inserciones, podemos escribir estos registros insertados dentro de un fichero externo en vez de
una tabla de base de datos.
No podemos indexar tablas externas. La falta de ndices sobre tablas externas no tiene por qu ser un factor
negativo en el funcionamiento de una aplicacin. Las consultas a tablas externas se completan muy
rpidamente, aun cuando requieran una exploracin completa de la tabla con cada acceso.
Nota. Para analizar tablas externas, se usa el paquete DBMS_STATS. No podemos analizar tablas
externas con el comando ANALYZE.
No podemos especificar restricciones sobre una tabla externa. Incluso crear una restriccin NOT NULL o de
clave fornea falla.
Al margen de estas limitaciones, las tablas externas ofreces muchas funcionalidades tiles. Podemos combinar
tablas externas (con otras, o con tablas estndar). Podemos usar etiquetas para forzar al optimizador a elegir

Oracle /251
varias formas de join.
Como una alternativa a la carga de datos, las tablas externas ofrecen a los DBA's y programadores de
aplicaciones la posibilidad de acceder a datos sin tener que soportar programas de cargas de larga duracin.
Ya que los ficheros pueden ser editados al nivel del sistema operativo, podemos rpidamente reemplazar los
datos rpidamente sin preocuparnos de transacciones que modifiquen las tablas. Por ejemplo, podemos usar
esta capacidad para crear varias tablas externas y crear una vista UNION ALL con ellas, creando una vista
particionada a travs de varios ficheros. Podemos entonces gestionar los datos de cada tabla separadamente al
nivel del sistema operativo, reemplazando su contenido si es necesario.
Ya que la tabla externa puede se consultada, podemos usar la tabla externa como origen de datos para un
comando INSERT AS SELECT. Durante esta operacin, Oracle intentar cargar los ficheros externos en
paralelo, potencialmente mejorando el rendimiento. Para mejorar el rendimiento de las operaciones INSERT
AS SELECT, deberamos usar la etiqueta APPEND para forzar inserciones a nivel de bloque. Cuando
especificamos el grado de paralelismo para las operaciones INSERT AS SELECT, Oracle inicia varios
dispositivos de acceso ORACLE_LOADER para procesar los datos en paralelo. Para mejorar el funcionamiento
de la carga, hay que evitar usar campos de longitud variable, campos delimitados, conversin de juego de
caracteres, NULLIF, DEFAULTIF, y operaciones de conversin de tipos de datos. Desactivando la generacin
del fichero "malo" (con NOBADFILE) eliminamos el coste asociado con la creacin del fichero y el
mantenimiento el contexto de filas original.
Durante la INSERT AS SELECT podemos aplicar funciones sobre los datos que se procesan. Podemos aplicar
estas funciones en la sintaxis del comando INSERT AS SELECT o en la definicin de la tabla externa. Esto
ofrece importantes beneficios a las tablas externas (podemos centralizar la representacin y requerimientos de
proceso de nuestros datos, creando rutinas de traslacin dentro de la definicin de nuestras tablas).
Durante las consultas, las tablas externas permiten seleccionar conjuntos de datos especficos (mediante la
clusula LOAD WHEN). Si tenemos varios orgenes de datos para cargas de datos de repositorio, podemos
elegir qu datos estarn disponibles an mientras los datos estn fuera de la base de datos. Podemos usar esta
caracterstica para mantener aplicaciones disponibles durante cargas de datos. Estas cargas pueden ocurrir en
paralelo si los ficheros externos tiene un formato de fichero FIXED.
La caracterstica de lmites de acceso tambin permite forzar reglas de seguridad complejas concernientes al
acceso de datos. Por ejemplo, podemos tomar datos sensibles desde fuera de la base de datos, en un
directorio seguro. Usuarios con acceso READ al directorio deberan ser capaces de usar la tabla externa y
combinarla con otras tablas; usuarios sin este acceso deberan estar limitados para insertar datos dentro de las
tablas pblicamente accesibles. Datos altamente seguros, o datos dinmicos poco accedidos, no tienen que ser
insertados en la base de datos hasta que sea necesario.
Si usamos tablas externas en nuestra arquitectura de base de datos, debemos asegurarnos de planificar copias
de respaldo y recuperacin para estos ficheros al igual que para el resto de la base de datos. Si los ficheros
externos cambian ms rpidamente que los ficheros de base de datos, podemos necesitar recuperarlos ms
frecuentemente para tomar todas las ventajas de las capacidades de recuperacin de Oracle.
12. Consultas flashback
Como parte de su modelo consistente de lectura, Oracle muestra datos que han sido confirmados en la base
de datos. Desde Oracle9i, podemos consultar datos previos a una transaccin que ha sido confirmada. Si
accidentalmente confirmamos una actualizacin podemos usar esta capacidad (llamada consultas flashback)
para ver los datos en el estado previo a la confirmacin. Podemos usar los resultados de la consulta flashback
para restaurar los datos. Para soportar consultas flashback nuestra base de datos debera usar deshacer
administrado por el sistema, una funcionalidad introducida en Oracle9i para automticamente administrar
segmentos de rollback. El DBA debe crear una tablespace de deshacer, habilitar Automatic Undo
Management, y establecer una ventana de tiempo de retencin de deshacer. Las consultas flashback pueden
ejecutarse a travs de bases de datos remotas.
Oracle intentar mantener cada informacin de deshacer en el tablespace de deshacer para soportar consultas
flashback durante el periodo de retencin de los datos. El tiempo de retencin asignado y la cantidad de
espacio disponible en el tablespace de deshacer pueden impactar significativamente nuestra habilidad para
ejecutar consultas flashback.

Oracle /252
Nota. Oracle usa deshacer (undo) para dar marcha atrs a transacciones y soportar consultas
flashback. Oracle usa rehacer (redo), mediante ficheros de log de rehacer en lnea, para aplicar
transacciones durante recuperaciones de base de datos.
Las consultas flashback son herramientas muy importantes mediante los esfuerzos de recuperaciones
parciales. En general, no deberamos confiar en consultas flashback como parte del diseo de nuestras
aplicacin debido a su dependencia de elementos del sistema fuera del control de los programadores de la
aplicacin (como el nmero de transacciones durante un perodo de tiempo y el tamao de tablespace de
deshacer). Ms bien deberamos tratarlas como una opcin durante los periodos de pruebas, soporte y
recuperacin de datos. Por ejemplo, podramos usarlas para crear copias de tablas y puntos en el tiempo que
sern usados para reconstruir los datos cambiados.
Nota. Para usar algunas caractersticas de las consultas flashback, debemos tener el permiso
EXECUTE sobre el paquete DBMS_FLASHBACK. La mayora de usuarios no necesitarn permisos sobre
este paquete.
12.1. Ejemplo de consulta flashback basada en el tiempo.
La tabla PEDIDO_LIBRO tiene seis registros, tal como se muestra en el siguiente listado:
COLUMN Titulo FORMAT A30
SELECT * FROM PEDIDO_LIBRO;
TITULO EDITOR CATEGORIA
-------------------------- -------------------- ----------------
Joe descalzo Mariner Adulto-fic
Evangelio Picador Adulto-fic
Algo tan fuerte Pandoras Adulto-nf
La hija de Galileo Penguin Adulto-nf
Longitud Penguin Adulto-nf
Una vez quitado Sancturay Pub Adulto-nf
Llega un envo, y los registros antiguos de PEDIDO_LIBRO son suprimidos y se confirma el borrado.
Lamentablemente, no todos los libros estaban en el envo, y por tanto la supresin fue inadecuada:
DELETE FROM PEDIDO_LIBRO;
COMMIT;
Cmo podemos reconstruir los registros de libros no recibidos de la tabla PEDIDO_LIBRO? Podemos realizar
una recuperacin de la base de datos usando Data Pump Import para restaurar la tabla, o podemos usar una
recuperacin fsica de la base de datos para recuperarla a un punto anterior a la supresin. Sin embargo, con
consultas flashback podemos evitar la necesidad de realizar operaciones de recuperacin.
Primero debemos consultar los datos antiguos a la base de datos. Desde Oracle9i Release 2, podemos usar las
clusulas AS OF TIMESTAMP y AS OF SCN del comando SELECT para especificar cmo de lejos debera llegar
Oracle para recuperar datos.
Nota. En la liberacin 9.0.1 de Oracle9, esta sintaxis no est soportada; es necesario ejecutar
procedimientos del paquete DBMS_FLASHBACK y escribir bucles PL/SQL para realizar cualquier
transaccin basada en los datos.
SELECT COUNT(*) FROM PEDIDO_LIBRO;
COUNT(*)
-------------
0
SELECT COUNT(*) FROM PEDIDO_LIBRO
AS OF TIMESTAMP (SYSDATE 5/1440);
COUNT(*)
-------------
6
Cuando ejecutamos una consulta flashback, slo es cambiado el estado de los datos. Se usa el tiempo actual
del sistema (el valor de SYSDATE), y el diccionario de datos actual. Si la estructura de la tabla ha cambiado, la
consulta fallar.

Oracle /253
12.2. Guardando los datos.
Como se muestra en el ejemplo de PEDIDO_LIBRO, las consultas flashback son sencillas de implementar, a
condicin de que el administrador de deshacer de la base de datos est correctamente configurado y la
informacin deshacer est disponible. Pero cmo trabajar con los datos flashback?
El mtodo ms simple consiste en guardar los datos en otra tabla. Hay 1440 minutos en un da, as "SYSDATE
5/1440" dirigir a la base de datos al estado que tena hace 5 minutos. Ntese entonces que la consulta puede
no retornar registros si han pasado ms de 5 minutos desde la confirmacin.
CREATE TABLE PEDIDO_LIBRO_OLD
AS SELECT * FROM PEDIDO_LIBRO AS OF TIMESTAMP (SYSDATE 5/1440);
/
SELECT COUNT(*) FROM PEDIDO_LIBRO_OLD;
COUNT(*)
-------------
6
Podemos verificar que los datos recuperados son correctos consultando la tabla PEDIDO_LIBRO_OLD. Y
entonces podemos trabajar con estos datos para restaurar los datos perdidos, realizar actualizaciones
selectivas, insertar slo registros incorrectamente borrados, o cualquier otra operacin necesaria.
La nueva tabla, PEDIDO_LIBRO_OLD, no tiene ndices ni restricciones de integridad referencial. Si necesitamos
combinarla con otras tablas, podemos necesitar crear copias flashback de varias tablas para mantener la
integridad referencial de los datos. Tambin podemos notar que cada consulta es ejecutada en diferentes
momentos del tiempo (y los tiempos relativos usados en la clusula AS OF TIMESTAMP, por lo tanto, pueden
conducir a confusin o resultados incoherentes).
Podemos trabajar directamente con datos antiguos (sin embargo, confiamos en que los datos viejos estn
disponibles para nuestra transaccin). Es generalmente seguro crear una tabla y almacenar los datos viejos
temporalmente mientras trabajamos con ellos.
12.2.1. Limitaciones en las consultas flashback basadas en el tiempo.
El ejemplo precedente muestra cmo usar el tiempo del sistema durante nuestras consultas flashback. Como
se indic, este mtodo proporciona un soporte limitados para consultas flashback multi-tablas. Para realizar
consultas flashback complejas correctamente deberamos usar el nmero de cambio del sistema (SCN).
Oracle usa internamente el SCN, no el tiempo del sistema, para generar datos flashback, aunque
especifiquemos la clusula AS OF TIMESTAMP. El tiempo del sistema se mapea a los valores SCN cada cinco
minutos; la tabla SYS.SMON_SCN_TIME registra las ltimas 1440 coincidencias de SCN al tiempo del sistema.
Cuando volvemos a un punto del tiempo, Oracle usa los 5 minutos ms recientes que preceden al tiempo
consultado. Si SMON_SCN_TIME tiene un registro para las 1:00 P.M. y otro para las 1:05 P.M., una consulta
flashback para las 1:04 P.M. retornar los datos desde las 1:00 P.M.
SMON_SCN_TIME slo mantiene las ms recientes 1440 entradas, as que las consultas flashback que van ms
all de los ltimos cinco das deben usar un acercamiento basado en SCN. Si cerramos nuestra base de datos
de vez en cuando (por ejemplo, para hacer respaldos fuera de lnea), los 1440 registros de SMON_SCN_TIME
incluirn ms de cinco das.
Para ver las entradas ms recientes de SYS.SMON_SCN_TIME, podemos ejecutar la siguiente consulta como
SYS, conectados como SYSDBA:
SELECT TO_CHAR(TIME_DP, 'DD-MON-YYYY HH24:MI:SS')
FROM SYS.SMON_SCN_TIME
ORDER BY TIME_DP DESC ;
12.3. Ejemplo de consulta flashback basada en SCN.
Cuando realizamos consultas flashback basadas en el tiempo, realmente estamos haciendo consultas basadas
en SCN; simplemente confiamos en Oracle para encontrar un SCN cerca del tiempo especificado. Si
conocemos el SCN exacto podemos realizar una consulta flashback con una gran precisin.
Para comenzar una consulta flashback basada en SCN, primero debemos conocer el SCN de nuestra
transaccin. Para obtener el ltimo nmero de cambio debemos aplicar un COMMIT y entonces usar la
clusula AS OF SCN del comando SELECT. Podemos encontrar el SCN actual ejecutando la funcin
GET_SYSTEM_CHANGE_NUMBER del paquete DBMS_FLASHBACK antes de la ejecucin de nuestra transaccin.

Oracle /254
Nota. Antes de ejecutar el siguiente ejemplo, tenemos que tener concedido el permiso EXECUTE
sobre el paquete DBMS_FLASHBACK.
El siguiente ejemplo muestra este proceso como parte de una transaccin a travs de la tabla
PEDIDO_LIBRO_OLD creada y poblada previamente. Primero, el SCN actual se asigna a una variable llamada
scn_flash y se muestra mediante el comando PRINT de SQL*Plus:
COMMIT;
VARIABLE scn_flash NUMBER;
EXECUTE :scn_flash :=DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;
PRINT scn_flash
scn_flash
-------------
529732
A continuacin, se realiza un borrado y el resultado es confirmado:
DELETE FROM PEDIDO_LIBRO_OLD;
COMMIT;
Ahora podemos consultar los datos flashback. Aunque conocemos el valor SCN, podemos continuar usando
la variable scn_flash dentro de la misma sesin:
SELECT COUNT(*) FROM PEDIDO_LIBRO_OLD
AS OF SCN (:scn_flash);
COUNT(*)
-------------
6
Podemos usar los datos flashback de PEDIDO_LIBRO_OLD, accedidos por la clusula AS OF SCN, para poblarla
con los valores antiguos:
INSERT INTO PEDIDO_LIBRO_OLD
SELECT * FROM PEDIDO_LIBRO_OLD AS OF SCN (:scn_flash);
COMMIT;

Nota. Las operaciones DDL que modifican la estructura de la tabla invalidan los datos de deshacer
para la tabla, y las capacidades flashback se limitan a antes de que el DDL fue ejecutado.
12.4. Qu ocurre si falla una consulta flashback?
Si no hay suficiente espacio en el tablespace de deshacer para mantener todos los datos necesarios para la
consulta de flashback, la consulta fallar. Aunque el DBA cree un tablespace de deshacer grande, es posible
que una serie de transacciones largas usen todo el espacio disponible. Una porcin de cada consulta fallida
ser escrita en el registro de avisos de la base de datos.
Desde la perspectiva de un usuario que intenta recuperar datos antiguos, deberamos intentar recuperar los
datos que sean tan correctos y oportunos como sea posible. A menudo podemos tener que ejecutar varias
consultas flashback para determinar como de lejos podemos consultar sucesivamente los datos, y luego
guardar los datos ms viejos a los que podemos tener acceso y los datos ms cercanos al punto en el cual el
problema ocurri. Una vez que los datos ms viejos se han ido del tablespace de deshacer, no podemos usar
consultas flashback para recuperarlo.
Si no es posible recuperar datos que son bastante viejos para nuestras necesidades, tendremos que realizar
algn tipo de la recuperacin de la base de datos (recuperando la base de datos entera o recuperando tablas y
tablespaces especficos mediante los mtodos tradicionales de un DBA). Si este problema es habitual,
deberamos aumentar el tiempo de retencin de deshacer, aumentar el espacio asignado para el tablespace
deshacer, y la aplicacin debera examinarse para determinar por qu se repiten transacciones cuestionables.
12.5. Qu SCN est asociado con cada registro?
Desde Oracle Database 10g, podemos ver el ms reciente SCN asociado con cada registro de la bases de
datos.
Comenzaremos repoblando nuestra tabla PEDIDO_LIBRO con los datos que fueron restaurados en la tabla
PEDIDO_LIBRO_OLD:
DELETE FROM PEDIDO_LIBRO;
INSERT INTO PEDIDO_LIBRO
SELECT * FROM PEDIDO_LIBRO_OLD;

Oracle /255
COMMIT;
Ahora usaremos la pseudo-columna ORA_ROWSCN introducida en Oracle Database 10g para ver el SCN
asociado con cada registro:
SELECT Titulo, ORA_ROWSCN FROM PEDIDO_LIBRO;
TITULO ORA_ROWSCN
-------------------------- ------------------
Joe descalzo 553531
Evangelio 553531
Algo tan fuerte 553531
La hija de Galileo 553531
Longitud 553531
Una vez quitado 553531
Todos los registros son parte de la misma transaccin y por tanto tienen el mismo SCN. Ahora, despus de
que se han realizado otras transacciones en la base de datos, insertaremos un nuevo registro:
INSERT INTO PEDIDO_LIBRO
VALUES ('Innumeracy','Vintage Books','Adulto-nf');
COMMIT;
Ahora que ha sido confirmado un nuevo cambio, podemos usar el SCN asociado con l:
SELECT Titulo, ORA_ROWSCN FROM PEDIDO_LIBRO;
TITULO ORA_ROWSCN
-------------------------- ------------------
Joe descalzo 553531
Evangelio 553531
Algo tan fuerte 553531
La hija de Galileo 553531
Longitud 553531
Una vez quitado 553531
Innumeracy 553853
A qu hora se hace el mapeado SCN? Podemos usar la funcin de SCN_TO_TIMESTAMP para mostrar la
fecha en la cual se hizo el cambio:
SELECT SCN_TO_TIMESTAMP(555853) FROM DUAL;
SCN_TO_TIMESTAMP(555853)
-------------------------------------------
20-FEB-2011 03.11.28.000000000 PM
Podemos integrar estas dos consultas par ver los tiempos de la ltima transaccin para cada registro:
SELECT Titulo, SCN_TO_TIMESTAMP(ORA_ROWSCN)
FROM PEDIDO_LIBRO;
12.6. Consultas de versin flashback.
Desde Oracle Database 10g, podemos mostrar varias versiones de las filas que existen durante intervalos
especificados. Como con los ejemplos mostrados previamente, los cambios son dependientes de SCN, as que
slo estos que son confirmados se mostrarn.
Nota. Las consultas de versin flashback requieren que el DBA tenga asignado un valor distinto de
cero para el parmetro de inicializacin UNDO_RETENTION. Si el valor de UNDO_RETENTION es
demasiado pequeo obtendremos un error ORA-30052.
Para los siguientes ejemplos, eliminaremos los registros antiguos de la tabla PEDIDO_LIBRO:
DELETE FROM PEDIDO_LIBRO;
Ahora repoblaremos la tabla PEDIDO_LIBRO:
SELECT SYSTIMESTAMP FROM DUAL;
INSERT INTO PEDIDO_LIBRO
SELECT * FROM PEDIDO_LIBRO_OLD;
SELECT SYSTIMESTAMP FROM DUAL;
Ahora esperamos unos pocos minutos y actualizamos todos los registros:
SELECT SYSTIMESTAMP FROM DUAL;
UPDATE PEDIDO_LIBRO SET Categoria = 'Adulto-f';

Oracle /256
SELECT SYSTIMESTAMP FROM DUAL;
Para ejecutar una consulta de versin flashback se usa la clusula VERSIONS BETWEEN en el comando SELECT.
Podemos especificar la fecha o el SCN. En este ejemplo, el formato para la clusula TIMESTAMP est basado
en el formato estndar de Oracle.
SELECT *
FROM PEDIDO_LIBRO
VERSIONS BETWEEN TIMESTAMP
TO_TIMESTAMP('20-FEB-04 16.00.20','DD-MON-YY HH24.MI.SS')
AND
TO_TIMESTAMP('20-FEB-04 16.06.20','DD-MON-YY HH24.MI.SS') ;
Cuando ejecutemos esta consulta, Oracle retornar una fila por cada versin de cada registro entre las fechas
indicadas. Para las filas retornadas, podemos consultar pseudo-columnas adicionales:
Pseudo-columna Descripcin
VERSIONS_STARTSCN El SCN cuando los primeros datos tenan los valores reflejados. Si NULL,
entonces la fila fue creada antes del lmite inferior de la consulta.
VERSIONS_STARTTIME La fecha cuando los primeros datos tenan los valores reflejados. Si NULL,
entonces la fila fue creada antes del lmite inferior de la consulta.
VERSIONS_ENDSCN El SCN cuando la versin de la fila expira. Si NULL, entonces la fila es actual o ha
sido borrada.
VERSIONS_ENDTIME La fecha cuando la versin del la fila expira. Si NULL, entonces la fila es actual o
ha sido borrada.
VERSIONS_XID El identificador de la transaccin que cre la versin de la fila.
VERSIONS_OPERATION La operacin que realiz la transaccin (I para INSERT, U para UPDATE, D para
DELETE).
El siguiente ejemplo muestra el uso de consultas de versin flashback. Los valores de Versions_StartSCN son
NULL para las filas actuales; las filas antiguas han sido actualizadas. La fecha ser diferente segn la plataforma.
SELECT Titulo, VERSIONS_STARTSCN, VERSIONS_OPERATION
FROM PEDIDO_LIBRO
VERSIONS BETWEEN TIMESTAMP
TO_TIMESTAMP('20FEB-04 16.00.20','DD-MON-YY HH24.MI.SS')
AND
TO_TIMESTAMP('20FEB-04 16.06.20','DD-MON-YY HH24.MI.SS') ;
TITULO ORA_ROWSCN V
-------------------------- ------------------ ----
Una vez quitado 568127 U
Longitud 568127 U
La hija de Galileo 568127 U
Algo tan fuerte 568127 U
Evangelio 568127 U
Joe descalzo 568127 U
Joe descalzo
Evangelio
Algo tan fuerte
La hija de Galileo
Longitud
Una vez quitado
La clusula VERSIONS BETWEEN puede usarse en subconsultas de comandos DML y DDL.
Desde Oracle Database 10g, podemos usar la vista FLASHBACK_TRANSACTION_QUERY del diccionario de
datos para seguir los cambios hechos por cada transaccin. Para una transaccin dada,
FLASHBACK_TRANSACTION_QUERY muestra el nombre del usuario que las ejecut, la operacin realizada, la
tabla sobre la que se aplic la transaccin, el SCN y fechas iniciales y finales, y el SQL necesario para deshacer
la transaccin.
12.7. Planificacin de las consultas flashback.
Par los DBA's, las consultas flashback pueden servir para realizar operaciones de recuperaciones parciales
rpidamente.

Oracle /257
Si los datos pueden ser reconstruidos mediante consultas flashback, y si el volumen de datos no es aplastante,
podemos ser capaces de guardar los resultados de varias consultas flashback en tablas independientes.
Podemos entonces comparar los datos en las tablas mediante las opciones SQL mostradas previamente
(subconsultas correlacionadas, EXISTS, NOT EXISTS, MINUS, y dems). Si no podemos evitar la necesidad de
una operacin de recuperacin, deberamos sealar el perodo de tiempo para ser usado en una operacin de
recuperacin basada en el tiempo.
Como se ver en el siguiente captulo, Oracle Database 11g introduce opciones adicionales (los comandos
FLASHBACK DATABASE y FLASHBACK TABLE).
Para los programadores y administradores de aplicaciones, las consultas flashback proporcionan una
herramienta importante para reconstruir datos. Las consultas flashback pueden ser particularmente crticas
durante operaciones de pruebas y soporte.
13. Tablas y bases de datos flashback
Desde Oracle Database 10g, podemos usar los comandos FLASHBACK TABLE y FLASHBACK DATABASE para
simplificar nuestros esfuerzos de recuperacin de datos. El comando FLASHBACK TABLE automatiza el
proceso de restaurar una tabla entera a un estado previo. El comando FLASHBACK DATABASE recupera una
base de datos entera, y necesita modificaciones sobre el estado y registro de la base de datos.
13.1. El comando FLASHBACK TABLE.
El comando FLASHBACK TABLE recupera un estado anterior de una tabla en el evento de error humano o de
aplicacin. Oracle no puede restaurar una tabla a un estado previo durante operaciones DDL que cambien la
estructura de la tabla.
Nota. La base de datos debera usar Automatic Undo Management (AUM) para trabajar con
FLASHBACK TABLE. La habilidad de recuperar datos viejos est limitada a la cantidad de datos de
deshacer retenidos en el tablespace de deshacer y el parmetro de inicializacin UNDO_RETENTION.
No se puede dar marcha atrs a un comando FLASHBACK TABLE. Sin embargo, podemos aplicar otro
comando FLASHBACK TABLE y especificar un tiempo anterior al actual.
Nota. Registre el SCN actual antes de la ejecucin de un comando FLASHBACK TABLE.
13.1.1. Permisos requeridos.
Debemos tener el permiso de objeto FLASHBACK sobre la tabla o el permiso de sistema FLASHBACK ANY
TABLE. Debemos tambin tener los permisos de objeto SELECT, INSERT, DELETE y ALTER sobre la tabla.
Debemos habilitar el movimiento de fila para todas las tablas de la lista flashback. Para dar marcha atrs una
tabla antes de una operacin DROP sobre tabla, slo necesitamos tener los permisos necesarios para borrar la
tabla.
13.1.2. Recuperacin de tablas borradas.
Consideremos la tabla AUTOR:
DESCRIBE AUTOR
Name Null? Type
------------------ -------- ----------------------------
NombreAutor NOT NULL VARCHAR2(50)
Comentarios VARCHAR2(100)
Ahora, asumamos que la tabla es borrada accidentalmente. Esto ocurre normalmente cuando un usuario con
permisos intenta borrar una tabla en el entorno de desarrollo/pruebas pero pensando en la base de datos de
produccin cuando ejecuta el comando:
DROP TABLE AUTOR CASCADE CONSTRAINTS;
Cmo podemos recuperar la tabla? Desde Oracle Database 10g, una tabla borrada no desaparece
completamente. Sus bloques todava se mantienen en el tablespace, y eso todava perjudica la cuota de
espacio. Podemos ver los objetos borrados consultando la vista RECYCLEBIN del diccionario de datos. Ntese
que el formato de la columna Object_Name puede diferir entre versiones.
SELECT Object_Name, Original_Name, Operation, Type, Ts_Name, CreateTime FROM RECYCLEBIN;
OBJECT_NAME ORIGINAL_NAME OPERATION TYPE TS_NAME CREATETIME
--------------------------- ---------------------- --------------- --------- ------------- -------------------------
RB$$48448$TABLE$0 AUTOR DROP TABLE USERS 2004-02-23:16:10:58

Oracle /258
RB$$48449$INDEX$0 SYS_C004828 DROP INDEX USERS 2004-02-23:16:10:58
SELECT DropTime, DropScn, Partition_Name, Can_Undrop, Can_Purge, Related FROM RECYCLEBIN;
DROPTIME DROPSCN PARTITION_NAME CAN CAN RELATED
------------------------- -------------- ------------------------ ------- ------ -------------
2004-02-25:14:30:23 720519 YES YES 48448
2004-02-25:14:30:23 720516 NO YES 48448
SELECT Base_Object, Purge_Object, Space FROM RECYCLEBIN;
BASE_OBJECT PURGE_OBJECT SPACE
------------------ ---------------------- ----------
48448 48448 8
48448 48449 8
RECYCLEBIN es un sinnimo pblico de la vista USER_RECYCLEBIN del diccionario de datos, que muestra las
entradas del reciclador para el usuario actual. Los DBA's pueden ver todos los objetos borrados mediante la
vista DBA_RECYCLEBIN del diccionario de datos.
Como se muestra en el listado precedente, Oracle ha borrado la tabla AUTOR y su ndice de clave primaria
asociado. Aunque hayan sido borrados todava estn disponibles para recuperacin. Ntese que el listado
muestra el SCN para el comando DROP usado para borrar el objeto base.
Podemos usar el comando FLASHBACK TABLE TO BEFORE DROP para recuperar la tabla desde el reciclador:
FLASHBACK TABLE AUTOR TO BEFORE DROP;
La tabla es restaurada, junto con sus filas, ndices y estadsticas. La sintaxis completa de este comando es la
siguiente:

Qu ocurre si borramos la tabla AUTOR, la recreamos y entonces la borramos otra vez? El reciclador
contendr ambas tablas. Cada entrada en el reciclador se identificar mediante su SCN y la fecha de borrado.
Nota. El comando FLASHBACK TABLE TO BEFORE DROP no recupera restricciones referenciales.
Para purgar entradas antiguas del reciclador se usa el comando PURGE. Podemos purgar todos nuestros
objetos borrados, todos los objetos borrados en la base de datos (si somos un DBA), todos los objetos de un
tablespace especfico, o todos los objetos de un usuario determinado en un tablespace especfico.
La sintaxis completa del comando PURGE se muestra a continuacin:

Podemos usar la clusula RENAME del comando FLASHBACK TABLE para renombrar la tabla cuando se
recupera.

Oracle /259
13.1.3. Cmo recuperar a una fecha o SCN.
Como se vio en el captulo previo, podemos guardar los resultados de una consulta flashback a otra tabla
mientras la tabla principal permanece inalterada. Tambin podemos actualizar las filas de una tabla segn los
resultados de una consulta flashback. Podemos usar el comando FLASHBACK TABLE para transformar una
tabla a una versin anterior (borrando los cambios hechos desde el punto de retroceso especificado).
Durante la operacin de recuperacin de tabla, Oracle adquiere bloqueos DML exclusivos sobre todas las
tablas especificadas. El comando es ejecutado como una nica transaccin a travs de todas las tablas; si
alguna de ellas falla, todo el comando falla. Podemos entonces recuperar una tabla a un SCN o tiempo
especficos.
Nota. FLASHBACK TABLE TO SCN o TO TIMESTAMP no preservan los RowID's.
El siguiente comando de actualizacin intenta actualizar el comentario para el autor Clement Hurd. Sin
embargo, la clusula WHERE no es especificada; todos los registros sern actualizados.
UPDATE AUTOR
SET COMMENTS = 'Ilustrador de libros para nios';
COMMIT;
En este caso, sabemos que la mayora de la tabla tiene datos incorrectos, y sabemos que la transaccin fue
ejecutada incorrectamente. Para recuperar los datos correctos, podemos dar marcha atrs a la base de datos y
entonces aplicar cualquier nuevo comando necesario para actualizar los datos.
Primero, nos aseguraremos de conocer el SCN actual para retornar a este punto:
COMMIT;
VARIABLE scn_flash NUMBER;
EXECUTE :scn_flash :=DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;
PRINT scn_flash
SCN_FLASH
------------------
720880
Ahora, recuperaremos la tabla al tiempo anterior a la actualizacin. Primero, habilitaremos el movimiento de
filas para la tabla:
ALTER TABLE AUTOR ENABLE ROW MOVEMENT;
Entonces podemos recuperar la tabla:
FLASHBACK TABLE AUTOR TO TIMESTAMP (SYSTIMESTAMP 5/1440);
Podemos usar la clusula TO SCN si queremos especificar un SCN en vez de una fecha.
13.1.4. ndices y estadsticas.
Cuando una tabla es recuperada, sus estadsticas no son recuperadas. Los ndices que existen sobre la tabla
son revertidos y reflejan el estado de la tabla al punto de recuperacin. Los ndices borrados desde el punto
de recuperacin no son restaurados. Los ndices creados desde el punto de recuperacin continuarn
existiendo y sern actualizados para reflejar los viejos datos.
13.2. El comando FLASHBACK DATABASE.
El comando FLASHBACK DATABASE retorna la base de datos a un tiempo o SCN pasado, proporcionando una
alternativa rpida para realizar recuperaciones incompletas de la base de datos. Despus de una operacin de
retroceso de base de datos, para tener acceso de escritura a la base de datos recuperada debemos volver a
abrirla con un comando ALTER DATABASE OPEN RESETLOGS. Debemos tener el permiso de sistema SYSDBA
para usar el comando FLASHBACK DATABASE.
Nota. La base de datos debe haber sido puesta en modo flashback con el comando ALTER
DATABASE FLASHBACK ON. La base de datos debe ser montada en modo exclusivo pero no estar
abierta cuando este comando es ejecutado.
La sintaxis para el comando FLASHBACK DATABASE es la siguiente:

Oracle /260
Podemos usar tanto la clusula TO SCN como TO TIMESTAMP para asignar el punto al cual queremos retornar
toda la base de datos. Con la clusula TO BEFORE podemos regresar a un punto crtico (como una transaccin
que produce una alteracin no intencionada de varias tablas). Se usa la pseudo-columna ORA_ROWSCN para
ver el SCN de las transacciones que ms recientemente modificaron las filas.
Para usar FLASHBACK DATABASE, debemos primer modificar la base de datos mientras est montada pero no
abierta. Si no ocurre esto, necesitaremos cerrar nuestra base de datos y habilitar flashback durante el proceso
de inicio:
STARTUP MOUNT EXCLUSIVE;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE FLASHBACK ON;
ALTER DATABASE OPEN;

Nota. Debemos tener habilitado recuperacin de medios mediante el comando ALTER DATABASE
ARCHIVELOG antes de ejecutar el comando ALTER DATABASE FLASHBACK ON.

Dos parmetros de inicializacin controlan cmo los datos flashback son retenidos en la base de datos. El
parmetro DB_FLASHBACK_RETENTION_TARGET asigna el lmite superior (en minutos) para determinar qu
lejos en el tiempo podemos recuperar la base de datos. El parmetro DB_RECOVERY_FILE_DEST asigna el
tamao del rea de recuperacin. Ntese que el comando FLASHBACK TABLE usa el tablespace de deshacer,
mientras que el comando FLASHBACK DATABASE confa en registros de recuperacin almacenados en un rea
de recuperacin.
Podemos determinar cun lejos podemos recuperar la base de datos consultando la vista
V$FLASHBACK_DATABASE_LOG. La cantidad de datos flashback retenidos en la base de datos es controlada
por el parmetro de inicializacin y el tamao del rea de recuperacin. El siguiente listado muestra las
columnas disponibles en V$FLASHBACK_DATABASE_LOG y contenidos de ejemplo:
DESC V$FLASHBACK_DATABASE_LOG
Name Null? Type
----------------------------------------- -------- ------------
OLDEST_FLASHBACK_SCN NUMBER
OLDEST_FLASHBACK_TIME DATE
RETENTION_TARGET NUMBER
FLASHBACK_SIZE NUMBER
ESTIMATED_FLASHBACK_SIZE NUMBER
SELECT * FROM V$FLASHBACK_DATABASE_LOG;
OLDEST_FL OLDEST_FL RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FL
--------------- --------------- --------------------------- ----------------------- ---------------------
722689 25-FEB-04 1440 8192000 0
Podemos verificar el estado de recuperacin de la base de datos consultando V$DATABASE; la columna
Flashback_On tendr el valor YES si la recuperacin est habilitada para la base de datos.
SELECT CURRENT_SCN, FLASHBACK_ON FROM V$DATABASE;
CURRENT_SCN FLASHBACK_ON
--------------------- ----------------------
723649 YES
Con la base de datos abierta durante ms de una hora, verificamos que los datos flashback estn disponibles y
entonces los recuperamos (perderemos todas las transacciones que ocurrieron durante este tiempo):
SHUTDOWN;
STARTUP MOUNT EXCLUSIVE;
FLASHBACK DATABASE TO TIMESTAMP SYSDATE-1/24;
Ntese que el comando FLASHBACK DATABASE requiere que la base de datos est montada en modo

Oracle /261
exclusivo.
Cuando ejecutamos el comando FLASHBACK DATABASE, Oracle comprueba que todo el archivado requerido y
los ficheros de registro de deshacer en lnea estn disponibles. Si los registros estn disponibles, los ficheros
de datos en lnea se revierten al tiempo o SCN especificado.
Si no hay suficientes datos en lnea en los registros de archivado y reas de recuperacin, necesitaremos usar
mtodos tradicionales de recuperacin de base de datos para recuperar los datos. Por ejemplo, podemos
necesitar usar un mtodo de recuperacin de ficheros del sistema despus de la marcha atrs de los datos.
Una vez que la recuperacin se ha completado, debemos abrir la base de datos usando la opcin RESETLOGS
para tener accesos de escritura sobre la base de datos:
ALTER DATABASE OPEN RESETLOGS;
Para desactivar la opcin de flashback de la base de datos hay que ejecutar el comando ALTER DATABASE
FLASHBACK OFF cuando la base de datos est montada pero no abierta:
STARTUP MOUNT EXCLUSIVE;
ALTER DATABASE FLASHBACK OFF;
ALTER DATABASE OPEN;

Oracle /262
V. SOPORTE DE OBJETOS Y XML
Esta leccin trata de las caractersticas y funcionalidades XML de Oracle Database en su versin 9i. Estas
caractersticas no son slo el almacenamiento de este tipo de datos como cadenas de caracteres sino el
modelado de estos tipos, su clasificacin e indexado en el sistema de modelado de datos de Oracle,
permitiendo peticiones y manipulacin avanzada de los mismos.
La naturaleza de estructura no plana de los documentos XML obliga para su modelado hacer uso de las
caractersticas objeto-relacionales de la base de datos. Por eso, la primera parte de esta leccin habla del
modelo objeto-relacional de Oracle. La segunda parte se centra en los documentos XML en la base de datos
Oracle.
1. Modelo objeto-relacional de Oracle
Las bases de datos relacionales son una tecnologa muy madura y eficiente, pero su principal defecto es la
planaridad de su modelo. Esto ha dificultado el modelado de los tipos de datos basados en objetos, obligando
a establecer capas de transformacin del modelo orientado a objetos de la aplicacin con el modelo relacional
de la base de datos. Esto exiga una doble labor de diseo en ambos planos y el uso de cdigo envolvente
(wrapper) entre los dos modelos.
Las bases de datos orientadas a objetos aparecen para cubrir esta problemtica. Al ser el modelado de los
elementos de este software tambin orientado a objetos, slo es necesario un nico diseo y el wrapper
desaparece o se simplifica enormemente. Sin embargo, el nuevo modelo orientado a objetos es mucho ms
ineficiente y lento.
La ltima opcin en aparecer fue la objeto-relacional. Este modelo combina las ventajas de los dos anteriores:
la base de datos es relacional (por lo que conserva su rapidez y eficiencia), pero permite hacer uso de nuevos
elementos que modelan los objetos a esta base de datos relacional, con lo que el analista y diseador ve un
modelo orientado a objetos. Oracle Database pertenece a este ltimo tipo desde la versin 8i.
Los objetos en Oracle 9i se denominan tipos abstractos de datos y poseen funcionalidades de herencia y
mtodos implementados en SQL o Java. La problemtica de la planaridad se resuelve con las tablas anidadas
y los arrays variables (VARRAY). Las relaciones entre objetos se establecen mediante el tipo de referencia REF.
El almacenamiento de conjuntos de datos no estructurado se realiza con los tipos de objetos grandes. Y la
base de datos relacional se puede modelar como objetos mediante las vistas de objeto.
1.1. Tipos abstractos de datos (clases y objetos).
Oracle permite modelar los objetos en filas o columnas:
Un objeto modelado en filas es una tabla (una clase), en la cual cada fila es del tipo del objeto (una
instancia), y los atributos nativos del objeto son modelados como columnas.
Un objeto modelado en columnas es una fila dentro de una tabla (o instancia del tipo de objeto), y se
modela haciendo corresponder sus atributos con las columnas de la tabla o atributos del objeto
respectivamente.
En el ejemplo siguiente se define un objeto Compra, que se modelar con su atributo id seguido de los
atributos de un objeto persona: nombre y telefono, y de una referencia a la tabla anidada tabla_detalles. Adems
declara un mtodo getValor, cuyo cuerpo se definir posteriormente.
-- Se define el objeto Persona con la informacin del comprador
CREATE TYPE Persona AS OBJECT (
nombre VARCHAR2(30),
telefono VARCHAR2(20)
);
/
-- Se define el objeto LineaDetalle, con la informacin del producto comprado
CREATE TYPE LineaDetalle AS OBJECT (
producto VARCHAR2(30),
cantidad NUMBER,
precioUnitario NUMBER(12,2)
);
/
-- Se define un nuevo tipo de array (tabla anidada) de lneas de detalle de compra
CREATE TYPE Tabla_detalles AS TABLE OF LineaDetalle;

Oracle /263
/
-- Se define el objeto Compra, con un ID, un comprador y un conjunto de lneas de detalle de compra
CREATE TYPE Compra AS OBJECT (
id NUMBER,
comprador Persona,
detalles Tabla_detalles,
MEMBER FUNCTION getValor RETURN NUMBER
);
1.1.1. Modificacin de los atributos de un tipo de dato.
Una vez creado un tipo de dato podemos modificar su lista de atributos mediante el comando ALTER TYPE,
con la siguiente sintaxis:
ALTER TYPE nombre_del_tipo ADD ATTRIBUTE (nombre_del_atributo tipo_de_dato) CASCADE;
Por ejemplo, supongamos el tipo Telefono_TA y el tipo Telefono_Lista_TA:
CREATE OR REPLACE TYPE Telefono_TA AS OBJECT (
codigo CHAR(3),
numero CHAR(8)
) NOT FINAL;
/
CREATE OR REPLACE TYPE Telefono_Lista_TA AS TABLE OF Telefono_TA;
/
Si queremos aadir un nuevo atributo al tipo Telefono_TA, al usar el siguiente comando se producir un error:
CREATE OR REPLACE TYPE Telefono_TA AS OBJECT (
Pais CHAR(3),
codigo CHAR(3),
numero CHAR(8)
) NOT FINAL;
/
El error se debe a la dependencia del tipo Telefono_TA respecto al tipo Telefono_Lista_TA. Para aadir el nuevo
atributo debemos utilizar el siguiente comando:
ALTER TYPE Telefono_TA ADD ATTRIBUTE (pais CHAR(3)) CASCADE;
1.2. Seguridad para tipos de datos abstractos.
El ejemplo precedente asume que el mismo usuario es propietarios de los tipos de dato Persona, LineaDetalle y
Compra. Qu ocurrira si el propietario de Persona fuese diferente del propietario de Compra?
Por ejemplo, supongamos que la cuenta llamada Dora es propietaria del tipo de dato Persona, y el usuario de la
cuenta George intenta crear un tipo de dato Cliente_TA. George ejecuta el siguiente comando:
REM Mientras est conectado como George:
CREATE TYPE Cliente_TA AS OBJECT (
Identidad Persona,
Direccion VARCHAR2(100)
);
SiGeorge no es propietario del tipo abstracto Persona, Oracle responder a este comando CREATE TYPE con el
siguiente mensaje:
Warning: Tipo creado con errores de compilacin.
Los errores de compilacin son causados por problemas al crear el mtodo constructor (un mtodo especial
creado por Oracle para el tipo de dato). Oracle no puede resolver la referencia al tipo de dato Persona porque
George no es propietario de un tipo de dato con ese nombre. George podra intentar ejecutar otra vez el
comando CREATE TYPE para referenciar especialmente el tipo de dato Persona perteneciente a Dora:
CREATE OR REPLACE TYPE Cliente_TA AS OBJECT (
Identidad Dora.Persona,
Direccion VARCHAR2(100)
);
/
Warning: Tipo creado con errores de compilacin.
Para ver los errores asociados con la creacin del tipo de dato podemos usar el comando SHOW ERRORS:
SHOW ERRORS
Errores para el tipo CLIENTE:
LINE/COL ERROR

Oracle /264
------------ --------------------------------------------------------------------------
0/0 PL/SQL: Anlisis de la unidad de compilacin terminada
3/11 PLS-00201: Identificador 'DORA.PERSONA' debe ser declarado
George no ser capaz de crear el tipo de dato Cliente_TA a menos que Dora primero le conceda el permiso
EXECUTE sobre su tipo. Esto se muestra a continuacin:
REM Mientras est conectado como Dora:
GRANT EXECUTE ON Persona TO George;
Ahora George puede crear el tipo de datos basado en el tipo Persona, propiedad de Dora.
Usar tipos de datos de otros usuarios no es trivial. Por ejemplo, durante operaciones de insercin, debemos
especificar el propietario de cada tipo o usar un sinnimo. George puede crear una tabla basada sobre el tipo
Cliente_TA (el cual incluye el tipo de datos Dora.Persona), tal como se muestra a continuacin:
CREATE TABLE CLIENTES (
Cliente_Id NUMBER,
Cliente Cliente_TA) ;
Una insercin en la tabla CLIENTES debera tener el siguiente formato:
INSERT INTO CLIENTES VALUES
( 1, Cliente_TA( Persona('Juan Prez', '111111111'), 'Calle Ronda 25') );
Ya que George no es propietario del tipo Persona, este comando fallar. Durante la insercin, se usa el mtodo
constructor de Persona (y Dora es su propietario). Por lo tanto, debemos modificar el comando INSERT para
especificar que Dora es el propietario del tipo Persona. El siguiente ejemplo muestra el comando INSERT
correcto:
INSERT INTO CLIENTES VALUES
( 1, Cliente_TA( Dora.Persona('Juan Prez', '111111111'), 'Calle Ronda 25') );
George puede simplificar el SQL creando un sinnimo llamado Persona:
CREATE PUBLIC SYNONYM Persona FOR Dora.Persona;
Este sinnimo puede ser usado en consultas DML y DDL. Podemos usar un sinnimo para otros tipos de
datos de usuario durante consultas e inserciones. Por ejemplo, George inserta clientes ahora que existe el
sinnimo Persona:
INSERT INTO CLIENTES VALUES
( 1, Cliente_TA( Persona('Juan Prez', '111111111'), 'Calle Ronda 25') );

Nota. Cuando creamos un sinnimo, Oracle no verifica la validez del objeto para el cual es creado
el sinnimo. Cuando se usa CREATE SYNONYM X FOR Y, Oracle no verifica que Y sea un nombre de
objeto vlido o un tipo de objeto vlido. La validez de este objeto es slo verificada cuando el objeto
es accedido a travs del sinnimo.
En una implementacin solo relacional de Oracle podemos conceder el permiso EXECUTE sobre objetos
como procedimientos y paquetes. Dentro de la implementacin objeto-relacional de Oracle, el permiso
EXECUTE se extiende para cubrir tipos de datos abstractos. El permiso EXECUTE es apropiado porque los tipos
de datos abstractos pueden incluir mtodos (funciones PL/SQL y procedimientos que operan sobre el tipo
de datos). Si concedemos algn permiso para usar nuestro tipo de datos, estamos concediendo al usuario el
permiso de ejecutar los mtodos definidos dentro del tipo de datos. Aunque Dora an no definiera ningn
mtodo sobre el tipo Persona, Oracle crea automticamente un mtodo constructor para acceder a los datos.
Cualquier objeto (como Cliente_TA) que usa el tipo Persona usa su mtodo constructor asociado. Incluso si no
hemos creado ningn mtodo para nuestro tipo de dato abstracto, todava tiene procedimientos asociados
con l.
Podemos describir la tabla CLIENTES:
DESCRIBE CLIENTES;
Name Null? Type
------------------- -------- -----------------
CLIENTE_ID NUMBER
CLIENTE CLIENTE_TA
Podemos usar el comando SET DESCRIBE DEPTH en SQL*Plus para mostrar los atributos del tipo de dato para
tablas que usan caractersticas objeto-relacional. Podemos especificar valores de profundidad de 1 a 50:
SET DESCRIBE DEPTH 2
DESC CLIENTES

Oracle /265
Name Null? Type
------------------- -------- -----------------
CLIENTE_ID NUMBER
CLIENTE CLIENTE_TA
IDENTIDAD PERSONA
DIRECCION VARCHAR(100)
SET DESCRIBE DEPTH 3
DESC CLIENTES
Name Null? Type
------------------- -------- -----------------
CLIENTE_ID NUMBER
CLIENTE CLIENTE_TA
IDENTIDAD PERSONA
NOMBRE VARCHAR2(30)
TELEFONO VARCHAR2(20)
DIRECCION VARCHAR(100)

1.3. Herencia de clases.


Oracle permite la herencia simple de clases a travs del modificador UNDER. Siguiendo el ejemplo del
apartado anterior, aadimos una fecha a las compras creando una subclase:
CREATE TYPE CompraConFecha UNDER Compra (
fecha DATE
) NOT FINAL;
La clusula FINAL indica si se puede heredar la clase por un subtipo ( NOT FINAL) o si es una clase final y por
lo tanto no se puede extender (FINAL). En este ejemplo s es heredable.
Otra clusula es INSTANTIABLE, para indicar que la clase no es abstracta y por tanto se puede instanciar, o
NOT INSTANTIABLE, para indicar que la clase es abstracta y no se puede instanciar.
La clusula TREAT es el operador de moldeo de un tipo de objeto a subtipos del mismo. Si el moldeo no es
posible se devuelve NULL. El siguiente ejemplo busca en la tabla relacional TRCompraConFecha, asociada al tipo
CompraConFecha, y devuelve los registros de respuesta como objetos Compra.
SELECT VALUE(TREAT(T AS Compra))
FROM TRCompraConFecha T
WHERE VALUE(T.comprador) = Persona('Juan','555');
El operador de predicados para saber si un objeto instanciado pertenece a una clase es IS OF.
IF c1 IS OF (Compra) THEN
DBMS_OUTPUT.PUT_LINE('El objeto referenciado por la variabla c1 es de tipo Compra');
END IF;
1.4. Mtodos.
Existen tres tipos de mtodos a definir en objetos de Oracle: mtodos propiamente dichos, mtodos de
comparacin y constructores.
1.4.1. Administrando mtodos.
Podemos aadir nuevos mtodos a un tipo de datos modificando el tipo de datos (mediante el comando
ALTER TYPE). Por ejemplo, para aadir un mtodo al tipo de dato Persona ya creado:
ALTER TYPE Persona ADD
MEMBER FUNCTION ObtenNombreTelefono RETURN VARCHAR2 CASCADE;
Cuando se modifica un tipo de datos se listan todos sus mtodos, tanto los viejos como los nuevos. Despus
de modificar el tipo de dato debemos modificar el cuerpo del tipo.
CREATE OR REPLACE TYPE BODY Persona IS
MEMBER FUNCTION ObtenNombreTelefono RETURN VARCHAR2 CASCADE IS
BEGIN
RETURN Nombre || ' (' || telefono || ')';
END,
END;
No necesitamos tener el permiso EXECUTE sobre las funciones o procedimientos miembros de un tipo de
dato abstracto. Si concedemos a otro usuario el permiso EXECUTE sobre el tipo Persona, este usuario adquiere
automticamente el permiso EXECUTE sobre los mtodos que son parte del tipo de dato.

Oracle /266
Cuando creamos funciones miembro podemos especificar un mtodo de comparacin (o bien de tipo MAP o
bien de tipo ORDER) o ninguno.
1.4.2. Definicin de mtodos.
Los mtodos (su firma) se indican en la definicin del objeto, pero se implementan posteriormente mediante
el comando CREATE TYPE BODY.
El siguiente cdigo muestra cmo implementar el cuerpo del mtodo getValor() de la clase Compra para
obtener el precio de venta de cada compra:
CREATE TYPE BODY Compra AS
id NUMBER,
comprador Persona,
detalles Tabla_detalles,
MEMBER FUNCTION getValor RETURN NUMBER
IS
Total NUMBER := 0;
BEGIN
FOR I IN detalles.FIRST..detalles.LAST LOOP
Total := Total + ( detalles(I).cantidad * detalles(I).precioUnitario );
END LOOP;
RETURN Total;
END;
END;
1.4.3. Especificacin de los mtodos.
La especificacin de un mtodo se hace junto a la creacin de su tipo, y puede llevar asociada una directiva de
compilacin PRAGMA RESTRICT_REFERENCES(mtodo, lista modificadores) para evitar que el mtodo manipule la
base de datos o las variables del paquete PL/SQL. Por ejemplo:
CREATE TYPE Compra AS OBJECT (
id NUMBER,
comprador Persona,
detalles Tabla_detalles,
MEMBER FUNCTION getValor RETURN NUMBER,
PRAGMA RESTRICT_REFERENCES(getValor, WNDS, RNDS)
);
Los modificadores de la directiva pueden ser alguno de los siguientes:
WNDS: no se permite al mtodo modificar las tablas de la base de datos
WNPS: no se permite al mtodo modificar las variables del paquete PL/SQL
RNDS: no se permite al mtodo leer las tablas de la base de datos
RNPS: no se permite al mtodo leer las variables del paquete PL/SQL
Los mtodos se pueden ejecutar sobre los objetos de su mismo tipo. Si c es una variable PL/SQL que
almacena un objeto del tipo Compra, entonces c.getValor() retorna el valor total de la compra.
1.4.4. Constructores.
Los mtodos constructores, que son implcitamente creados por la base de datos, tienen como objetivo crear
instancias de objetos a partir del estado definido por sus atributos. El constructor implcito creado por la base
de datos tiene como nombre el mismo que la clase y como parmetros sus atributos en el mismo orden en
que se definieron en la clase.
CREATE TYPE Cliente_t AS OBJECT (
id NUMBER,
nombre VARCHAR2(20),
telefono VARCHAR2(30)
);
/
DECLARE
cust1 Cliente_t:= Cliente_t(103, 'Ravi', '1-800-555-1212');
cust2 Cliente_t := NEW Cliente_t(104, 'Ronn', 1-700-444-1212');
An as, es posible definir constructores propios en que se soliciten otros atributos y el proceso de
construccin no sea simplemente la asignacin de valores a sus atributos.
CREATE TYPE Cliente_t AS OBJECT (
id NUMBER,

Oracle /267
nombre VARCHAR2(20),
telefono VARCHAR2(30),
CONSTRUCTOR FUNCTION Cliente_t(id NUMBER, nombre VARCHAR2)
RETURN SELF AS RESULT
);
/
CREATE TYPE BODY Cliente_t AS
CONSTRUCTOR FUNCTION Cliente_t(id NUMBER, nombre VARCHAR2)
RETURN SELF AS RESULT
AS
BEGIN
SELF.id := id;
SELF.nombre := nombre;
RETURN;
END;
END;
/
DECLARE
Cliente_t := NEW Cliente_t(103, 'Ravi');
Tambin se pueden crear mtodos estticos que acten como constructores:
CREATE TYPE Cliente_t AS OBJECT (
id NUMBER,
nombre VARCHAR2(20),
telefono VARCHAR2(30),
STATIC FUNCTION CrearCliente(id NUMBER, nombre VARCHAR2) RETURN Cliente_t
);
/
CREATE TYPE BODY Cliente_t AS
STATIC FUNCTION CrearCliente(id NUMBER, nombre VARCHAR2) RETURN Cliente_t
IS
BEGIN
RETURN Cliente_t(id, nombre, NULL);
END;
END;
/
DECLARE
Cliente_t:= Cliente_t.CrearCliente(103, 'Ravi');
1.4.5. Mtodos de comparacin.
Para comparar los objetos de cierto tipo es necesario indicar a Oracle cul es el criterio de comparacin. Para
ello hay que escoger entre un mtodo MAP u ORDER, debindose definir slo uno de estos mtodos por cada
tipo de objeto que necesite ser comparado. La diferencia entre ambos tipos de mtodos es la siguiente:
Un mtodo MAP sirve para indicar cul de los atributos del tipo se utilizar para ordenar los objetos del
tipo, y por tanto se puede utilizar para comparar los objetos de ese tipo por medio de los operadores de
comparacin aritmticos (<, >). Por ejemplo, la siguiente declaracin permite establecer que los objetos
Persona se van a comparar por su atributo nombre sin tener en cuenta maysculas y minsculas:
CREATE TYPE Persona AS OBJECT (
nombre VARCHAR2(30),
telefono VARCHAR2(20),
MAP MEMBER FUNCTION RetornaNombre RETURN VARCHAR2
);
/
CREATE TYPE BODY Persona AS
MAP MEMBER FUNCTION RetornaNombre RETURN VARCHAR2
IS
BEGIN
RETURN UPPER(nombre);
END;
END;

Oracle /268
Un mtodo ORDER utiliza los atributos del objeto sobre el que se ejecuta para realizar un clculo y
compararlo con otro objeto del mismo tipo pasado como argumento de entrada. Este mtodo devolver
un valor negativo si el parmetro de entrada es mayor que el atributo, un valor positivo si ocurre lo
contrario y un cero si ambos son iguales. El siguiente ejemplo define un orden para el tipo Persona
diferente al anterior.
CREATE TYPE Persona AS OBJECT (
nombre VARCHAR2(30),
telefono VARCHAR2(20),
ORDER MEMBER FUNCTION Compara( P Persona) RETURN INTEGER
);
/
CREATE TYPE BODY Persona AS
ORDER MEMBER FUNCTION Compara( P Persona) RETURN INTEGER
IS
BEGIN
IF (SELF.nombre = P.nombre) THEN
RETURN 0;
ELSE
IF (SELF.nombre < P.nombre) THEN
RETURN -1;
ELSE
RETURN 1;
END IF;
END IF;
END;
END;
Ahora ya podemos comparar dos objetos Persona:
DECLARE
p1 Persona := Persona('Juan', '111111');
p2 Persona := Persona('LUIS', '222222');
BEGIN
IF p1 < p2 THEN
-- p1 es menor que p2
ELSE
-- p1 es mayor o igual que p2
END IF;
END;
Slo una de estas definiciones (MAP u ORDER) puede ser vlida en un tiempo dado. Si un tipo de objeto no
tiene definido ninguno de estos mtodos, Oracle es incapaz de deducir cundo un objeto es mayor o menor
que otro. Sin embargo, s puede determinar cundo dos objetos del mismo tipo son iguales. Para ello, el
sistema compara el valor de los atributos de los objetos uno a uno:
Si todos los atributos son no nulos e iguales, Oracle indica que ambos objetos son iguales.
Si alguno de los atributos no nulos es distinto en los dos objetos, entonces Oracle dice que son
diferentes.
En otro caso, Oracle dice que no puede comparar ambos objetos.
Estas funciones son muy tiles para funciones de agrupacin del estilo DISTINCT, GROUP BY y ORDER BY.
1.5. Tablas relacionales de objetos.
Una vez definidos los tipos, stos pueden utilizarse para definir nuevos tipos, tablas relacionales que
almacenen objetos de esos tipos, o para definir el tipo de los atributos de una tabla relacional.
1.5.1. Creacin de tablas de objetos.
Una tabla relacional de objetos es una clase especial de tabla que almacena un objeto en cada fila y que facilita
el acceso a los atributos de esos objetos como si fueran columnas de la tabla. Por ejemplo, se puede definir
una tabla relacional para almacenar objetos Persona:
CREATE TABLE TRPersona OF Persona
(nombre PRIMARY KEY);
Y otra para almacenar la dependencia de trabajo entre dos personas:

Oracle /269
CREATE TABLE TRJefeEmpleado (
jefe Persona,
empleado Persona);
La diferencia entre la primera tabla ( TRPersona) y la segunda (TRJefeEmpleado) es que la primera almacena
objetos con su propia identidad (OID) y la segunda no es una tabla de objetos, sino una tabla con dos
columnas con un tipo de datos de objeto.
Nota. No podemos borrar y recrear un tipo que es usado por una tabla.
Oracle aade un campo identificador a cada objeto de una tabla relacional para poder referenciarlo. Este
identificador puede coincidir con el campo clave de los registros si especificamos:
CREATE TABLE TRPersona OF Persona (
nombre PRIMARY KEY
) OBJECT IDENTIFIER IS PRIMARY KEY;
O bien puede ser generado automticamente si especificamos:
CREATE TABLE TRPersona OF Persona (
nombre PRIMARY KEY
) OBJECT IDENTIFIER IS SYSTEM GENERATED;
Adems de esto, Oracle permite considerar una tabla de objetos desde dos puntos de vista:
Como una tabla con una sola columna cuyo tipo es el de un tipo de objetos.
Como una tabla que tiene tantas columnas como atributos los objetos que almacena.
Por ejemplo, se puede ejecutar una de las dos instrucciones siguientes.
INSERT INTO TRPersona VALUES (
'Juan Prez',
'696-779789');
/
SELECT VALUE(T) FROM TRPersona T
WHERE T.nombre = 'Juan Prez';
En la primera instruccin, la tabla TRPersona se considera como una tabla con varias columnas cuyos valores
son los especificados. En el segundo caso, se la considera como con una tabla de objetos que en cada fila
almacena un objeto. En esta instruccin, la clusula VALUE permite visualizar el valor de un objeto.
Las reglas de integridad, de clave primaria, y el resto de propiedades que se definan sobre una tabla, slo
afectan a los objetos de esa tabla; es decir, no se refieren a todos los objetos del tipo asignado a la tabla.
Para crear una tabla relacional que almacene objetos que contengan tablas anidadas debemos especificar una
tabla relacional que almacene los elementos de la tabla anidada. Por ejemplo:
-- Se crea una tabla relacional 'TRCompra' cuyos registros mapearn los objetos 'Compra'
-- Tambin se crea una tabla relacional 'TRDetalles' cuyos registros mapearn los objetos 'LineaDetalle'
--contenidos en la tabla anidada 'detalles'
CREATE TABLE TRCompra OF Compra (id PRIMARY KEY) OBJECT IDENTIFIER IS PRIMARY KEY
NESTED TABLE detalles STORE AS TRDetalles;
La tabla anidada TRDetalles no podr ser accedida directamente. Su contenido debe ser accedido a travs de
los objetos de la tabla TRCompra.
1.5.2. Insercin y acceso a los datos en tablas de objetos.
Toda clase o tipo de array dispone de un constructor, el cual es creado automticamente para poder instanciar
un objeto de la clase o tipo. Este constructor tiene como parmetros los atributos que definen la clase en el
mismo orden en que fueron definidos. Por ejemplo, para insertar un nuevo objeto de tipo Compra en la base
de datos:
INSERT INTO TRCompra VALUES (
45,
Persona ('Juan', '555'),
Tabla_detalles (
LineaDetalle('Peras', 4, 3.5),
LineaDetalle('Churros', 12, 0.4)
)
);
En una base de datos con tipos y objetos, lo ms recomendable es utilizar siempre alias para los nombres de
las tablas. El alias de una tabla debe ser nico en el contexto de la consulta. Los alias sirven para acceder al
contenido de la tabla, pero en el caso de las tablas que almacenan objetos, el alias tambin sirve como

Oracle /270
referencia del objeto, y por tanto se utiliza para acceder a los atributos, mtodos y referencias mediante la
nomenclatura habitual del punto entre objeto y atributo. Por ejemplo, para hacer una peticin de elementos:
SELECT T.*
FROM TRCompra T
WHERE T.comprador.nombre='Juan' AND T.comprador.telefono='555';
O bien:
SELECT VALUE(T)
FROM TRCompra T
WHERE T.comprador = Persona('Juan', '555');
Ambos devuelven el mismo valor, salvo que la primera en forma de tabla, siendo cada columna un atributo
del objeto resultado de la consulta. Y en el segundo devuelve el objeto con la forma de constructor explicada
en el ejemplo anterior.
1.5.3. Llamadas a mtodos.
Para invocar un mtodo hay que utilizar su nombre y unos parntesis que encierren sus argumentos de
entrada. Si el mtodo no tiene argumentos, se especifican los parntesis aunque estn vacos. Por ejemplo, la
siguiente consulta es correcta:
SELECT T.getValor() FROM TRCompra T;
1.5.4. ndices para tablas de objetos.
La creacin de ndices en objetos es igual a la de tablas relacionales, identificando el elemento de indexacin
mediante la referencia al atributo ndice. Por ejemplo, para indexar la tabla TRCompra por el nombre del
comprador:
CREATE INDEX NombreComprador ON TRCompra (comprador.nombre);
1.6. Tipos referencia (REF).
Los identificadores nicos asignados por Oracle a los objetos que se almacenan en una tabla relacional,
permiten que stos puedan ser referenciados desde los atributos de otros objetos o desde las columnas de
tablas. El tipo de datos proporcionado por Oracle para soportar esta facilidad se denomina REF. Un atributo
de tipo REF almacena una referencia a un objeto del tipo definido, e implementa una relacin de asociacin
entre los dos tipos de objetos. Estas referencias se pueden utilizar para acceder a los objetos referenciados y
para modificarlos; sin embargo, no es posible operar sobre ellas directamente. Para asignar o actualizar una
referencia se debe utilizar siempre REF o NULL.
Cuando se define una columna de un tipo a REF, es posible restringir su dominio a los objetos que se
almacenen en cierta tabla. Si la referencia no se asocia a una tabla sino que slo se restringe a un tipo de
objeto, se podr actualizar a una referencia a un objeto del tipo adecuado con independencia de la tabla
donde se almacene. En este caso su almacenamiento requerir ms espacio y su acceso ser menos eficiente.
El siguiente ejemplo redefine el tipo Compra y restringe el dominio de su campo comprador a los objetos de
cierta tabla.
-- Tabla relacional cuyos registros se mapean con objetos "Persona"
CREATE TABLE TRPersona OF Persona;
-- Modificacin de la clase "Compra" para que referencie a un objeto "Persona" de la tabla "TRPersona"
CREATE TYPE Compra AS OBJECT (
id NUMBER,
comprador REF Persona,
detalles Tabla_detalles
);
-- Tabla relacional cuyos registros se mapean con objetos "Compra"
CREATE TABLE TRCompra OF Compra (
PRIMARY KEY (id),
SCOPE FOR (comprador) IS TRPersona -- o bien: comprador SCOPE IS TRPersona
);
Cuando se borran objetos de la base de datos puede ocurrir que otros objetos que referencien a los borrados
queden en estado inconsistente. Estas referencias se denominan dangling references, y Oracle proporciona el
predicado llamado IS DANGLING que permite comprobar cundo sucede esto. Por ejemplo, la siguiente
instruccin pone a nulo el comprador que ha perdido su referencia:
UPDATE TRCompra SET comprador = NULL WHERE comprador IS DANGLING;
Los tipos referencia permiten navegar a travs de la estructura de objetos de la misma manera que si fuesen
un atributo del objeto, mediante el operador punto.

Oracle /271
SELECT T.comprador.nombre FROM TRCompra T;
Oracle posee dos funciones para los tipos referencia: REF() que devuelve el identificador de objeto dado la
instancia de un objeto, y DEREF() que dado el identificador de un objeto devuelve la instancia del objeto (y por
tanto es el opuesto de la funcin REF).
Si queremos insertar un objeto en la tabla TRCompra deberemos obtener la referencia de un objeto de la tabla
TRPersona de la siguiente manera:
INSERT INTO TRCompra (id, comprador, detalles)
SELECT 1, REF(tr), NULL FROM TRPersona tr WHERE nombre='Jos Prez';
Para mostrar el contenido de la tabla, ahora debemos aplicar la funcin DEREF:
SELECT id, DEREF(comprador), detalles FROM TRCompra;
1.7. Tablas anidadas y arrays variables.
Como ya se ha visto, los arrays variables ( VARRAY) y las tablas anidadas (TABLE) permiten modelar las
relaciones de uno a varios que son muy comunes en los modelos orientados a objetos. Estos tipos se
denominan colecciones porque representan conjuntos de datos de un mismo tipo.
Las tablas anidadas permiten almacenar un conjunto indeterminado de elementos, y por eso no es posible
almacenar su contenido dentro del registro que la incluye como campo. Cuando creemos un atributo de tipo
tabla anidada debemos indicar siempre qu tabla externa ser la que almacene los datos. En el ejemplo del
apartado anterior
CREATE TABLE TRCompra OF Compra
NESTED TABLE detalles STORE AS TRDetalles;
TRDetalles es la tabla externa que almacenar los elementos LineaDetallede la tabla anidada detalles. Esta tabla
relacional quedar oculta en el diccionario de datos y su acceso slo podr realizarse a travs de la tabla
principal TRCompra.
Sin embargo, los arrays variables son de un tamao mximo fijo, por lo que no es necesario guardarlos en una
tabla externa y se almacenan en la propia tabla principal (u objeto).
Hay dos formas de acceder a los elementos de las colecciones:
La primera es recibiendo la coleccin como un solo elemento en la forma de su constructor.
La segunda es acceder a su contenido como un conjunto de registros mediante la funcin TABLE().
Un ejemplo del primer tipo sera el siguiente, en el que se devuelve un valor de tipo coleccin que engloba a
todos los valores de la coleccin:
SELECT T.id, T.detalles FROM TRCompra T;
Un resultado posible ser:
Id detalles
--- -----------------------------------------------------------------------
1 Tabla_detalles (LineaDetalle('P1',4,3.5), LineaDetalle('P2',12,0.4))
2 Tabla_detalles (LineaDetalle('P1',9,7))
Un ejemplo del segundo tipo es el siguiente en el que se devuelven las lneas de detalle para el pedido de id 1:
SELECT * FROM TABLE( SELECT T.detalles FROM TRCompra T WHERE T.id=1);
El resultado ser:
Producto Cantidad PrecioUnitario
---------- ---------- --------
P1 4 3.5
P2 12 0.4
Igualmente, para la insercin o modificacin de colecciones podemos hacer uso del constructor de la
coleccin para introducirle el conjunto de valores por completo, modificndose todo el array variable o tabla
anidada de una vez:
INSERT INTO TRCompra VALUES (
1,
Persona('Juan', '555'),
Tabla_detalles(
LineaDetalle('chorizo', 4, 3.5),
LineaDetalle('jamn', 3, 7.6)
)
);
O bien (slo para tablas anidadas) podemos insertar tuplas en la columna correspondiente de la tupla
seleccionada por una subconsulta usando la palabra clave THE con la siguiente sintaxis:

Oracle /272
INSERT INTO THE (SELECT T.detalles FROM TRCompra T WHERE id = 45)
VALUES (LineaDetalle('Nuevo producto', 3, 5.2));
Esta tcnica es especialmente til si dentro de una tabla anidada se guardan referencias a otros objetos.
Tambin en el caso de una tabla anidada (no es posible en un array variable), podemos acceder a la tabla
directamente haciendo uso de la funcin TABLE(), lo que nos permitira actualizar de forma selectiva los
elementos:
UPDATE TABLE(SELECT T.detalles FROM TRCompra T WHERE T.id=1) P
SET VALUE(P) = LineaDetalle('chorizo', 6, 5.5)
WHERE P.producto = 'choriz';
Para poner condiciones a las tuplas de una tabla anidada, se pueden utilizar cursores dentro de un SELECT o
desde un programa PL/SQL. Por ejemplo, la siguiente consulta recupera las compras con su cdigo de
compra, el nombre del comprador y las lneas de detalle con cantidades mayores de 5:
SELECT T.id, T.comprador.nombre, CURSOR(SELECT * FROM TABLE(T.detalles) D WHERE D.cantidad>5)
FROM TRCompra T;
La clusula THE tambin sirve para seleccionar las tuplas de una tabla anidada. Por ejemplo, para seleccionar
la primera lnea de detalle de la compra de cdigo 45:
SELECT LP.*
FROM THE (SELECT T.detalles FROM TRCompra T WHERE T.id=45) LP
WHERE ROWNUM=1;
1.7.1. Funciones adicionales para tablas anidadas y arrays variables.
Desde Oracle Database 10g, podemos usar varias funciones nuevas para tablas anidadas y arrays variables.
Para los siguientes ejemplos usaremos los siguientes tipos y tablas:
CREATE TYPE ANIMALES_AV AS VARRAY(10) OF VARCHAR(20);
CREATE TYPE ANIMALES_TA AS TABLE OF VARCHAR(20);
CREATE TABLE GRANJA (
Propietario VARCHAR2(200),
Ubicacion VARCHAR2(200),
Animales ANIMALES_AV
);
La funcin CARDINALITY retorna el nmero de elementos dentro de una tabla anidada o array variable:
SELECT CARDINALITY(Animales) FROM GRANJA;
La funcin MULTISET EXCEPT toma dos tablas anidadas como entrada y retorna el conjunto de registros que
estn en la primera tabla anidada pero no en la segunda (similar al operador de resta).
DECLARE
A1 ANIMALES_TA := ANIMALES_TA ('PERRO', 'GATO');
A2 ANIMALES_TA := ANIMALES_TA('GALLINA', 'PERRO');
A3 ANIMALES_TA;
BEGIN
A3 := A1 MULTISET EXCEPT A2;
-- Como resultado: A3 := ANIMALES_TA('GATO')
END;
La funcin MULTISET INTERSECT toma dos tablas anidadas como entrada y retorna los elementos en comn.
DECLARE
A1 ANIMALES_TA := ANIMALES_TA ('PERRO', 'GATO');
A2 ANIMALES_TA := ANIMALES_TA('GALLINA', 'PERRO');
A3 ANIMALES_TA;
BEGIN
A3 := A1 MULTISET INTERSECT A2;
-- Como resultado: A3 := ANIMALES_TA('PERRO')
END;
La funcin MULTISET UNION toma dos tablas anidadas como entrada y retorna los elementos de ambas
tablas.
DECLARE
A1 ANIMALES_TA := ANIMALES_TA ('PERRO', 'GATO');
A2 ANIMALES_TA := ANIMALES_TA('GALLINA', 'PERRO');
A3 ANIMALES_TA;
BEGIN

Oracle /273
A3 := A1 MULTISET INTERSECT DISTINCT A2;
-- Como resultado: A3 := ANIMALES_TA('PERRO', 'GATO', 'GALLINA')
END;
Para esta funcin podemos especificar MULTISET UNION ALL (por defecto) o MULTISET UNION DISTINCT.
La funcin SET convierte una tabla anidada dentro de un conjunto mientras elimina duplicados, retornando
una tabla anidada de valores distintos:
DECLARE
A1 ANIMALES_TA := ANIMALES_TA ('PERRO', 'GATO', 'GALLINA', 'PERRO');
A2 ANIMALES_TA;
BEGIN
A3 := SET(A1);
-- Como resultado: A3 := ANIMALES_TA('PERRO', 'GATO', 'GALLINA')
END;
La funcin COLLECT toma una columna como entrada y crea una tabla anidada del tipo de entrada. Para
obtener los resultados de esta funcin debemos usarla dentro de una funcin CAST con un comando SELECT
con la clusula GROUP BY.
CREATE OR REPLACE TYPE varchar2_ntt AS TABLE OF VARCHAR2(200);
SELECT Propietario, CAST(COLLECT(Ubicacion) AS varchar2_ntt)
FROM GRANJA
GROUP BY Propietario;
Un posible resultado de esta consulta puede ser:
PROPIETARIO CAST(COLLECT(UBICACION)ASVARCHAR2_NTT)
-------------------------- -----------------------------------------------------------
Juan Prez VARCHAR2_NTT('Madrid', 'Castelln')
Mara Belo VARCHAR2_NTT('Alicante')
La funcin POWERMULTISET toma como entrada una tabla anidada y retorna una tabla anidada cuyos
elementos son tablas anidadas que contienen todos los subconjuntos no vacos de la tabla de entrada.
SELECT CAST(POWERMULTISET(Animales) AS ANIMALES_TA)
FROM GRANJA;
La funcin POWERMULTISET_BY_CARDINALITY toma como entrada una tabla anidada y una cardinalidad y
retorna una tabla anidada cuyos elementos son tablas anidadas que contienen los subconjuntos no vacos de
la tabal de entras en la cardinalidad especificada.
SELECT CAST(POWERMULTISET_BY_CARDINALITY(Animales, 2) AS ANIMALES_TA)
FROM GRANJA;
1.8. Vistas de objeto.
Para poder convertir el modelo relacional en el modelo orientado a objetos, sin necesidad de modificar los
datos ni su estructura (metadatos), es posible generar vistas de los datos relacionales de tal manera que stos
puedan ser vistos como objetos.
CREATE TABLE Tabla_empleado (
empNum NUMBER (5),
eNombre VARCHAR2 (20),
salario NUMBER (9, 2),
trabajo VARCHAR2 (20)
);
/
CREATE TYPE Empleado_t AS OBJECT(
empNum NUMBER (5),
eNombre VARCHAR2 (20),
salario NUMBER (9, 2),
trabajo VARCHAR2 (20),
MEMBER FUNCTION SalarioNeto RETURN NUMBER
);
/
CREATE VIEW vistaEmpleado OF Empleado_t WITH OBJECT IDENTIFIER (empNum) AS
SELECT e.empNum, e.eNombre, e.salario, e.trabajo
FROM Tabla_empleado e

Oracle /274
WHERE trabajo = 'Programador';
Al crear la vista de objetos debemos especificar el campo que actuar como identificador de cada objeto y que
ser normalmente el campo clave de la tabla base.
La ventaja de las vistas de objeto est en la capacidad de invocar los mtodos del objeto en las consultas:
SELECT v.empNo, v.eNombre, v.SalarioNeto()
FROM vistaEmpleado v;
1.9. Trabajando con tipos SQL desde aplicaciones JDBC.
1.9.1. Recuperacin de objetos Oracle en objetos oracle.sql.STRUCT.
Podemos recuperar un objeto Oracle directamente dentro de una instancia de oracle.sql.STRUCT. En el
siguiente ejemplo, se usa el mtodo getObject() para obtener un objeto de una tabla de objetos.
Connection conexion = DriverManager.getConnection( cadenaDeConexion, login, password );
// Se crea un tipo de objeto y una tabla de objetos
String cmd = "CREATE TYPE Tipo_Lote AS OBJECT (codigo NUMBER, fecha DATE)";
Statement stmt = conexion.createStatement();
stmt.execute(cmd);
cmd = "CREATE TABLE Tabla_Lote OF Tipo_Lote";
stmt.execute(cmd);
// Se insertan dos registros en la tabla de objetos
cmd = "INSERT INTO Tabla_Lote VALUES (Tipo_Lote(10,'01-Abr-11'))";
stmt.execute(cmd);
cmd = "INSERT INTO Tabla_Lote VALUES (Tipo_Lote(20,'02-May-11'))";
stmt.execute(cmd);
// Se recuperan los registros de la tabla de objetos
ResultSet rs= stmt.executeQuery("SELECT * FROM Tabla_Lote");
rs.next();
// Se accede al primer registro
oracle.sql.STRUCT oracleSTRUCT = (oracle.sql.STRUCT) rs.getObject(1);
Otro modo es retornar los objetos como un objeto STRUCT es moldear el resultado a un objeto
OracleResultSet y usar el mtodo de Oracle getSTRUCT():
oracle.sql.STRUCT oracleSTRUCT = ((OracleResultSet) rs).getSTRUCT(1);
Si queremos acceder ahora a los atributos del STRUCT como tipos oracle.sql, se usa el mtodo
getOracleAttributes():
oracle.sql.Datum[] attrs = oracleSTRUCT.getOracleAttributes();
1.9.2. Enlazando objetos STRUCT dentro de un comando.
Para enlazar un objeto oracle.sql.STRUCT a un comando del tipo PreparedStatement o CallableStatement,
podemos usar el mtodo estndar setObject(), o moldear el objeto de comando a un OraclePreparedStatement
u OracleCallableStatement, y usar el mtodo setOracleObject(). Siguiendo con el ejemplo anterior:
PreparedStatement ps =
conexion.prepareStatement("UPDATE Tabla_Lote T SET VALUE(T) = ? WHERE VALUE(T).codigo=10");
StructDescriptor sd = new StructDescriptor("Tipo_Lote", conexion);
STRUCT miSTRUCT = new STRUCT (sd, conexion, new Object [] {11, new java.sql.Date(2011,12,22)});
ps.setObject(1, miSTRUCT, Types.STRUCT);
ps.execute()
O bien:
PreparedStatement ps =
conexion.prepareStatement("UPDATE Tabla_Lote T SET VALUE(T) = ? WHERE VALUE(T).codigo=10");
StructDescriptor sd = new StructDescriptor("Tipo_Lote", conexion);
STRUCT miSTRUCT = new STRUCT (sd, conexion, new Object [] {11, new java.sql.Date(2011,12,22)});
((OraclePreparedStatement) ps).setOracleObject(1, miSTRUCT);
ps.execute()
1.10. Crear y usar clases de objetos Java personalizadas para objetos Oracle.
Si queremos crear clases de objetos personalizadas para los objetos Oracle, entonces debemos definir
entradas en el mapa de tipos que especifique las clases de objetos que los drivers deben instanciar para los
correspondientes tipos de Oracle. Tambin debemos proporcionar un modo de crear y poblar instancias de la
clase personalizada desde los objetos Oracle y sus atributos. Para crear y poblar clases personalizadas y
proporcionar capacidades de lectura/escritura podemos elegir entre dos interfaces a implementar:

Oracle /275
La interfaz de JDBC estndar java.sql.SQLData.
Las interfaces oracle.sql.ORAData y oracle.sql.ORADataFactory proporcionadas por Oracle.
La clase personalizada debe implementar una de estas interfaces. La interfaz ORAData tambin puede ser
usada para implementar la clase de referencia personalizada correspondiente a una clase de objeto
personalizada. Si usamos la interfaz SQLData, sin embargo, slo podemos usar tipos de referencias dbiles en
Java (java.sql.Ref u oracle.sql.REF). La interfaz SQLData se usa slo para mapear objetos SQL.
Como un ejemplo, asumamos que existe en la base de datos un tipo de objeto Oracle denominado
Empleado.Persona, el cual consiste de dos atributos: Nombre (como un VARCHAR2) y Edad (como un NUMBER).
CREATE TYPE Persona AS OBJECT (
Nombre VARCHAR2(100), Edad NUMBER(3)
);
Usaremos el mapeado de tipos para especificar que el objeto Persona debera mapear con una clases
personalizada que llamaremos JPersona. Podemos implementar tanto SQLData como ORAData en la clase
JPersona.
1.10.1. Ventajas de ORAData contra SQLData.
A la hora de decidir qu interfaz implementar, consideremos las siguientes ventajas de cada interfaz:
Ventajas de oracle.sql.ORAData Ventajas de java.sql.SQLData
No requiere una entrada en el mapa de tipos para el Es un estndar JDBC, haciendo nuestro cdigo ms
objeto Oracle. portable.
Tiene acceso a las extensiones de Oracle.
Podemos crear un ORAData desde un STRUCT. Es
ms eficiente porque evita conversiones innecesarias.
Proporciona mejor rendimiento: ORAData trabaja
directamente con tipos Datum, que es el formato
interno usando por el driver que contiene los objetos
Oracle.
La interfaz SQLData es slo para mapear objetos SQL. Mientras que ORAData es ms flexible, permitiendo
mapear objetos SQL con cualquier otro tipo SQL. Podemos crear un objeto ORAData para cualquier tipo de
dato encontrado dentro de la base de datos de Oracle. Esto podra ser til para serializar datos RAW en Java.
1.10.2. El mapeado de tipos para implementaciones SQLData.
Si usamos la interfaz SQLData en una clase personalizada, entonces podemos crear entradas para el mapeado
de tipos que especifiquen las clases de objetos personalizados que usaremos para mapear los tipos de objetos
de Oracle. Podemos usar el mapeado de tipos por defecto para el objeto de conexin, o un mapeado de tipos
que podemos especificar cuando recuperemos los datos. El mtodo ResultSet.getObject() tiene una firma que
permite especificar un mapeado de tipos:
public Object getObject(int columnIndex, Map map);
Cuando usamos la implementacin SQLData, si no incluimos una entrada en el mapeado de tipos, entonces el
objeto ser mapeado a la clase oracle.sql.STRUCT por defecto. (Las implementaciones ORAData, en contrasta,
tienen su propia funcionalidad de mapeado, as que no requiere entradas de mapeado de tipos. En este caso
se usa el mtodo getORAData() en vez del mtodo getObject().)
El mapeado de tipos relaciona un tipo de Java a un nombre de tipo SQL para un objeto Oracle. Este
mapeado se almacena en un HashTable como pares clave-valor. Cuando de leen datos de un objeto Oracle, el
driver JDBC considera el mapeado de tipos para determinar qu clase Java debe usar para materializar los
datos desde el tipo de Oracle. Cuando escribimos datos a un objeto Oracle, el driver JDBC obtiene el nombre
del tipo SQL desde la clase de Java invocando el mtodo getSQLTypeName() de la interfaz SQLData. La
conversin entre SQL y Java es realizada por el driver.
Los atributos de una clase Java que correspondan con objetos Oracle pueden usar tipos nativos Java o tipos
nativos Oracle (instancias de las clases oracle.sql.*).
Creando un mapeado de tipos para implementaciones SQLData.
Cada instancia de conexin (objetos java.sql.Connection) tiene asociado un mapa, el cual puede ser obtenido
mediante el mtodo getTypeMap(). Cuando se establece por primera vez la conexin este mapa est vaco.
Podemos poblarlo usando cualquier funcionalidad de mapeado SQL-Java.
Normalmente deberemos seguir los siguientes pasos para aadir entradas al mapa existente:
1) Usar el mtodo OracleConnection.getTypeMap() para obtener el mapa de tipos:
java.util.Map miMapa = conexion.getTypeMap();

Oracle /276
2) Usar el mtodo put() para aadir entradas de mapeado.
miMapa.put("EMPLEADO.PERSONA", JPersona.class);

Nota. El nombre del tipo SQL debe ser especificado en maysculas, porque es as como es
almacenado en el diccionario de datos de la base de datos.
Podemos tambin crear un nuevo mapa y asignarlo al objeto de conexin mediante el mtodo
Connection.setTypeMap().
Materializando tipos de objetos no especificados en el fichero de tipos.
Si no proporcionamos en el mapa de tipos una entrada apropiada cuando usamos una llamada a getObject(),
entonces el driver JDBC materializar un objeto Oracle como una instancia de la clase oracle.sql.STRUCT. Si el
objeto Oracle contiene objetos embebidos, y stos no estn presentes en el mapa de tipos, el driver los
materializar tambin como instancias de oracle.sql.STRUCT. Si los objetos embebidos estn presentes en el
mapa de tipos, una llamada al mtodo getAttributes() retornar los objetos embebidos como instancias de las
clases Java especificadas en el mapa.
1.10.3. Cmo se utiliza la interfaz SQLData.
La interfaz SQLData define mtodos que trasladan tipos entre SQL y Java para los objetos de Oracle. Una
clase que implemente SQLData debe proporcionar los mtodos readSQL() y writeSQL().
El driver JDBC llama a nuestro readSQL() para leer un flujo de valores de datos desde la base de datos y
puebla una instancia de nuestra clase personalizada. Normalmente el driver usar este mtodo como parte de
la llamada al mtodo OracleResultSet.getObject(). Anlogamente, el driver llama al mtodo writeSQL() para
escribir una secuencia de datos desde una instancia de nuestra clase personalizada a la base de datos.
Normalmente el driver usar este mtodos como parte de la llamada al mtodo setObject() de objetos
OraclePreparedStatement y OracleCallableStatement.
La firma de ambos mtodos es la siguiente:
public void readSQL(SQLInput stream, String typeName) throws SQLException
public void writeSQL(SQLOutput stream) throws SQLException
Uso de las interfaces SQLInput y SQLOutput.
El mtodo readSQL() recibe como primer argumento un objeto del tipo java.sql.SQLInput, el cual representa
un canal de entrada. SQLInput incluye mtodos readXXX() para cada tipo de dato Java a los cuales un atributos
del objeto Oracle puede ser convertido, tales como readObject(), readInt(), readLong(), readFloat(), readBlob(), y
dems. Cada mtodo readXXX() convierte el dato SQL al dato Java correspondiente.
Por su parte, el mtodo writeSQL() recibe como argumento un objeto de tipo SQLOutput, el cual representa un
canal de salida. SQLOutput incluye mtodos writeXXX() para cada uno de los tipos Java.
Implementacin de los mtodos readSQL() y writeSQL().
El mtodo readSQL() recibe un argumento de tipo SQLInput y un string que indica el nombre del tipo SQL de
los datos. Cuando nuestra aplicacin Java invoca getObject(), el driver JDBC crea un canal de tipo SQLInput y
lo puebla con datos desde la base de datos. El driver puede tambin determinar el nombre del tipo SQL de
los datos cuando son ledos desde la base de datos. Cuando el driver llama a readSQL() le pasa estos
parmetros.
Para cada tipo de dato Java que mapea a un atributo del objeto Oracle, readSQL() debe llamar al apropiado
mtodo readXXX() del canal.
Por su parte, el mtodo writeSQL() recibe un canal de tipo SQLOutput. Por cada tipo de dato Java que mapea a
un atributo de un objeto Oracle, writeSQL() debe llamar a los apropiados mtodos writeXXX() del canal para
enviar los datos de sus atributos.
Por ejemplo, si estamos leyendo objetos Persona (que tienen un atributo VARCHAR2 para el nombre, y un
atributo NUMBER para la edad) debemos llamar a readString() y a readInt() para poblar los campos
correspondientes del objeto Java. La implementacin puede ser como sigue:
public class JPersona implements SQLData {
private String nombre;
private int edad;
public JPersona() throws SQLException {
}
public JPersona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;

Oracle /277
}
@Override
public String getSQLTypeName() throws SQLException {
return "EMPLEADO.PERSONA";
}
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
if (typeName.equals("EMPLEADO.PERSONA")) {
nombre = stream.readString();
edad = stream.readInt();
}
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeString(nombre);
stream.writeInt(edad);
}
@Override
public String toString() {
return "JPersona{" + "nombre=" + nombre + ", edad=" + edad + '}';
}
}
Leyendo y escribiendo datos con la implementacin SQLData.
Veamos ahora cmo leer registros de una tabla de objetos Persona creada en la base de datos:
CREATE TABLE TPERSONA OF PERSONA;
INSERT INTO TPERSONA VALUES (PERSONA('JUAN', 30));
INSERT INTO TPERSONA VALUES (PERSONA('ANA', 33));
Previamente debemos crear un objeto de conexin y crear una entrada en el mapa de tipos para nuestro tipo
de objeto:
Connection conexion = DriverManager.getConnection( cadenaDeConexion );
conexion.getTypeMap().put("EMPLEADO.PERSONA", JPersona.class);
Ahora consultamos la tabla para obtener los registros como objetos Persona de Oracle:
Statement comando = conexion.createStatement();
ResultSet rs = comando.executeQuery("SELECT VALUE(T) FROM TPERSONA T");
Por ltimo podemos leer el primer registro y mostrar su contenido como un objeto JPersona de Java:
rs.next();
JPersona persona = (JPersona) rs.getObject(1);
System.out.println(persona);
conexion.close();
Si ahora queremos insertar un nuevo objeto Persona en la base de datos podemos utilizar un PreparedStament y
pasar el dato como un parmetro:
conexion.getTypeMap().put("EMPLEADO.PERSONA", JPersona.class);
PreparedStatement ps = conexion.prepareStatement("INSERT INTO TPERSONA VALUES (?)");
ps.setObject(1, new JPersona("Maria", 23));
ps.execute();
conexion.close();
1.10.4. Cmo se utiliza la interfaz ORAData.
La interfaces oracle.sql.ORAData y oracle.sql.ORADataFactory hacen lo siguiente:
El mtodo toDatum() de ORAData transforma los datos en una representacin de tipos oracle.sql.*.
El mtodo create() de ORADataFactory equivale a un constructor de nuestra clase personalizada. Crea y
retorna una instancia de ORAData. El driver JDBC usa el mtodo create() para retornar una instancia de la
clase personalizada para nuestra aplicacin Java. Toma como entrada un objeto oracle.sql.Datum y un entero
que indica el cdigo de tipo SQL (pueden utilizarse las constantes de la clase oracle.jdbc.OracleTypes).
Las interfaces ORAData y ORADataFactory tienen las siguientes definiciones:
public interface ORAData {
Datum toDatum (OracleConnection conn) throws SQLException;
}

Oracle /278
public interface ORADataFactory {
ORAData create (Datum d, int sql_Type_Code) throws SQLException;
}
Recuperando e insertando datos.
El driver JDBC proporciona los siguientes mtodos para recuperar e insertar objetos de datos como
instancias de ORAData.
Para recuperar objetos de datos:
Se usa el mtodo especfico de Oracle OracleResultSet.getORAData(), que tiene la siguiente firma:
ORAData getORAData (int col_index, ORADataFactory factory);
Este mtodo toma como entrada el ndice de la columna de los datos en el ResultSet, y una instancia de
ORADataFactory.
O se usa el mtodo estndar ResultSet.getObject(index, map) para recuperar datos como instancias de
ORAData. En este caso debemos incluir una entrada en el mapa de tipos para identificar la clase creadora
que ser usada por el tipo de objeto y que se corresponde con un nombre de tipo SQL.
Para insertar objetos de datos:
Se usa el mtodo especfico de Oracle OraclePreparedStatement.setORAData(), que tiene la siguiente firma:
void setORAData (int bind_index, ORAData custom_obj);
Este mtodo toma como entrada el ndice del parmetro de la variable enlazada y el objeto que contiene la
variable.
O se usa el mtodo estndar PreparedStatement.setObject(). Tambin se puede usar este mtodo, en sus
diferentes formas, para insertar instancias ORAData sin requerir un mapa de tipos.
Para continuar con el ejemplo del tipo Persona de Oracle, podemos crear la siguiente clase en nuestra
aplicacin Java:
// Se define la clase personalizada implementando ambas interfaces
public class JPersona2 implements ORAData, ORADataFactory {
private CHAR nombre;
private NUMBER edad;
public JPersona2() throws SQLException {
}
private JPersona2(CHAR nombre, NUMBER edad) {
this.nombre = nombre;
this.edad = edad;
}
public JPersona2(String nombre, int edad) {
this.nombre = new CHAR(nombre.getBytes(), CharacterSet.make(CharacterSet.UTF8_CHARSET));
this.edad = new NUMBER(edad);
}
@Override
public String toString() {
return "JPersona{" + "nombre=" + nombre + ", edad=" + edad.stringValue() + '}';
}
@Override
public Datum toDatum(Connection cnctn) throws SQLException {
StructDescriptor sd = StructDescriptor.createDescriptor("PEDRO.PERSONA", cnctn);
Object[] atributos = {nombre, edad};
return new STRUCT(sd, cnctn, atributos);
}
@Override
public ORAData create(Datum datum, int i) throws SQLException {
if (datum == null) {
return null;
}
Object[] atributos = ((STRUCT) datum).getOracleAttributes();
return new JPersona2((CHAR) atributos[0], (NUMBER) atributos[1]);
}
}
Ahora podemos escribir un cdigo para recuperar un registro Persona de la tabla TPersona:

Oracle /279
Connection conexion = DriverManager.getConnection( cadenaDeConexion );
Statement comando = conexion.createStatement();
OracleResultSet rs = (OracleResultSet) comando.executeQuery("SELECT VALUE(T) FROM TPERSONA T");
rs.next();
JPersona2 datum = (JPersona2) rs.getORAData(1, new JPersona2());
conexion.close();.
En este ejemplo se recupera el primer registro como un objeto ORAData, y para ello se pasa un objeto de tipo
JPersona2, puesto que implementa ORADataFactory. El driver JDBC llamar al mtodo create() de este objeto,
de forma que retorna a nuestra aplicacin Java una instancia de la clase JPersona2 poblada con los datos del
ResultSet.

Nota. ORAData y ORADataFactory pueden ser definidas como interfaces independientes, de forma
que diferentes clases pueden implementarlas.
Tambin podemos usar el mtodo estndar getObject() para recuperar los datos. Este mtodo requiere un
mapa de tipos que identifique la clase que implementa ORADataFactory y su correspondiente nombre de tipo
SQL.
HashMap mapa = new HashMap();
mapa.put ("EMPLEADO.PERSONA", JPersona2.class);
Connection conexion = DriverManager.getConnection( cadenaDeConexion );
Statement comando = conexion.createStatement();
OracleResultSet rs = (OracleResultSet) comando.executeQuery("SELECT VALUE(T) FROM TPERSONA T");
rs.next();
JPersona2 datum = (JPersona2) rs.getObject(1, mapa);
conexion.close();.
Para insertar un nuevo registro en la tabla TPersona usando un objeto JPersona2 podemos utilizar el siguiente
cdigo:
JPersona2 p = new JPersona2("Jse", 40);
OraclePreparedStatement ps =
(OraclePreparedStatement) conexion.prepareStatement("INSERT INTO TPERSONA VALUES (?)");
ps.setORAData(1, new JPersona2("Jse", 40));
ps.execute();
conexion.close();
En vez de setORAData() tambin se puede usar el mtodo estndar setObject():
ps.setObject(1, new JPersona2("Jse", 40));
1.10.5. Creando objetos SQL a partir de clases de Java.
En los apartados previos hemos creado una clase Java para mapear una clase SQL de Oracle creada
previamente. Tambin es posible crear una clase Java dentro de la base de datos y usarla para crear a partir de
ella un tipo de objeto de Oracle.
Definimos la clase JPersona dentro de la base de datos:
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED JPersona AS
import java.sql.*;
import java.io.*;
public class JPersona implements SQLData {
private String tipo_sql = "EMPLEADO.PERSONA";
private String nombre;
private int edad;
public String getNombre() {return nombre;}
public void setNombre(String nombre) {this.nombre= nombre;};
public int getEdad() {return edad;}
public void setEdad(int edad) {this.edad = edad;}
public JPersona () {}
public String getSQLTypeName() throws SQLException { return tipo_sql; }
public void readSQL(SQLInput stream, String typeName) throws SQLException {
tipo_sql = typeName;
nombre = stream.readString();
edad = stream.readInt();
}

Oracle /280
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeString(nombre);
stream.writeInt(edad);
}
// otros mtodos
public String toString() {
return "(" + nombre + "," + edad + ")";
}
}
Una vez implementada la clase Java y compilada, se puede cargar en la base de datos, y a partir de este
momento la clase y sus mtodos estn disponibles en Oracle. A continuacin se define el tipo abstracto SQL
de la manera explicada hasta ahora y se indica que el tipo lo implementa una clase Java y cmo se mapean los
mtodos de Java a Oracle. La firma del mtodo en Oracle va seguida del comando EXTERNAL NAME con la
firma del mtodo en Java de donde se infiere el mapeado de tipos.
El siguiente ejemplo modifica el tipo de objeto Persona para que mapee la clase de Java denominada JPersona:
CREATE OR REPLACE TYPE Persona AS OBJECT EXTERNAL NAME 'JPersona' LANGUAGE JAVA
USING SQLData (
nombre VARCHAR2(30) EXTERNAL NAME 'nombre',
edad NUMBER(3) EXTERNAL NAME 'edad',
MEMBER FUNCTION TO_STRING RETURN VARCHAR2
EXTERNAL NAME 'toString() return java.lang.String'
);
/

2. Documentos XML en Oracle


XML es el formato de codificacin/estructuracin para el intercambio de datos ms comn hoy en da. Sin
embargo el modelado de este tipo de datos en bases de datos relacionales era complicado por el mismo
motivo que el modelado de objetos: los documentos XML no tienen una estructura plana, con lo que su
representacin en tablas se hace complicada.
La opcin hasta hace poco era el almacenar los documentos en objetos grandes de tipo CLOB o NCLOB y
analizar/transformar estos elementos tomando este flujo de caracteres y hacindolos pasar por un parseador
XML habitual. No se aprovechaba ninguna de las caractersticas de la base de datos para mejorar la eficiencia
de bsquedas y consultas, salvo por alguna caracterstica de indexado avanzada de texto.
Con la llegada del modelo objeto-relacional el problema de la planaridad se resuelve y las mismas facilidades
que se daban para el modelado de objetos se ofrecen ahora para el modelado de los objetos XML en la
estructura de la base de datos. Esta integracin permite hacer uso de la eficiencia de las consultas y
flexibilidad de recorrido de estructuras del modelo relacional en estos documentos.
2.1. XMLType.
Este mapeado de la estructura XML a la estructura de la base de datos en Oracle se realiza con el tipo
XMLType, que es un tipo abstracto. El tipo XMLType se almacena en un tipo CLOB y puede asociarse a un
Esquema XML para la definicin de su estructura, lo que obliga a que cualquier documento sea validado con
este esquema. En este caso, el esquema del documento se modela en la estructura objeto-relacional de la base
de datos.
La ventaja de no validar contra un esquema es que todo tipo de documentos XML pueden almacenarse en ese
elemento XMLType. En caso contrario se obliga a que el elemento sea vlido frente al esquema asociado,
aunque su mapeado en la estructura objeto-relacional permite tratar el documento de manera ms eficiente y
flexible.
2.2. Mapeado de XMLType dado un esquema XML.
Los elementos del esquema XML se mapean como objetos en los que cada elemento anidado de tipo simple
es representado por un atributo de un tipo nativo lo ms acorde posible con el tipo del esquema: si es un
nmero con NUMBER, si es texto con VARCHAR2,
An as, es posible forzar la representacin del elemento a un tipo de Oracle mediante el atributo SQLType
utilizado en el elemento del esquema. Cuando un elemento contiene un elemento complejo, ste es modelado
con un objeto y el elemento padre establece una referencia a l con tipos referencia. Es posible forzar que el
mapeado de los tipos complejos se realice en CLOB, NCLOB o VARCHAR2 (sin ser representados en el modelo

Oracle /281
objeto-relacional) mediante el atributo SQLType (=CLOB) utilizado en el elemento del esquema.
Cuando la ocurrencia de un elemento, bien simple o complejo, es mayor que uno el elemento es representado
en el objeto padre con un array variable (si el nmero de ocurrencias mximas es finito) o con un tabla
anidada (si es infinito).
El mapeado se entiende mucho mejor con el siguiente ejemplo:
DECLARE
doc varchar2(3000) :=
'<schema xmlns = "http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp.xsd"
xmlns:emp="http://www.oracle.com/emp.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<element name = "Empleado">
<complexType>
<sequence>
<element name = "Nombre" type = "string"/>
<element name = "Edad" type = "decimal"/>
<element name = "Direccion" maxOccurs="unbounded">
<complexType>
<sequence>
<element name = "Calle" type = "string"/>
<element name = "Ciudad" type = "string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>';
Se mapeara de la siguiente manera:
CREATE TYPE Direccion_t AS OBJECT (
calle VARCHAR2(4000),
ciudad VARCHAR2(4000) );
CREATE TYPE Direccion_t_table AS TABLE OF Direccion_t;
CREATE TYPE Empleado AS OBJECT (
Nombre VARCHAR2(4000),
Edad NUMBER,
Direccion_table Direccion_t_table );
2.3. Crear tablas/columnas XMLType.
Para crear columnas o tablas XMLType slo tenemos que hacerlo como lo hicimos al definir columnas o tablas
de objetos. Si no validamos el tipo XMLType con un esquema, los ejemplos seran los siguientes (el primero es
una tabla con una columna tipo XMLType y el segundo es una tabla de XMLType):
CREATE TABLE TREmpleado (
id NUMBER(3),
xmlEmpleado XMLTYPE
);
/
CREATE TABLE TXEmpleado OF XMLTYPE;
En este segundo caso, realmente se crea una tabla con un campo de tipo XMLTYPE denominado
SYS_NC_ROWINFO$.
Para definir una columna o tabla XMLType asociada a un esquema debemos registrar primero el esquema en la
base de datos. Esto se realiza mediante la biblioteca DBMS_XMLSCHEMA que posee dos funciones:
REGISTERSCHEMA para registrar el esquema y DELETESCHEMA para eliminar el registro.
DBMS_XMLSCHEMA.REGISTERSCHEMA ('http://www.oracle.com/empleado.xsd', doc);
DBMS_XMLSCHEMA.DELETESCHEMA ('http://www.oracle.com/empleado.xsd',
DBMS_XMLSCHEMA.DELETE_CASCADE_FORCE);
Una vez registrado el esquema podemos crear columnas y tablas XMLType asociadas haciendo uso del
comando XMLSCHEMA en la definicin:

Oracle /282
-- Para la siguiente definicin de tabla
CREATE TABLE TREmpleado (
id NUMBER(3),
xmlEmpleado XMLTYPE
)
XMLTYPE COLUMN xmlEmpleado XMLSCHEMA "http://www.oracle.com/empleado.xsd"ELEMENT "Empleado";
-- Se asocia el campo "xmlEmpleado" sobre el elemento "Empleado" del esquema
O bien se crea una tabla de tipo XMLType:
CREATE TABLE TXEmpleado OF XMLTYPEXMLSCHEMA "http://www.oracle.com/empleado.xsd"
ELEMENT "Empleado";
-- O bien se utiliza la sintaxis:
CREATE TABLE TXEmpleado OF XMLTYPEELEMENT "http://www.oracle.com/empleado.xsd#Empleado";
2.4. Operaciones con columnas XMLType.
2.4.1. Insertar y actualizar registros con datos XML.
Si tratamos a los tipos XMLType como objetos podemos utilizar el constructor de dichos objetos para
instanciar nuevos elementos XMLType, tomando como parmetro la cadena que representa al documento
XML:
INSERT INTO TREmpleado (id, xmlEmpleado) VALUES(
1,
XMLType('<Empleado><Nombre>Juan</Nombre><Edad>34</Edad><Direccion /></Empleado>')
);
Si queremos actualizar el campo debemos proporcionar un nuevo documento XML entero:
UPDATE TREmpleado
SET xmlEmpleado = XMLType('<Empleado><Nombre>Juan</Nombre><Edad>34</Edad><Direccion /></Empleado>')
WHERE id = 1;
Tambin podemos hacer uso de los comandos SQLX para generar el documento XML en vez del
constructor de XMLType, tal como veremos en un apartado posterior.
2.4.2. Consultar registros con datos XML.
Es posible recuperar un documento XML de un registro en forma de CLOB, VARCHAR2 o NUMBER mediante
los mtodos de XMLType: getClobVal(), getStringVal(), y getNumberVal(). Con estas funciones simplemente
obtenemos el documento XML convertido en un tipo nativo de Oracle.
El siguiente ejemplo obtiene el contenido del campo xmlEmpleado como un valor de tipo CLOB:
SELECT e.xmlEmpleado.getClobval() AS "EmpleadoXML"
FROM TREmpleado e
WHERE e.id = 1;
Tambin es posible recuperar partes del documento y efectuar predicados de seleccin en partes del
documento. Estas partes se basan en la estructura DOM de XML y se sealan haciendo uso de expresiones
XPath. Las funciones incluidas con este propsito son extract, extractValue y existsNode: las dos primeras
devuelven el nodo del documento XML (de la estructura DOM) solicitado y la tercera devuelve verdadero ( 1)
cuando existe el nodo solicitado o falso (0) si no existe.
En el siguiente ejemplo se hace una consulta a la tabla relacional TREmpleado para obtener el nodo Empleado de
aquellos empleados cuyo nombre sea "Juan":
SELECT e.xmlEmpleado.getStringVal() AS EmpleadoXML
FROM TREmpleado e
WHERE e.xmlEmpleado.existsNode('/Empleado [Nombre = "Juan"]') = 1;
Siendo el resultado (se muestra un registro):
EmpleadoXML
--------------------------------
<Empleado><Nombre>Juan</Nombre><Edad>34</Edad><Direccion /></Empleado>
En el siguiente ejemplo se hace una consulta para obtener el id y el nodo Direccion de aquellos empleados en
la tabla relacional TREmpleado que tengan asignado el campo xmlEmpleado, y lo convertimos en una cadena (si
no sera un XMLType):
SELECT e.id ,EXTRACT(e.xmlEmpleado, '/Empleado/Direccion').getStringVal()AS "Direccin"
FROM TREmpleado e
WHERE e.xmlEmpleado IS NOT NULL;
Un resultado posible podra ser (se muestran dos registros):

Oracle /283
id Direccin
---- -------------------------------------------------------------------------------------
1 <Direccion />
2 <Direccion><Calle>La Ronda></Calle><Ciudad>La Corua</Ciudad></Direccion>
La funcin extract() siempre devuelve el nodo en formato XMLType; si queremos recuperar el valor de un
nodo final podemos utilizar getNumberVal() o getStringVal() sobre el elemento XMLType devuelto. O bien
podemos utilizar extractValue(), que tiene una sintaxis idntica a extract() pero que devuelve el valor del nodo
de texto y no el elemento XMLType. Estas funciones slo son vlidas para nodos que tengan un solo y nico
nodo de texto.
Por ejemplo, si queremos recuperar el nombre del empleado de id 1 podemos usar una de las dos consultas
siguientes:
SELECT EXTRACT(e.xmlEmpleado, '/Empleado/Nombre/text()').getStringVal() AS "Nombre"
FROM TREmpleado e
WHERE e.id = 1;
/
SELECT EXTRACTVALUE(e.xmlEmpleado, '/Empleado/Nombre').getStringVal() AS "Nombre"
FROM TREmpleado e
WHERE e.id = 1;
2.4.3. Borrar registros con datos XML.
El borrado de registros que contienen columnas de tipo XMLType es similar a borrar registros con cualquier
otro tipo de datos.
Por ejemplo, para eliminar los registros con la ciudad Madrid, ejecutaremos el siguiente comando:
DELETE FROM TREmpleado
WHERE e.xmlEmpleado.extractValue('/Empleado/Direccion/Ciudad')='Madrid';
En esta consulta se supone que cada empleado posee una nica direccin. En caso contrario la funcin
extractValue() producira un error.
2.4.4. Actualizar datos XML.
La funcin updateXML() permite actualizar el contenido de un objeto de tipo XMLType retornando un nuevo
XMLType. Tiene tres parmetros:
- El objeto XMLType que queremos modificar.
- Una expresin XPath que estable el o los elementos que queremos modificar.
- Una expresin que ser utilizada para hacer la sustitucin.
Gracias a esta funcin podemos evitar modificar todo el documento XML cuando slo vare una parte. Por
ejemplo, el siguiente comando modifica la edad de todos los empleados de la tabla TREmpleado al valor 33:
UPDATE TREmpleado
SET xmlEmpleado = UPDATEXML(xmlEmpleado,'/Empleado/Edad/text()', '33');
Es importante notar que, efectivamente, no se modifica un nico nodo Edad, sino que el valor de cada nodo
Edad de empleado es modificado al valor 33.
Si actualizamos un elemento XML a valor null, Oracle elimina los atributos y elementos hijos del mismo, y
entonces el elemento queda vaco. Pero el elemento no desaparece como tal, y retiene sus propiedades de tipo
y espacio de nombres. Un valor null para un elemento actualizado es equivalente a asignar un elemento vaco.
Si actualizamos un nodo de texto de un elemento a null, Oracle quita el valor quedando el elemento vaco.
Asignar un atributo a null es similar a poner el valor del atributo a un string vaco.
Si aplicamos la funcin:
updateXML(xmlEmpleado,'/Empleado/Direccion',null)
Obtenemos:
Valor original en el campo xmlEmpleado Nuevo valor tras la actualizacin
<Empleado> <Empleado>
<Nombre>Juan</Nombre> <Nombre>Juan</Nombre>
<Edad>33</Edad> <Edad>33</Edad>
<Direccion> <Direccion />
<Calle>333</Calle> </Empleado>
<Ciudad>Nueva York</Ciudad>
</Direccion>
</Empleado>

Oracle /284
Por tanto no se puede utilizar updateXML() de forma directa para aadir o eliminar elementos o atributos del
documento. Para ello se debe actualizar el contenido del documento a un nuevo valor.
Supongamos, por ejemplo, que queremos aadir una nueva direccin al empleado de cdigo 1. Podemos
obtener la lista de nodos de direccin mediante la funcin extract() y concatenarle la nueva direccin. A
continuacin se puede utilizar la funcin UpdateXml() para cambiar el contenido antiguo por el nuevo.
El siguiente comando aade un nuevo nodo de direccin al empleado de id 1:
UPDATE TREmpleado
SET xmlEmpleado = UPDATEXML(xmlEmpleado,
'/Empleado/Direccion',
EXTRACT(xmlEmpleado, '/Empleado/Direccion') || '<Direccion />' )
WHERE id = 1;
Y el resultado es:
Valor original en el campo xmlEmpleado Nuevo valor tras la actualizacin
<Empleado> <Empleado>
<Nombre>Juan</Nombre> <Nombre>Juan</Nombre>
<Edad>33</Edad> <Edad>33</Edad>
<Direccion> <Direccion>
<Calle>333</Calle> <Calle>333</Calle>
<Ciudad>Nueva York</Ciudad> <Ciudad>Nueva York</Ciudad>
</Direccion> </Direccion>
</Empleado> <Direccion />
</Empleado>
Pero aunque esto funciona, CUIDADO! Si volvisemos a ejecutar nuevamente este comando obtendramos
un resultado no esperado donde se duplicaran las direcciones existentes ms la nueva. Esto es as porque la
primera vez slo exista un nodo Direccin y por tanto era sustituido por s mismo ms la nueva direccin
concatenada. La segunda vez ya existen dos nodos Direccion, y la sustitucin se realiza por cada nodo que
retorna la expresin Xpath '/Empleado/Direccion'. Este problema se resolvera si encapsulamos los nodos
Direccion en un nico nodo Direcciones, tal como se muestra a continuacin:
UPDATE TREmpleado
SET xmlEmpleado = UPDATEXML(xmlEmpleado,
'/Empleado/Direcciones', '<Direcciones>' ||
EXTRACT(xmlEmpleado, '/Empleado/Direcciones/Direccion') || '<Direccion />' ||
' </Direcciones>' )
WHERE id = 1;
Y el resultado es:
Valor original en el campo xmlEmpleado Nuevo valor tras la actualizacin
<Empleado> <Empleado>
<Nombre>Juan</Nombre> <Nombre>Juan</Nombre>
<Edad>33</Edad> <Edad>33</Edad>
<Direcciones> <Direcciones>
<Direccion> <Direccion>
<Calle>333</Calle> <Calle>333</Calle>
<Ciudad>Nueva York</Ciudad> <Ciudad>Nueva York</Ciudad>
</Direccion> </Direccion>
<Direcciones> <Direccion />
</Empleado> </Direcciones>
</Empleado>
Si queremos eliminar una direccin, podemos obtener la lista de direcciones mediante extract() aplicando una
seleccin slo sobre las que queremos conservar. Por ejemplo, si queremos eliminar la ltima direccin
podemos realizar la siguiente actualizacin:
UPDATE TREmpleado
SET xmlEmpleado = UPDATEXML(xmlEmpleado,
'/Empleado/Direccion','<Direcciones>' ||
EXTRACT(xmlEmpleado, '/Empleado/Direcciones/Direccion [not (position() = last())]') ) ||
'</Direcciones>'
WHERE id = 1;

Oracle /285
Y el resultado es:
Valor original en el campo xmlEmpleado Nuevo valor tras la actualizacin
<Empleado> <Empleado>
<Nombre>Juan</Nombre> <Nombre>Juan</Nombre>
<Edad>33</Edad> <Edad>33</Edad>
<Direcciones> <Direcciones>
<Direccion> <Direccion>
<Calle>333</Calle> <Calle>333</Calle>
<Ciudad>Nueva York</Ciudad> <Ciudad>Nueva York</Ciudad>
</Direccion> </Direccion>
<Direccion> </Direcciones>
<Calle>444</Calle> </Empleado>
<Ciudad>Boston</Ciudad>
</Direccion>
</Direcciones>
</Empleado>
2.4.5. Aplicar hojas de estilo XSTL.
Otra forma de modificar un documento XML es utilizando una hoja de estilo XSLT y la funcin
XMLTransform(). El comando XMLTransform() toma como parmetros dos instancias de XMLtype, siendo la
primera el documento origen y la segunda un documento XSLT de transformaciones XML, y devuelve el
documento resultante de la transformacin. Un sinnimo de este comando es el mtodo Transform() de la
clase XMLType.
Como ejemplo, supongamos la siguiente tabla:
CREATE TABLE testxml (xml XMLType);
Insertamos un registro:
INSERT INTO testxml VALUES (XMLType('<a><b>1</b><b>2</b></a>'));
Tras la insercin, el contenido de la tabla es el siguiente:
XML
-----------------
<a><b>1</b><b>2</b></a>
Ahora aplicamos una transformacin, de forma que se eliminan las etiquetas <b> y sus valores se concatenan
como valor de la etiqueta <a>.
SELECT XMLTransform(x.xml, XMLType(
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="a">
<a><xsl:apply-templates/></a>
</xsl:template>
</xsl:stylesheet>'
)) AS xml FROM testxml x;
El resultado es:
XML
-----------------
<a>12</a>
Otra forma de aplicar la transformacin es con la funcin Transform():
SELECT x.xml.transform(XMLType( . . . )) AS xml FROM testxml x;
Las funciones Transform() retornan un valor XMLType; esto quiere decir que el resultado de la transformacin
debe ser un documento o parte de un documento XML bien formado.
2.5. Validar los documentos XML sobre un esquema.
Es posible validar documentos XML frente a esquemas XML mediante el comando XMLisValid() y el mtodo
de XMLType, isSchemaValidated(). Ambos devuelven verdadero (1) si el documento se valida correctamente. El
siguiente ejemplo valida cada documento de la columna xmlEmpleado de la tabla TREmpleado con el esquema
dado devolviendo 1 (verdadero) cuando la validacin es correcta y 0 (falso) cuando no:
SELECT e.xmlEmpleado.isSchemaValid('http://www.oracle.com/empleado.xsd','Empleado')
FROM TREmpleadoe;

Oracle /286
2.6. Indexar elementos XMLType.
Para acelerar las consultas en los tipos XMLType podemos utilizar ndices basados en funcin, para acelerar las
funciones extract() o existsNode() en rutas XPath definidas, como por ejemplo:
CREATE INDEX ciudad_index ON TREmpleado(xmlEmpleado.extract('//Ciudad/text()').getStringVal());
CREATE BITMAP INDEX direccion_index ON TREmpleado(xmlEmpleado.existsNode('//Direccion'));
Para los documentos XMLType mapeados, el ndice a utilizar para acelerar las consultas con parmetros o rutas
XPath es CTXSYS.CTXXPATH:
CREATE INDEX xml_idx ON TREmpleado(xmlEmpleado) INDEXTYPE IS CTXSYS.CTXXPATH;
Sin embargo, si quisiramos ms flexibilidad y funcionalidad de un ndice para los documentos XML sin
esquema deberamos utilizar "Oracle Text", que se utiliza en columnas tipo CLOB o VARCHAR y que en la
ltima versin de Oracle se ha extendido para utilizar XMLType. Para crear un ndice de "Oracle Text" en la
columna xmlEmpleado de la tabla TREmpleado:
CREATE INDEX emp_text_index ON TREmpleado(xmlEmpleado) INDEXTYPE IS CTXSYS.CONTEXT;
El tipo de ndice utilizado es CTXSYS.CONTEXT, que es apropiado para predicados y consultas de "Oracle
Text" como CONTAINS, SCORE, INPATH, HASPATH. Si queremos acelerarlas consultas con las funciones
extract() y existsNode() debemos utilizar el ndice CTXSYS.CTXXPATH.
Cuando trabajemos con las opciones de secciones de "Oracle Text" debemos definir cmo se crean estas
secciones. Las secciones son partes del documento a las que referenciaren las bsquedas, como son por
ejemplo los nodos de cada documento XML. Las secciones permiten restringir las bsquedas a ciertas partes
del documento.
El predicado de bsqueda de "Oracle Text" es CONTAINS(), que toma 2 parmetros: el primero es la columna
donde efectuar la bsqueda y el segundo es el predicado a cumplir por el documento. Por cada fila devuelta
CONTAINS() devuelve el porcentaje entre 0 y 100 de relevancia del documento.
SELECT id FROM mi_tabla
WHERE CONTAINS (mi_columna, 'ingresos') > 0
Si el documento esta dividido por secciones (en el modo de secciones de "Oracle Text"
AUTO_SECTION_GROUP, las secciones se crean automticamente con las etiquetas [y se las referencia: etiqueta]
y atributos XML [y se las referencia: etiqueta@atributo]) nos es posible restringir la bsqueda a una seccin en
particular. En el siguiente ejemplo se busca ingresos en el atributo titulo de la etiqueta informe:
SELECT id FROM mi_tabla
WHERE CONTAINS (mi_columna,'ingresos WITHIN informe@titulo') > 0
El operador INPATH es muy parecido a WITHIN pero ha sido incluido para dar soporte a documentos XML.
Su sintaxis es igual pero la ruta de seccin ya no es del tipo etiqueta o etiqueta@atributo, si no que se utiliza
XPath para referirse a cada nodo del documento. El operador HASPATH busca qu documentos tienen la ruta
especificada en XPath como parmetro.
SELECT id FROM catalogo
WHERE CONTAINS(text,'caja INPATH(pedido/item)') > 0;
SELECT id FROM catalogo
WHERE CONTAINS(text,'HASPATH(pedido/item)') > 0;
2.7. SQLX, generar XML de los datos relacionales.
Al igual que en el modelado objeto-relacional, en el que no es necesario convertir los datos del modelo plano
relacional al modelo objeto-relacional para trabajar con ellos en este ltimo modelo, es posible mediante
comandos y vistas representar datos del modelo relacional u objeto-relacional como documentos XML sin
necesidad de modificarlos.
Oracle soporta cinco comandos del estndar SQLX (SQL para XML, SQL/XML) para la representacin de
datos relacionales con XML: XMLElement(), XMLForest(), XMLConcat(), XMLAttributes() y XMLAgg(). Tambin
soporta XMLColAttVal() como comando SQLX propio, pero an no es aceptado en el estndar. Estos
comandos permiten representar datos como un documento XML definiendo nosotros la estructura de ese
documento.
Oracle, adems, soporta las funciones SYS_XMLGEN.SYS_XMLAGG(), XMLSEQUENCE() y XMLFormat con el
mismo propsito que las anteriores pero sin ser parte del estndar SQLX o de su propuesta.
Nos es posible tambin crear vistas del tipo XMLType para representar tablas y vistas relacionales como
documentos XML de forma transparente para la consulta, como si de una consulta a un XMLType se tratase.
2.7.1. Funciones SQLX.
XMLElement() es una funcin que devuelve un tipo XMLType dados como parmetros el nombre del elemento

Oracle /287
XML, una serie de atributos y el contenido del nodo. El XMLType devuelto es un nodo con el nombre del
primer parmetro, los atributos del segundo y el contenido de los ltimos parmetros. El contenido puede ser
un valor o un nuevo elemento XMLType para poder formar la estructura anidada de los documentos XML.
Los atributos se definen mediante la funcin XMLAttributes() que toman como mtodo el listado de atributos
a asignar al elemento XML. Si no se especifica la clusula AS en cada atributo se toma como nombre de
atributo el inferido de la estructura relacional, y si se utiliza AS se toma el indicado.
Supongamos la siguiente tabla relacional:
CREATE TABLE TEmpleado (
id INTEGER PRIMARY KEY,
fecha DATE,
fnombre VARCHAR2(100),
lnombre VARCHAR2(100),
dept VARCHAR2(20),
jubila DATE );
La instruccin siguiente muestra el contenido de esta tabla en formato XML:
SELECT XMLELEMENT("Empleado",
XMLATTRIBUTES (e.id,e.fecha AS "fechaNacimiento"),
XMLELEMENT("nombre", e.fnombre ||''|| e.lnombre),
XMLELEMENT("jubilacion", e.jubila)) AS "result"
FROM TEmpleado e
WHERE id > 200 ;
Donde el resultado puede ser algo como esto (se muestra un nico registro):
result
---------------------------------------------------------------
<Empleado id="200" fechaNacimiento="13-07-1951">
<nombre>Juan Martn</nombre>
<jubilacion>24-05-2000</jubilacion>
</Empleado>
La funcin XMLForest() crea un rbol XML de los parmetros que toma. Un rbol XML son nodos situados a
la misma altura, es decir, nodos que partiran del mismo nodo raz, salvo que no definimos este nodo raz.
Cuando el parmetro se acompaa de la clusula AS se utiliza ste como nombre del elemento XML, cuando
no, se infiere de la estructura de los datos. El siguiente es un ejemplo de XMLElement() para crear el nodo raz
y de XMLForest() para crear los elementos de este nodo:
SELECT XMLELEMENT("Empleado",
XMLATTRIBUTES ( e.fnombre ||''|| e.lnombre AS "nombre" ),
XMLForest ( e.jubila, e.dept AS "departamento")) AS "result"
FROM TEmpleado e;
Donde el resultado puede ser algo como esto (se muestran dos registros):
result
--------------------------------------------------
<Empleado nombre="Juan Gmez"><jubila>24-05-2000</jubila><departamento>Finanzas</departamento></Empleado>
<Empleado nombre="Mara Martin"><jubila>01-02-1996</jubila><departamento>Ventas</departamento></Empleado>
La funcin XMLConcat(), dados como parmetros una secuencia de elementos XMLType o datos tipo XMLType,
los concatena uno tras otro en el orden en que aparecen como parmetros. Mientras que en XMLForest() los
parmetros son datos relacionales, en XMLConcat() son tipos XMLType:
SELECT XMLCONCAT(XMLELEMENT("primero", e.fnombre),XMLElement("ultimo", e.lnombre))AS "result"
FROM TEmpleado e ;
Donde el resultado puede ser algo como esto (se muestran dos registros):
result
------------------------------------------
<primero>Mara</primero><ultimo>Martin</ultimo>
<primero>Juan</primero><ultimo>Gmez</ultimo>
La funcin XMLAgg() es una funcin de agregado que produce un bosque de elementos XML dada una
coleccin de elementos. Se usa normalmente en consultas con clusulas de agrupacin como GROUP BY, como
se puede ver en el siguiente ejemplo:
SELECT XMLELEMENT("Departamento",
XMLATTRIBUTES ( e.dept AS "nombre" ),

Oracle /288
XMLAGG (XMLELEMENT("emp", e.lnombre))) AS "result"
FROM TEmpleado e
GROUP BY dept;
Donde el resultado puede ser algo como esto (se muestran dos registros):
result
----------------------------------------------
<Departamento nombre="Finanzas"><emp>Lpez</emp><emp>Garca</emp></Departamento>
<Departamento nombre="Ventas"><emp>Gutierrez</emp><emp>Martin</emp></Departamento>
En este ejemplo, la funcin XMLAgg() genera elementos <emp> por cada registro dentro un grupo y los
concatena como un nico XMLType.
La funcin XMLColAttVal() crea un rbol de XML donde cada elemento es de tipo column y posee un atributo
tipo name con el nombre del elemento, especificado por AS en los parmetros o inferido de los datos. El
siguiente es un ejemplo de uso de XMLColAttVal():
SELECT XMLELEMENT("Emp",XMLATTRIBUTES(e.fnombre ||''||e.lnombre AS "nombre" ),
XMLCOLATTVAL ( e.jubila, e.dept AS "departamento")) AS "result"
FROM TEmpleado e;
Donde el resultado puede ser algo como esto (se muestran tres registros):
result
-------------------------------------------------------------
<Emp nombre="Juan Gmez">
<column nombre="Jubilacion">25-05-2000</column>
<column nombre="departamento">Finanzas</column>
</Emp>
<Emp nombre="Mara Lpez">
<column nombre="Jubilacion">01-02-1996</column>
<column nombre="departamento">Ventas</column>
</Emp>
<Emp nombre="Samanta Rojas">
<column nombre="Jubilacion">15-11-1992</column>
<column nombre="departamento">Personal</column>
</Emp>
2.7.2. SYS_Xmlgen, Sys_XmlAgg, XMLSequence y XMLFormat.
La funcin SYS_XMLAGG() permite englobar todos los resultados (con formato XMLType) de una consulta en
un nico valor de tipo XMLType. La etiqueta raz del resultado englobado ser por defecto ROWSET, pero
puede ser cambiada con la funcin XMLFormat().
Como ejemplo, supongamos la siguiente tabla donde se insertan documentos XML con la informacin de
ordenadores:
CREATE TABLE TXOrdenador OF XMLTYPE;
/
INSERT INTO TXOrdenador VALUES(XMLType('<pc><tipo>sobremesa</tipo><marca>Fujitsu</marca></pc>'));
/
INSERT INTO TXOrdenador VALUES(XMLType('<pc><tipo>porttil</tipo><marca>ACER</marca></pc>'));
/
INSERT INTO TXOrdenador VALUES(XMLType('<pc><tipo>sobremesa</tipo><marca>IBM/marca></pc>'));
La siguiente consulta obtiene de cada registro de la tabla TXOrdenador el nodo <marca /> y devuelve un nico
resultado con los nodos concatenados dentro de una etiqueta <marcas />:
SELECT SYS_XMLAGG(EXTRACT(VALUE(T),'/pc/marca'), XMLFORMAT('marcas'))AS "Marcas"
FROM TXOrdenador T;
El resultado sera el siguiente (se muestra un nico registro):
Marcas
----------------------------------------------------------------------------------------------
<marcas><marca>Fujitsu</marca><marca>ACER</marca><marca>IBM/marca></marcas>
Por su parte, la funcin XMLSEQUENCE() devuelve una coleccin (un array variable) de objetos XMLType a
partir de un XMLType. Es decir, toma los nodos hijos directos del XMLType y devuelve un nodo XMLType por
cada uno de ellos en un objeto SYS.XMLSequenceType.
Supongamos la siguiente tabla:

Oracle /289
CREATE TABLE TXPlantilla OF XMLTYPE;
La cual contendr en cada registro la lista de empleados de un departamento. El contenido de un registro se
especifica en el siguiente comando de insercin:
INSERT INTO TXPlantilla VALUES (
'<empleados departamento="Finanzas">
<emp>
<empno>112</empno>
<nombre>Joe</nombre>
<salario>50000</salario>
</emp>
<emp>
<empno>217</empno>
<nombre>Jane</nombre>
<salario>60000</salario>
</emp>
<emp>
<empno>412</empno>
<nombre>Jack</nombre>
<salario>40000</salario>
</emp>
</empleados>' );
El siguiente cdigo PL muestra como obtener los nodos emp del departamento de Finanzas como un array de
valores XMLType:
DECLARE
vEmp XMLSequenceType;
BEGIN
-- Realizo una consulta que obtiene la coleccin de nodos <emp /> y la asigna en vEmp
SELECT XMLSEQUENCE(EXTRACT(VALUE(P), '/empleados/emp')) INTO vEmp
FROM TXPlantilla P
WHERE EXTRACTVALUE(VALUE(P),'/empleados/@departamento')='Finanzas';
-- Muestro el contenido del varray vEmp
FOR I IN vEmp.First()..vEmp.Last() LOOP
DBMS_OUTPUT.PUT_LINE( vEmp(I).getStringVal() );
END LOOP;
END;
El tipo SYS.XMLSequenceType es un tipo de VArray predefinido en Oracle cuyos elementos son de tipo
XMLType.
Si ahora quisiramos realizar una consulta que muestre los datos de cada empleado del departamento de
Finanzas como si se tratase de una tabla relacional, podemos usar la funcin TABLE() para convertir la
coleccin que devuelve XmlSequence en un origen de datos vlido para la clusula FROM:
SELECT EXTRACTVALUE(VALUE(T), '/emp/empno') AS "Nmero de empleado" ,
EXTRACTVALUE(VALUE(T), '/emp/nombre') AS "Nombre de empleado" ,
EXTRACTVALUE(VALUE(T), '/emp/salario') AS "Salario de empleado" ,
FROM TABLE(
(SELECT XMLSEQUENCE(EXTRACT(VALUE(P), '/empleados/emp'))FROM TXPlantilla P
WHERE EXTRACTVALUE(VALUE(P),'/empleados/@departamento')='Finanzas' )) T;
El resultado sera:
Nmero de empleado Nombre de empleado Salario de empleado
----------------------- ----------------------- ----------------------
112 Joe 50000
217 Jane 60000
412 Jack 40000
Por su parte, la funcin SYS_XMLGEN() toma un tipo nativo, un tipo abstracto o un tipo XMLType y genera
con l un documento XML. Si es un tipo nativo, forma una etiqueta con el valor dentro, si es un tipo
abstracto mapea los atributos del tipo abstracto a un documento XML y si es un XMLType engloba a este
elemento en otro elemento de nombre por defecto ROW. Es posible indicar el nombre de la etiqueta principal
del documento XML generado mediante la funcin XMLFormat().

Oracle /290
Supongamos el tipo de objeto CLIENTE_T, y una tabla asociada TRCliente donde se insertan varios registros:
CREATE TYPE CLIENTE_T AS OBJECT (
cod INT, nombre VARCHAR2(150)
);
/
CREATE TABLE TRCliente OF CLIENTE_T (cod PRIMARY KEY);
/
INSERT INTO TRCliente VALUES(1, 'Roberto Prez');
/
INSERT INTO TRCliente VALUES(2, 'Marisa Rubn');
/
INSERT INTO TRCliente VALUES(3, 'Adrin Martnez');
La siguiente consulta recupera todos los nombres de cliente como un documento XML:
SELECT SYS_XMLGEN( nombre ) AS "Cliente" FROM TRCliente;
El resultado sera el siguiente (se muestran tres registros):
Cliente
----------------------------------------------
<NOMBRE>Roberto Prez</NOMBRE>
<NOMBRE>Marisa Rubn</NOMBRE>
<NOMBRE>Adrin Martinez</NOMBRE>
Si ahora aplicamos la funcin sobre los registros como objetos:
SELECT SYS_XMLGEN( VALUE(T),XMLFORMAT('CLIENTE')) AS "Cliente" FROM TRCliente T;
Se obtiene (se muestran tres registros):
Cliente
----------------------------------------------
<CLIENTE><COD>1</COD><NOMBRE>Roberto Prez</NOMBRE></CLIENTE>
<CLIENTE><COD>2</COD><NOMBRE>Marisa Rubn</NOMBRE></CLIENTE>
<CLIENTE><COD>3</COD><NOMBRE>Adrin Martinez</NOMBRE></CLIENTE>
La funcin XMLFormat()puede ser un parmetro de SYS_XMLGEN() y SYS_XMLAGG(). Esta funcin define las
caractersticas del documento generado por estas dos funciones mediante sus atributos. Si queremos cambiar
el formato del documento XML generado tan solo tendremos que darle el valor adecuado al correspondiente
parmetro de XMLFormat(). Los parmetros ms importantes son:
enclTag. Es el nombre de la etiqueta que engloba el documento.
vschemaType. Indica si el documento est validado por un esquema o no, sus valores vlidos son
NO_SCHEMA y USE_GIVEN_SCHEMA.
schemaName. Nombre del esquema.
targetNameSpace. Namespace del documento.
dburl. URL donde encontrar la definicin de los esquemas, si no se declara se consideran relativos al
documento.
2.8. Vistas XMLType.
Las vistas XMLType nos permiten tomar elementos relacionales u objeto-relacionales de la base de datos y sin
modificar ni los datos ni su estructura poder mostrarlos como si documentos XML fuesen.
En la forma habitual, se crea una vista indicando que es de tipo XMLType (OF XMLTYPE):
-- Tabla relacional:
CREATE TABLE TInquilino (
idNUMBER(4),
fnombreVARCHAR2(20),
lnombreVARCHAR2(20),
alquiler DATE,
precio NUMBER(6));
/
-- Vista de XMLType:
CREATE OR REPLACE VIEW VInquilino OF XMLTYPE
WITH OBJECT ID (EXTRACT(sys_nc_rowinfo$,'/inquilino/@id').getNumberVal())AS
SELECT XMLELEMENT(
"inquilino",

Oracle /291
XMLAttributes(id),
XMLForest(T.fnombre ||''|| T.lnombre AS "nombre", T.alquiler AS "fechaAlquilier")) AS "result"
FROM TInquilino T
WHERE precio> 20000;
La clusula OBJECT ID indica que id ser el identificador nico de cada elemento y que el tipo XMLType se
almacenar en la columna sys_nc_rowinfo$. Y creamos la vista mediante las funciones SQLX y de Oracle
vistas en el apartado anterior.
Si ahora insertamos datos en la tabla relacional y los consultamos mediante la vista:
INSERT INTO TInquilino VALUES (2100, 'John', 'Smith', '24-05-2000', 30000);
/
INSERT INTO TInquilino VALUES (2200, 'Mary', 'Martin', '01-02-1996', 30000);
/
SELECT * FROM VInqulino;
Obtendremos:
SYS_NC_ROWINFO$
------------------------------------------------------------
<inquilino id="2100">
<nombre>John Smith</nombre>
<fechaAlquiler>24-05-2000</fechaAlquiler>
</inquilino>
<inquilino id="2200">
<nombre>Mary Martin</nombre>
<fechaAlquiler>01-02-1996</fechaAlquiler>
</inquilino>
Tambin es posible crear vistas XMLType mapeando los datos relacionales mediante un esquema y no con el
comando SELECT de la definicin de la vista. El esquema define el mapeado de cada elemento a la columna de
datos mediante el atributo xdb:SQLName en el elemento del esquema, de tal manera que el elemento contendr
el valor de la columna indicada en ese atributo.
Usaremos los siguientes tipos de objetos:
CREATE OR REPLACE TYPE Departamento_t AS OBJECT (
deptno NUMBER(2),
nombre VARCHAR2(14),
lugar VARCHAR2(13));
/
CREATE OR REPLACE TYPE Empleado_t AS OBJECT (
empno NUMBER(4),
nombre VARCHAR2(10),
trabajo VARCHAR2(9),
salario NUMBER(7,2),
departamento Departamento_t);
Y las siguientes tablas relacionales:
CREATE TABLE TRDepartamento (
deptno NUMBER(2) PRIMARY KEY,
nombre VARCHAR2(14),
lugar VARCHAR2(13));
/
CREATE TABLE TREmpleado (
empno NUMBER(4) PRIMARY KEY,
nombre VARCHAR2(10),
trabajo VARCHAR2(9),
salario NUMBER(7,2),
deptno NUMBER(2) REFERENCES TRDepartamento(depno));
El esquema es el siguiente y en l podemos comprobar cmo cada columna de los tipos Empleado_t y
Departamento_t es mapeada a un elemento del documento XML. La estructura del documento XML tambin
es definida por el esquema:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp.xsd"
version="1.0"

Oracle /292
xmlns:xdb="http://xmlns.oracle.com/xdb"
elementFormDefault="qualified">
<element name = "Empleado" xdb:SQLType="Empleado_t" xdb:SQLSchema="SCOTT">
<complexType>
<sequence>
<element name = "EmpleadoId" type = "positiveInteger"
xdb:SQLName="empno" xdb:SQLType="NUMBER"/>
<element name = "Nombre" type = "string" xdb:SQLName="nombre"
xdb:SQLType="VARCHAR2"/>
<element name = "trabajo" type = "string" xdb:SQLName="trabajo"
xdb:SQLType="VARCHAR2"/>
<element name = "Salario" type = "positiveInteger" xdb:SQLName="salario"
xdb:SQLType="NUMBER"/>
<element name = "Departamento" xdb:SQLName="departamento" xdb:SQLType="Departamento_t"
xdb:SQLSchema="SCOTT">
<complexType>
<sequence>
<element name = "DeptNo" type = "positiveInteger"
xdb:SQLName="deptno" xdb:SQLType="NUMBER"/>
<element name = "DeptNombre" type = "string" xdb:SQLName="nombre"
xdb:SQLType="VARCHAR2"/>
<element name = "Lugar" type = "string" xdb:SQLName="lugar"
xdb:SQLType="VARCHAR2"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
A continuacin podemos crear la vista de la siguiente manera:
CREATE OR REPLACE VIEW Empleado_xml OF XMLTYPE
XMLSCHEMA "http://www.oracle.com/emp.xsd"
ELEMENT "Empleado"
WITH OBJECT ID (EXTRACTVALUE(sys_nc_rowinfo$, '/Empleado/EmpleadoId'))
AS
SELECT Empleado_t(e.empno, e.enombre, e.trabajo, e.salario, Departemento_t(d.deptno, d.nombre, d.lugar))
FROM TREmpleado e JOIN TRDepartamento d USING (deptno);
La consulta tendra como respuesta el siguiente documento XML:
<Empleado xmlns="http://www.oracle.com/emp.xsd"
xmlns:xsi="http://www.oracle.com/emp.xsd http://www.oracle.com/emp.xsd">
<EmpleadoId>2100</EmpleadoId>
<Nombre>John</Nombre>
<Salario>123003</Salario>
<Departamento>
<Deptno>2000</Deptno>
<DeptNombre>Sports</DeptNombre>
<Lugar>San Francisco</Lugar>
</Departamento>
</Empleado>

Oracle /293
VI. PROCEDIMIENTOS DE GESTIN DE LA BASE DE DATOS.

1. Diccionario de datos de Oracle


El diccionario de datos de Oracle almacena toda la informacin que es usada para controlar todos los objetos
de una base de datos. Aunque el diccionario de datos es normalmente el dominio de los administradores de
base de datos (DBA's), tambin es una fuente de informacin valiosa para programadores y usuarios finales.
En este captulo veremos el diccionario de datos desde la perspectiva de un usuario final. Con algunas
excepciones, los nombres de los objetos en el diccionario de datos de Oracle comienzan con uno de los
siguientes prefijos: USER_, ALL_ o DBA_. Los registros en la vistas USER_ muestran normalmente informacin
acerca de los objetos propiedad de la cuenta que realiza la consulta. Los registros en las vistas ALL_ incluyen
los registros USER_ ms informacin acerca de los objetos sobre los que se posee el permiso PUBLIC. Las
vistas DBA_ incluyen todos los objetos de base de datos, independientemente de su propietario. Existen vistas
USER_TipoObjeto, ALL_TipoObjeto y DBA_TipoObjeto para la mayora de objetos de base de datos.
1.1. Las vistas DICTIONARY (DICT) y DICT_COLUMNS.
Las descripciones de todos los objetos que constituyen el diccionario de datos son accesibles a travs de una
vista llamada DICTIONARY. Esta vista, tambin accesible con el sinnimo pblico DICT, consulta la base de
datos para determinar qu vistas del diccionario de datos podemos ver. Tambin muestra los sinnimos
pblicos para estas vistas.
El siguiente ejemplo consulta DICT para obtener los nombres de todas las vistas del diccionario de datos
cuyos nombres incluyen el trmino 'VIEWS'. Haciendo la seleccin desde una cuenta de no administrador se
obtiene el siguiente resultado, donde se muestra el nombre y comentario de cada objeto.
SELECT Table_Name, Comments
FROM DICT
WHERE Table_Name LIKE '%VIEWS%'
ORDER BY Table_Name;
TABLE_NAME COMMENTS
----------------------------------- -------------------------------------------------------------------------------
ALL_BASE_TABLE_MVIEWS All materialized views with log(s) in the database that the user can
see
ALL_MVIEWS All materialized views in the database
ALL_REGISTERED_MVIEWS Remote materialized views of local tables that the user can see
ALL_VIEWS Description of views accessible to the user
ALL_XML_VIEWS Description of all XMLType views that the user has privileges on
USER_BASE_TABLE_MVIEWS All materialized views with log(s) owned by the user in the database
USER_MVIEWS All materialized views in the database
USER_REGISTERED_MVIEWS Remote materialized views of local tables currently using logs owned
by the user
USER_VIEWS Description of the user's own views
USER_XML_VIEWS Description of the user's own XMLType views
Podemos consultar las columnas de las vistas del diccionario de datos mediante la vista DICT_COLUMNS.
Como la vista DICTIONARY, DICT_COLUMNS muestra tambin comentarios. DICT_COLUMNS tiene tres
columnas: Table_Name, Column_Name, y Comments. Consultando DICT_COLUMNS podremos determinar cuales
vistas del diccionario de datos sern las ms tiles para nuestras necesidades.
Por ejemplo, si queremos ver el espacio asignado y usado por nuestros objetos de base de datos pero no
estamos seguros de qu vista almacena esta informacin, podemos consultas DICT_COLUMNS, tal como se
muestra en el siguiente ejemplo, el cual mira por todas las tablas del diccionario que tienen una columna
llamada Blocks:
SELECT Table_Name
FROM DICT_COLUMNS
WHERE Column_Name = 'BLOCKS' AND Table_Name LIKE 'USER%'
ORDER BY Table_Name;
TABLE_NAME

Oracle /294
--------------------------------------
USER_ALL_TABLES
USER_EXTENTS
USER_FREE_SPACE
USER_OBJECT_TABLES
USER_SEGMENTS
USER_TABLES
USER_TAB_PARTITIONS
USER_TAB_STATISTICS
USER_TAB_SUBPARTITIONS
USER_TS_QUOTAS
Para listar todos los nombres de columnas disponibles que podramos haber usado en este ltimo ejemplo,
podemos consultar DICT_COLUMNS:
SELECT DISTINCT Column_Name
FROM DICT_COLUMNS
ORDER BY Column_Name;
Siempre que no estemos seguros de dnde encontrar los datos que necesitamos, podemos verificar las vistas
DICTIONARY y DICT_COLUMNS. Si parece que un nmero grande de vistas podran ser tiles consultar
DICTIONARY para ver los comentarios de cada vista.
1.2. Cosas que podemos seleccionar de: tablas (y columnas), vistas, sinnimos y secuencias.
Un catlogo de usuario lista todos aquellos objetos de los cuales el usuario puede seleccionar registros; esto
es, cualquier objeto que puede ser listado en la clusula FROM de una consulta. Aunque las secuencias no
pueden ser referenciadas directamente en la clusula FROM, Oracle las incluye en el catlogo. En esta seccin
veremos cmo recuperar informacin sobre tablas, columnas, vistas, sinnimos, secuencias y el catlogo de
usuario.
1.2.1. Catlogo: USER_CATALOG (CAT)
Consultando la vista USER_CATALOG (o con su sinnimo CAT) podemos ver todas las tablas, vistas, sinnimos
y secuencias propiedad del usuario. La columna Table_Name muestra el nombre del objeto (aunque no sea una
tabla), y la columna Table_Type muestra el tipo del objeto:
SELECT Table_Name, Table_Type
FROM USER_CATALOG
WHERE Table_Name LIKE 'T%';
Hay dos catlogos adicionales disponibles. La vista ALL_CATALOG muestra lo mismo que USER_CATALOG ms
cualquier objeto sobre el que tengamos el permiso PUBLIC. La vista DBA_CATALOG muestra todos los objetos
del catlogo. Adems de las columnas Table_Name y Table_Type mostradas en la consulta de USER_CATALOG,
las vistas ALL_CATALOG y DBA_CATALOG incluyen la columna Owner, que indica el propietario del objeto.
1.2.2. Objetos: USER_OBJECTS (OBJ)
La vista USER_CATALOG slo muestra informacin sobre tablas, vistas, secuencias y sinnimos. Para recuperar
informacin sobre todos los tipos de objetos podemos consultar la vista USER_OBJECTS. Podemos usar esta
vista para encontrar cualquier cosa sobre muchos tipos de objetos, incluidos clsteres, enlaces de base de
datos, directorios, funciones, ndices, libreras, paquetes, cuerpos de paquete, clases Java, tipos de datos
abstractos, recursos, secuencias, sinnimos, tablas, triggers, vistas materializadas, LOB's y vistas. Las
columnas de la vista USER_OBJECTS se describen en la siguiente tabla.
Nombre col. Descripcin
Object_Name El nombre del objeto.
SubObject_Name El nombre del sub-objeto, como un nombre de particin.
Object_ID Un identificador nico de Oracle para el objeto.
Data_Object_ID El nmero de objeto del segmento que contiene los datos del objeto.
Object_Type El tipo de objeto (TABLE, INDEX, TABLE PARTITION, ...).
Created La fecha y hora de creacin del objeto (como una columna DATE).
Last_DDL_Time La fecha y hora en que se us el ltimo comando DDL sobre el objeto, incluidos ALTER,
GRANT y REVOKE.
Timestamp La fecha y hora de creacin del objeto (como Created, pero almacenado como una
columna de caracteres).
Status El estado del objeto (VALID o INVALID).

Oracle /295
Temporary Un indicador de si el objeto es una tabla temporal.
Generated Un indicador de si el nombre del objeto fue generado por el sistema.
Secondary Un indicador de si el objeto es un ndice secundario creado por un ndice de dominio.
USER_OBJECTS (o su sinnimo OBJ) contiene varias piezas vitales de informacin que no se encuentran en
otras vistas del diccionario de datos. Registra las fechas de creacin de los objetos (la columna Created) y la
ltima vez que un objeto fue alterado (la columna Last_DDL_Time). Estas columnas son tiles cuando
intentamos reconciliar diferentes conjuntos de objetos en la misma aplicacin.
Nota. Si recreamos objetos de alguna manera (por ejemplo, usando la utilidad Import), su valor para
la columna Created cambiar a la ltima vez en que fueron creados.
Anlogamente disponemos de las vistas ALL_OBJECTS y DBA_OBJECTS. Estas vistas aaden la columna
Owner.
1.2.3. Tablas: USER_TABLES (TABS)
Aunque todos los objetos de usuario son mostrados en la vista USER_OBJECTS, pocos atributos de estos
objetos se muestran aqu. Para obtener ms informacin sobre un objeto necesitamos mirar la vista que es
especfica para el tipo de objeto. Para las tablas, se usa la vista USER_TABLES (o por su sinnimo TABS).
Nota. Versiones previas de Oracle incluyen una vista llamada TAB. Esta vista, la cual es similar a
TABS, se sigue soportando porque es usada por algunos productos de Oracle. Sin embargo, TAB no
contiene las mismas columnas que TABS. Hay que usar TABS en nuestras consultas al diccionario de
datos.
Las columnas de USER_TABLES pueden dividirse en cuatro categoras (identificacin, relativas al espacio,
relativas a estadsticas, y otras), tal como se muestran en la siguiente tabla.
Columnas de identificacin
Table_Name Nombre de la tabla.
Backed_Up Indica si la tabla fue respaldada desde la ltima modificacin.
Partitioned Indica si la tabla fue particionada (YES o NO).
IOT_Name Nombre de la tabla de slo ndice, si la hay, a la cual el desbordamiento o las
entradas de mapeo pertenecen.
Logging Atributo de logging.
IOT_Type Si es una tabla de solo ndice, entonces es IOT o IOT_OVERFLOW o
IOT_MAPPING, sino es NULL.
Temporary Indica si la sesin actual puede ver solo los datos puesto en este mismo objeto.
Nested Indica si es una tabla anidada.
Secondary Indica si la tabla fue creada como parte de la creacin de ndices de dominio.
Columnas relativas al espacio
Tablespace_Name Nombre del tablespace que contiene la tabla.
Cluster_Name Nombre del clster, si lo hay, en el cual la tabla est contenido.
Pct_Free Mnimo porcentaje de espacio libre en un bloque.
Pct_Used Mnimo porcentaje de espacio usado en un bloque.
Ini_Trans Nmero inicial de transacciones.
Max_Trans Mximo nmero de transacciones.
Initial_Extent Tamao de la extensin inicial en bytes.
Next_Extent Tamao de la extensin secundaria en bytes.
Min_Extents Mnimo nmero de extensiones permitidas en el segmento.
Max_Extents Mximo nmero de extensiones permitidas en el segmento.
Pct_Increase Porcentaje de incremento en el tamao de las extensiones.
Freelists Nmero de procesos libres asignados en este segmento.
Freelist_Groups Nmero de grupos libres asignados en este segmento.
Columnas relativas a estadsticas
Num_Rows El nmero de filas en la tabla.
Blocks El nmero de bloques usados en la tabla.
Empty_Blocks El nmero de bloques vacos (nunca usados) de la tabla.
Avg_Space El promedio de espacio libre disponible en la tabla.
Chain_Cnt El nmero de filas encadenadas en la tabla.

Oracle /296
Avg_Row_Len El promedio de longitud de filas, incluidas las filas de desbordamiento.
Sample_Size El tamao de la muestra usada en los anlisis de la tabla.
Last_Analyzed La fecha y la hora ms reciente en que la tabla fue analizada.
Avg_Space_Freelist_Blocks El promedio de espacio libre de todos los bloques de una lista libre.
Num_Freelist_Blocks El nmero de bloques de una lista libre.
Global_Stats Indica si las estadsticas se calculan sin combinar particiones subyacentes.
User_Stats Indica si la estadstica fue entrada directamente por el usuario.
Otras columnas
Degree El nmero de hilos por instancia para consultas paralelas sobre la tabla.
Instances El nmero de instancias para consultas paralelas sobre la tabla.
Cache Indica si la tabla ha sido almacenada en una cach.
Table_Lock Indica si el bloqueo de tabla est habilitado o deshabilitado.
Buffer_Pool El bfer por defecto que ser usado por los bloques de la tabla.
Row_Movement Indica si el movimiento de fila particionada est permitido o no.
Duration Si es una tabla temporal, entonces es SYS$SESSION o SYS$TRANSACTION,
sino es NULL.
Skip_Corrupt Indica si est habilitado o no saltarse bloques corruptos.
Monitoring Indica si deben registrarse la cantidad de modificaciones.
Cluster_Owner Propietario del clster, si lo hay, al cual pertenece la tabla.
Dependencies Indica si deberamos nosotros guardar la pista de dependencias del nivel de fila.
Dropped Indica si la tabla fue enviada al reciclador (YES) o no (NO).
Compression Indica si la tabla est comprimida (YES) o no (NO).
El nombre de la tabla se muestra en la columna Table_Name. La columna Backed_Up muestra si la tabla ha sido
o no respaldada desde su ltima modificacin. La columna Partitioned tendr el valor 'YES' si la tabla ha sido
particionada.
Las columnas relativas a estadsticas como Num_Rows, Blocks, Empty_Blocks, Avg_Row_Len y Last_Analyzed, son
pobladas cuando la tabla es analizada.
Nota. Desde Oracle Database 10g, podemos usar la vista USER_TAB_STATISTICS para acceder a las
estadsticas de nuestras tablas.
La siguiente consulta lista todas las tablas cuyos nombres empiezan con la letra 'L':
SELECT Table_Name
FROM USER_TABLES
WHERE Table_Name LIKE 'L%';
La vista ALL_TABLES muestra todas lastablas propiedad del usuario as como cualquier otra sobre la que tenga
permisos de acceso. La vista DBA_TABLES lista todas las tablas de la base de datos. Estas dos vistas
incluyen la columna Owner con el nombre del propietario de la tabla.
Nota. Para tablas externas, usar las vistas USER_EXTERNAL_TABLES y USER_EXTERNAL_LOCATIONS.
1.2.4. Columnas: USER_TAB_COLUMNS (COLS)
Aunque los usuarios no consulten por columnas, la vista del diccionario de datos que muestra columnas est
estrechamente ligada a la vista de diccionario de datos de tablas. Esta vista, llamada USER_TAB_COLUMNS,
muestra informacin especfica de las columnas. USER_TAB_COLUMNS tambin puede ser consultada
mediante el sinnimo pblico COLS.
Las columnas que podemos consultar de USER_TAB_COLUMNS pueden ser separadas en tres categoras:
Identificacin, como Table_Name, Column_Name, y Column_ID.
Relativas a la definicin, como Data_Type, Data_Length, Data_Precision, Data_Scale, Nullable, y
Default_Length
Relativas a estadsticas, como Num_Distinct, Low_Value, High_Value, Density, Num_Nulls, y otras.
Las columnas Table_Name y Column_Name contienen los nombres de nuestras tablas y columnas. Las columnas
relativas a estadsticas son pobladas cuando la tabla es analizada. Las columnas para estadsticas son tambin
proporcionadas en la vista USER_TAB_COL_STATISTICS.
Para ver las definiciones de columnas de una tabla podemos consultar USER_TAB_COLUMNS, especificando
Table_Name en la clusula WHERE:
SELECT Column_Name, Data_Type
FROM USER_TAB_COLUMNS

Oracle /297
WHERE Table_Name = 'MI_TABLA';
COLUMN_NAME DATA_TYPE
--------------------- -----------------
CAMPO1 VARCHAR2
CAMPO2 CHAR
CAMPO3 NUMBER
Esta misma informacin tambin se puede obtener mediante SQL*Plus con el comando DESCRIBE; sin
embargo, DESCRIBE no nos da la opcin de ver los valores por defecto de las columnas y las estadsticas.
La vista ALL_TAB_COLUMNS muestra las columnas de todas las tablas y vistas propiedad del usuario as como
cualquier otra sobre los que tenga permisos de acceso. DBA_TAB_COLUMNS muestra las columnas de todas las
tablas y vistas de la base de datos. Ambas vistas aaden la columna Owner indicando el propietario de las
tablas.
Columnas de estadsticas.
Muchas de las columnas de estadsticas estn disponibles tanto en USER_TAB_COLUMNS como en
USER_TAB_COL_STATISTICS. Las columnas disponibles en USER_TAB_COL_STATISTICS son las mismas de
USER_TAB_COLUMNS ms Table_Name y Column_Name.
USER_TAB_COL_STATISTICS contiene columnas de estadsticas que tambin estn en USER_TAB_COLUMNS
para compatibilidad. Deberamos acceder a ellos usando USER_TAB_COL_STATISTICS.
Histogramas de valores de columna.
Podemos usar histogramas para mejorar el anlisis usado por el optimizador. La vista
USER_TAB_HISTOGRAMS contiene informacin acerca de cada histograma de columna: Table_Name,
Column_Name, Endpoint_Number, Endpoint_Value, y Endpoint_Actual_Value. Los valores en
USER_TAB_HISTOGRAMS son usados por el optimizador para determinar la distribucin de los valores de
columna dentro de la tabla.
Tambin estn disponibles las vistas ALL_TAB_HISTOGRAMS y DBA_TAB_HISTOGRAMS.
Columnas actualizables.
Podemos actualizar registros en vistas que contengan un JOIN en su consulta, a condicin de que el JOIN
cumpla ciertos criterios. La vista USER_UPDATABLE_COLUMNS muestra todas las columnas que podemos
actualizar. Para una columna determinada podemos consultar Owner, Table_Name, y Column_Name; la columna
Updatable tendr el valor 'YES' si la columna puede ser actualizada, y el valor 'NO' si la columna no puede ser
actualizada. Podemos tambin consultar las columnas Insertable y Deletable para saber si podemos insertar o
borrar registros mediante la vista.
1.2.5. Vistas: USER_VIEWS
La consulta subyacente de una vista es accesible mediante la vista del diccionario de datos USER_VIEWS, la
cual contiene 10 columnas. Las 3 columnas principales son:
View_Name El nombre de la vista
Text_Length La longitud de la consulta base, en caracteres.
Text La consulta que usa la vista.
La columna Text es de tipo LONG. Esto puede causar problemas cuando consultemos USER_VIEWS mediante
SQL*Plus, porque SQL*Plus trunca los LONG. Sin embargo, el punto en el que ocurre el truncamiento puede
ser cambiado mediante el comando SET LONG. USER_VIEWS proporciona un mecanismo para determinar el
valor apropiado para el punto de truncamiento, tal como se ve en el siguiente ejemplo.
La columna Text_Length muestra la longitud de la consulta subyacente. Por lo tanto, el punto de truncamiento
LONG en SQL*Plus debe asignarse a un valor mayor o igual que el valor de esta columna.
Por ejemplo, lo siguiente muestra una vista llamada Mi_Vista y cuya longitud de texto es de 355:
SELECT View_Name, Text_Length
FROM USER_VIEWS
WHERE View_Name = 'MI_VISTA';
VIEW_NAME TEXT_LENGTH
---------------------- ---------------------
MI_VISTA 355
Ya que la longitud del texto de la vista es de 355 caracteres, podemos usar el comando SET LONG para
incrementar el punto de truncamiento (que por defecto es 80):
SET LONG 355

Oracle /298
Entonces podemos consultar USER_VIEWS para ver el texto de la vista:
SELECT Text
FROM USER_VIEWS
WHERE View_Name = 'MI_VISTA';

Nota. Podemos consultar la definicin de columnas de una vista con USER_TAB_COLUMNS, la


misma vista del diccionario de datos para consultar por tablas.
Si usamos alias para las columnas de nuestra vista, y los alias de columna son parte de la consulta de la vista,
entonces las consultas en el diccionario de datos sobre la vista se simplificarn. Ya que se muestra el texto
entero de la consulta de la vista con USER_VIEWS, los alias de columna se mostrarn.
Podemos crear vistas usando este formato:
CREATE VIEW Cliente_View (Codigo, Nombre) AS
SELECT Id, Apellidos || ', ' || Nombre
FROM Cliente;
Indicando los nombres de columnas en la cabecera del comando CREATE VIEW se previene que una consulta
con USER_VIEWS muestre los alias de las columnas de nuestra vista. El nico medo de ver los nombres de las
columnas de nuestra vista es consultando USER_TAB_COLUMNS.
Para soportar vistas de objetos (vase el captulo "Soporte de objetos y XML"), USER_VIEWS contiene las
siguientes columnas:
Type_Text Tipo de clusula de la vista tipada.
Type_Text_Length Longitud del tipo de clusula de la vista tipada.
OID_Text Clusula WITH OID de la vista tipada.
OID_Text_Length Longitud de la clusula WITH OID de la vista tipada.
View_Type_Owner Propietario del tipo de la vista para la vista tipada
View_Type Tipo para la vista
Anlogamente tambin se dispone de las vistas ALL_VIEWS y DBA_VIEWS.
1.2.6. Sinnimos: USER_SYNONYMS (SYN)
La vista USER_SYNONYMS (o SYN) muestra todos los sinnimos de los que somos propietarios. Las columnas
que incluye son:
Synonym_Name El nombre del sinnimo.
Table_Owner El propietario de la tabla a la que se refiere el sinnimo.
Table_Name El nombre de la tabla a la que se refiere el sinnimo.
DB_Link El nombre del enlace de base de datos usado en el sinnimo.
La vista USER_SYNONYMS es usada depurando programas o resolviendo problemas con accesos de usuario a
objetos dentro de aplicaciones.
La columna DB_Link ser NULL si el sinnimo no usa un enlace de base de datos. Por lo tanto, si queremos
ver una lista de enlaces de base de datos actualmente usados por sinnimos de nuestra cuenta, podemos
ejecutar la siguiente consulta:
SELECT DISTINCT DB_Link
FROM USER_SYNONYMS
WHERE DB_Link IS NOT NULL;
Anlogamente tambin se dispone de las vistas ALL_SYNONYMS y DBA_SYNONYMS.
1.2.7. Secuencias: USER_SEQUENCES (SEQ)
Para mostrar los atributos de secuencias podemos consultar la vista USER_SEQUENCES (o su sinnimo SEQ).
Las columnas de USER_SEQUENCES se describen a continuacin:
Nombre col. Descripcin
Sequence_Name Nombre de la secuencia.
Min_Value Mnimo valor de la secuencia.
Max_Value Mximo valor de la secuencia
Increment_By Incremento entre los valores de la secuencia.
Cycle_Flag Un indicador de si la secuencia es cclica.
Order_Flag Un indicador de si los nmeros de la secuencia son generados en orden.
Cache_Size Nmero de entradas de secuencia en cach.
Last_Number El ltimo nmero de secuencia escrito a disco o en cach.

Oracle /299
La columna Last_Number no es actualizada durante operaciones normales de la base de datos; se usa durante
operaciones de reinicio/recuperacin de la base de datos.
Anlogamente tambin se dispone de las vistas ALL_SEQUENCES y DBA_SEQUENCES.
1.3. Papelera: USER_RECYCLEBIN y DBA_RECYCLEBIN
Desde Oracle Database 10g podemos usar el comando FLASHBACK TABLE para recuperar tablas y objetos
dependientes que han sido borrados. Para ver los objetos presentes en nuestra papelera podemos consultar la
vista USER_RECYCLEBIN (o RECYCLEBIN). Nos mostrar el nombre del objeto original, si puede ser recuperado
(columna Can_Undrop) y su fue borrado porque estaba relacionado con un objeto borrado explcitamente
(columna Base_Object).
Los objetos permanecen en el portapapeles hasta que son purgados. Los objetos pueden ser removidos de la
papelera automticamente sin no hay espacio libre en el tablespace donde fueron borrados.
Los DBA's pueden ver todos los objetos de todas las papeleras mediante la vista DBA_RECYCLEBIN. No hay
una versin ALL_ para esta vista.
1.4. Restricciones y comentarios.
Las restricciones y comentarios ayudan a comprender cmo las tablas y columnas se relacionan entre s. Los
comentarios son estrictamente informacin; no imponen ninguna condicin sobre los datos almacenados en
los objetos que describen. Las restricciones, por otra parte, definen las condiciones bajo las cuales los datos
son vlidos. Restricciones habituales incluyen NOT NULL, UNIQUE, PRIMARY KEY y FOREIGN KEY.
1.4.1. Restricciones: USER_CONSTRAINTS
La informacin de restricciones es accesible mediante la vista USER_CONSTRAINTS. Esta informacin es muy
til cuando intentamos modificar las restricciones sobre datos o resolver problemas con los datos de la
aplicacin. Las columnas de esta vista son las siguientes:
Nombre col. Descripcin
Owner El propietario de la restriccin.
Constraint_Name El nombre de la restriccin.
Constraint_Type El tipo de la restriccin:
'C' para restriccin CHECK; incluye NOT NULL
'P' para restriccin PRIMARY KEY
'R' para restriccin FOREIGN KEY
'U' para restriccin UNIQUE
'V' para restriccin WITH CHECK OPTION (en vistas)
'O' para restriccin WITH READ ONLY (en vistas)
Table_Name El nombre de la tabla asociada con la restriccin.
Search_Condition La condicin de bsqueda usada (para restricciones CHECK)
R_Owner El propietario de la tabla referenciada por la restriccin FOREIGN KEY.
R_Constraint_Name El nombre de la restriccin referenciada por una restriccin FOREIGN KEY.
Delete_Rule La accin a tomar sobre tablas FOREIGN KEY cuando un registro PRIMARY KEY es
borrado (CASCADE o NO ACTION).
Status El estado de la restriccin (ENABLED o DISABLED).
Deferrable Un indicador de si la restriccin puede ser diferida.
Deferred Un indicador de si la restriccin fue inicialmente diferida.
Validated Un indicador (VALIDATED o NOT VALIDATED) de si todos los datos cumplen la
restriccin.
Generated Un indicador de si el nombre de restriccin ha sido generado por la base de datos.
Bad Un indicador de si un dato que fue usado en la creacin de la restriccin sin especificar
un valor de centuria para restricciones CHECK es un ao ambiguo de dos dgitos; se
aplica slo a restricciones en bases de datos actualizadas desde versiones previas.
Rely Un indicador de si la restriccin est forzada o no.
Last_Change La fecha y hora en la que la restriccin fue activada o desactivada.
Index_Owner Propietario de ndice relacionado.
Index_Name Nombre del ndice relacionado.
Invalid Indicador de valido o no vlido.
View_Related Indicador Yes/No para registrar si la restriccin es relativa a una vista.
Aunque es una vista USER_ contiene una columna Owner. En esta vista, Owner hace referencia al propietario

Oracle /300
de la restriccin, y no al propietario de la tabla.
Las restricciones FOREIGN KEY tienen siempre un valor para las columnas R_Owner y R_Constraint_Name. Estas
dos columnas indican las restricciones referenciadas. Una FOREIGN KEY referencia otra restriccin, no otra
columna. Las restricciones NOT NULL sobre columnas son almacenadas en restricciones CHECK, as que tiene el
tipo 'C'.
Consultado USER_CONSTRAINTS obtendremos los nombres de todas las restricciones sobre una tabla. Esto
es importante cuando intentamos interpretar mensajes de error que slo proporcionan el nombre de la
restriccin que fue violada.
Una vez que conocemos el nombre y tipo de la restriccin, podemos verificar las columnas asociadas
mediante la vista USER_CONS_COLUMNS, descrita en la siguiente seccin.
Si no hemos asignado nombre a una restriccin cuando la hemos creado, Oracle genera un nombre nico. Si
la restriccin tiene un nombre generado por el sistema, esto se indicar en la columna Generated.
Si deferimos una restriccin (como se indica en la columna Deferred, la restriccin no ser forzada durante
una transaccin. Por ejemplo, si hemos realizado actualizaciones masivas sobre tablas relacionadas y no
podemos garantizar el orden de las transacciones, podemos decidir diferir la verificacin de la restriccin
sobre las tablas hasta que la actualizacin se ha completado.
Anlogamente tambin se dispone de las vistas ALL_CONSTRAINTS y DBA_CONSTRAINTS.
1.4.2. Restriccin de columnas: USER_CONS_COLUMNS
Podemos ver las columnas asociadas con restricciones mediante la vista USER_CONS_COLUMNS. Si hemos
consultado USER_CONSTRAINTS para obtener los tipos y nombres de las restricciones involucradas, podemos
usar USER_CONS_COLUMNS para determinar qu columnas estn involucradas con la restriccin. Las
columnas de esta vista son las siguientes:
Nombre col. Descripcin
Owner El propietario de la restriccin.
Constraint_Name El nombre de la restriccin.
Table_Name El nombre de la tabla asociada con la restriccin.
Column_Name El nombre de la columna asociada con la restriccin.
Position El orden de la columna dentro de la definicin de la restriccin.
Hay slo dos columnas de USER_CONS_COLUMNS que no estn en USER_CONSTRAINTS: Column_Name y
Position. Una simple consulta de esta tabla se muestra a continuacin:
SELECT Column_Name, Position
FROM USER_CONS_COLUMNS
WHERE Constraint_Name = 'SYS_C0008791';
COLUMN_NAME POSITION
---------------------- ---------------------
NOMBRE 1
APELLIDOS 2
Como se ve en el resultado, la combinacin del nombre y apellidos forman la restriccin (en este caso, una
clave primaria).
La columna Position es significativa. Cuando creamos una restriccin UNIQUE o PRIMARY KEY, Oracle crea
automticamente un ndice nico sobre el conjunto de columnas que especificamos. El ndice es creado segn
el orden de las columnas. El orden de las columnas afecta al rendimiento del ndice. Un ndice sobre varias
columnas puede ser ms eficiente si la primera columna del ndice ( Position=1) es usada en la clusula WHERE
de consultas.
Anlogamente tambin se dispone de las vistas ALL_CONS_COLUMNS y DBA_CONS_COLUMNS.
1.4.3. Excepciones en restricciones: EXCEPTIONS
Cuando activamos restricciones sobre tablas que ya contienen datos, podemos encontrarnos con violaciones
con los datos existentes. Por ejemplo, podemos intentar crear una restriccin PRIMARY KEY sobre una
columna que contiene el mismo valor en varios registros, pero tal tentativa fallara debido a violaciones de
unicidad.
Podemos capturar informacin acerca de las filas que cusan fallos en la creacin de la restriccin. Primero,
crearemos una tabla llamada EXCEPTIONS en nuestro esquema; el script SQL que debemos usar para crear eta
tabla se denomina utlexcpt.sql, y normalmente esta localizado en el directorio /rdbms/admin dentro de la
carpeta de instalacin de Oracle.

Oracle /301
Archivo utlexcpt.sql
rem
rem $Header: utlexcpt.sql,v 1.1 1992/10/20 11:57:02 GLUMPKIN Stab $
rem
Rem Copyright (c) 1991 by Oracle Corporation
Rem NAME
Rem except.sql - <one-line expansion of the name>
Rem DESCRIPTION
Rem <short description of component this file declares/defines>
Rem RETURNS
Rem
Rem NOTES
Rem <other useful comments, qualifications, etc.>
Rem MODIFIED (MM/DD/YY)
Rem glumpkin 10/20/92 - Renamed from EXCEPT.SQL
Rem epeeler 07/22/91 - add comma
Rem epeeler 04/30/91 - Creation

create table exceptions(row_id rowid, owner varchar2(30),


table_name varchar2(30), constraint varchar2(30));
La tabla EXCEPTIONS contiene cuatro columnas: Row_ID (el ROWID de cada fila que viola la restriccin),
Owner (el propietario de la restriccin violada), Table_Name (la tabla en la cual fue creada la restriccin
violada), y Constraint (la restriccin violada por la fila). Despus de crear la tabla EXCEPTIONS, intentaremos
habilitar la restriccin PRIMARY KEY sobre una tabla REVISTA:
ALTER TABLE REVISTAENABLE PRIMARY KEY EXCEPTIONS INTO EXCEPTIONS;
ORA-02437: cannot enable (NEWSPAPER.SYS_C00516) - primary key violated
La creacin de la restriccin falla, y una referencia a todas las filas que violan la restriccin es puesta en la
tabla EXCEPTIONS. Por ejemplo, si la restriccin PRIMARY KEY de este ltimo ejemplo genera una excepcin,
entonces podemos consultar la tabla EXCEPTIONS tal como se muestra a continuacin:
SELECT Owner, Table_Name, Constraint FROM EXCEPTIONS;
OWNER TABLE_NAME CONSTRAINT
------------------- --------------------- --------------------
EMPLEADO REVISTA SYS_C00516
EMPLEADO REVISTA SYS_C00516
Dos filas violan la restriccin llamadaSYS_C00516 (el cual, en este ejemplo, es el nombre de la restriccin
PRIMARY KEY para la tabla REVISTA). Podemos determinar qu filas de la tabla REVISTA se corresponden a
estas excepciones combinando la columna Row_ID de la tabla EXCEPTIONS con la pseudo-columna ROWID de
la tabla sobre la cual se aplic la restriccin:
SELECT *
FROM REVISTA
WHERE RowID IN (SELECT Row_ID FROM EXCEPTIONS);

Nota. Operaciones de flashback y recuperacin pueden cambiar los ROWID de las filas
previamente insertadas dentro de las tablas.
1.4.4. Comentarios de tablas: USER_TAB_COMMENTS
Podemos aadir un comentario a una tabla, vista o columna despus de haber sido creadas. Podemos mostrar
estos comentarios mediante las vistas del diccionario de datos DICTIONARY y DICT_COLUMNS. Para mostrar
comentarios sobre nuestras propias tablas se usa la vista USER_TAB_COMMENTS.
La vista USER_TAB_COMMENTS contiene tres columnas:
Table_Name El nombre de la tabla o vista.
Table_Type El tipo de objeto (TABLE, OBJECT TABLE, o VIEW).
Comments Comentarios asociados al objeto.
Para aadir comentarios a una tabla se usa el comando COMMENT, tal como se muestra a continuacin:
COMMENT ON TABLE Festivos IS 'Fechas con los das festivos de la empresa';
Consultando la vista USER_TAB_COMMENTS especificando Table_Name podemos ver los comentarios, tal

Oracle /302
como se muestra a continuacin:
SELECT Comments
FROM USER_TAB_COMMENTS
WHERE Table_Name = 'Festivos';
COMMENTS
---------------------------------------------------------
Fechas con los das festivos de la empresa
Para borrar un comentario se debe asignar a un string vaco:
COMMENT ON TABLE Festivos IS '';
Podemos ver los comentarios de todas las tablas mediante la vista ALL_TAB_COMMENTS. Esta vista tiene una
columna adicional, Owner, que especifica el propietario de la tabla. La vista DBA_TAB_COMMENTS muestra
todas tablas de la base de datos.
1.4.5. Comentarios de columnas: USER_COL_COMMENTS
La vista USER_COL_COMMENTS muestra los comentarios asociados con las columnas de nuestras tablas. Estos
comentarios son aadidos a la base de datos mediante el comando COMMENT. La vista USER_COL_COMMENTS
contiene tres columnas:
Table_Name El nombre de la tabla o vista.
Column_Name El nombre de la columna.
Comments Comentarios asociados ala columna.
Para aadir un comentario a una columna se usa el comando COMMENT, tal como se muestra a
continuacin:
COMMENT ON COLUMN Festivos.Dia IS 'Da correspondiente al festivo';
Consultado USER_COL_COMMENTS y especificando Table_Name y Column_Name podemos ver los comentarios
para una columnas.
SELECT Comments
FROM USER_COL_COMMENTS
WHERE Table_Name = 'Festivos' AND Column_Name = 'Dia';
Para borrar un comentario hay que asignar un string vaco:
COMMENT ON COLUMN Festivos.Dia IS '';
Tambin disponemos de las vistas anlogas ALL_COL_COMMENTS y DBA_COL_COMMENTS.
1.5. ndices y clsteres.
Los ndices y clsteres no cambian los datos almacenados en las tablas; sin embargo, cambian el modo en que
los datos son accedidos y almacenados.
1.5.1. ndices: USER_INDEXES (IND)
En Oracle, los ndices estn muy relacionados con las restricciones. Las restricciones PRIMARY KEY y UNIQUE
siempre tienen asociados ndices de unicidad. Hay dos vistas del diccionario de datos para consultar
informacin sobre los ndices: USER_INDEXES(o IND) y USER_IND_COLUMNS.
Las columnas de USER_INDEXES pueden ser agrupadas en cuatro categoras, tal como se muestra en la
siguiente tabla.
Columnas de identificacin
Indexe_Name Nombre del ndice.
Table_Owner Propietario de la tabla asociada con el ndice.
Table_Name Nombre de la tabla asociada con el ndice.
Table_Type
Uniqueness
Status
Partitioned
Index_Type
Temporary
Generated
Logging
Compression
Prefix_Length
Secondary

Oracle /303
Ityp_Owner
Ityp_Name
Columnas relativas al espacio
Tablespace_Name
Ini_Trans
Max_Trans
Initial_Extent
Next_Extent
Min_Extents
Max_Extents
Pct_Increase
Pct_Free
Freelists
Freelist_Groups
Pct_Threshold
Columnas relativas a estadsticas
Blevel
Leaf_Blocks
Distinct_Keys
Avg_Leaf_Blocks_Per_Key
Avg_Data_Blocks_Per_Key
Clustering_Factor
Num_Rows
Sample_Size
Last_Analyzed
User_Stats
Global_Stats
Otras columnas
Degree
Instances
Include_Column
Buffer_Pool
Duration
Pct_Direct_Access
Parameters
Domidx_Status
Domidx_Opstatus
Funcidx_Status
Join_Index
IOT_Redundant_Pkey_Elim
Dropped
El nombre del ndice se muestra en la columna Index_Name. El propietario y nombre de la tabla estn en las
columnas Table_Owner y Table_Name. La columna Uniqueness se asignar a UNIQUE para ndices de unicidad y a
NONUNIQUE para otros ndices. La columna Table_Type registra si el ndice es sobre una tabla ( 'TABLE') o
clster ('CLUSTER'). La columna Dropped, disponible desde Oracle Database 10g, identifica ndices que estn
en la papelera de reciclaje.
Nota. Desde Oracle Database 10g, podemos usar la vista USER_IND_STATISTICS para acceder a las
estadsticas de nuestros ndices.
Para ver todos los ndices de una tabla hay que consultar USER_INDEXES usando las columnas Table_Owner y
Table_Name en la clusula WHERE, tal como se muestra a continuacin:
SELECT Index_Name, Uniqueness
FROM USER_INDEXES
WHERE Table_Owner = 'Empleado' AND Table_Name = 'Festivos';
INDEX_NAME UNIQUENES
------------------- --------------------

Oracle /304
PK_FESTIVOS UNIQUE
La columna Clustering_Factor no est directamente relacionada con los clsteres, sino que representa el grado
en el cual las filas de la tabla estn ordenadas. Cuando ms ordenadas estn las filas, ms eficientes sern las
consultas de rango (las consultas de rango son aquellas en las cuales se da un rango de valores para una
columna).
Para descubrir qu columnas son parte de los ndices, y su orden dentro del ndice, necesitamos consultar la
vista USER_IND_COLUMNS.
Tambin se dispone de las vistas ALL_INDEXES y DBA_INDEXES.
Nota. Para ndices basados en funciones, ver la vista USER_IND_EXPRESSIONS.
1.5.2. Columnas de ndices: USER_IND_COLUMNS
Podemos determinar qu columnas estn en un ndice consultando la vista USER_IND_COLUMNS. Las
columnas disponibles de esta vista son las siguientes.
Index_Name El nombre del ndice.
Table_Name El nombre de la tabla del ndice.
Column_Name El nombre de la columna dentro del ndice.
Column_Position La posicin de la columna en el ndice.
Column_Length La longitud en el ndice de la columna.
Char_Length Longitud mxima del cdigo de la columna (Unicode)
Descend Un indicador Y/N que indica si la columna est ordenada en orden descendente.
Cinco columnas de esta vista no estn en USER_INDEXES: Column_Name, Column_Position, Column_Length,
Char_Length, y Descend. La columna Column_Length, como las columnas relativas a estadsticas en
USER_INDEXES, se puebla cuando la tabla base del ndice es analizada. A continuacin se muestra una simple
consulta sobre esta tabla, usando el Index_Name de USER_INDEXES (en este ejemplo, la columna
Column_Position es referenciada con el alias Pos):
SELECT Column_Name, Column_Position Pos
FROM USER_IND_COLUMNS
WHERE Index_Name = 'PK_FESTIVOS';
COLUMN_NAME POS
--------------------- ----------
MES 1
DIA 2
Tambin se dispone de las vistas ALL_IND_COLUMNS y DBA_IND_COLUMNS.
1.5.3. Columnas de ndices Bitmap Join: USER_JOIN_IND_COLUMNS
Si hemos creado un ndice Bitmap Join, podemos consultar la vista USER_JOIN_IND_COLUMNS para obtener
los detalles de join. La vista USER_JOIN_IND_COLUMNS registra los nombres de las tablas involucradas en el
Join, la columna INNER y OUTER JOIN, y la dimensin y tablas involucradas.
1.5.4. Clsteres: USER_CLUSTERS (CLU)
Los parmetros de almacenamiento y estadsticos asociados con clsteres son accesibles mediante la vista
USER_CLUSTERS (tambin conocida por su sinnimo CLU). Las columnas de esta vista se muestran en la
siguiente tabla separadas por tipos.
Columnas de identificacin
Cluster_Name
Cluster_Type
Function
Columnas relativas al espacio
Tablespace_Name
Pct_Free
Pct_Used
Key_Size
Ini_Trans
Max_Trans
Initial_Extent
Next_Extent

Oracle /305
Min_Extents
Max_Extents
Pct_Increase
Freelists
Freelist_Groups
Columnas relativas a estadsticas
Avg_Blocks_Per_Key
Hashkeys
Otras columnas
Degree
Instances
Cache
Buffer_Pool
Single_Table
Dependencies
La columna Cluster_Name contiene el nombre del clster. Cluster_Type especifica si el clster usa un ndice
estndar B*-tree o una funcin de hashing para el clster.
1.5.5. Columnas de clster: USER_CLU_COLUMNS
Para ver el mapeado de columnas de tabla a columnas de clster, hay que consultar la vista
USER_CLU_COLUMNS, cuyas columnas son las siguientes:
Cluster_Name El nombre del clster.
Clu_Column_Name El nombre de la columna clave en el clster.
Table_Name El nombre de la tabla dentro del clster.
Tab_Column_Name El nombre de la columna clave en la tabla.
Desde un nico clster podemos almacenar datos para varias tablas, USER_CLU_COLUMNS es til para qu
columnas de qu tablas mapean las columnas del clster.
No hay versin ALL_ para esta vista, pero s existe la vista DBA_CLU_COLUMNS.
1.6. Tipos de datos abstractos, estructuras ORDBMS y LOB's.
En esta seccin veremos las vistas del diccionario de datos asociadas con las estructuras objeto-relacional de
Oracle, como los tipos de datos abstractos, mtodos y objetos grandes (LOB's). Existen versiones USER_,
ALL_ y DBA_ de estas vistas.
1.6.1. Tipos de datos abstractos: USER_TYPES
Los tipos de datos abstractos creados dentro de nuestro esquema pueden ser listados usando la vista
USER_TYPES, la cual incluye columnas para el nombre del tipo (Type_Name), nmero de atributos (Attributes)
y nmero de mtodos (Methods) definidos por el tipo de dato.
Por ejemplo, el tipo de dato ANIMAL_TY tiene tres atributos y un mtodo:
SELECT Type_Name, Attributes, Methods
FROM USER_TYPES
WHERE Type_Name = 'ANIMAL_TY';
TYPE_NAME ATTRIBUTES METHODS
-------------------- ------------------ --------------
ANIMAL_TY 3 1
Atributos de tipos de datos: USER_TYPE_ATTRS
Para ver los atributos de un tipo de datos podemos consultar la vista USER_TYPE_ATTRS. Las columnas
de esta vista son las siguientes:
Type_Name Nombre del tipo.
Attr_Name Nombre del atributo.
Attr_Type_Mod El tipo de modificador del atributo.
Attr_Type_Owner Propietario del tipo del atributo, si el atributo est basado en otro tipo.
Attr_Type_Name Nombre del tipo del atributo.
Length Longitud del atributo.
Precision Precisin del atributo.
Scale Escala del atributo.
Character_Set_Name Juego de caracteres del atributo.

Oracle /306
Attr_No Posicin ordinal del atributo dentro de la definicin del tipo.
Inherited Indicador Y/N de si el atributo es heredado de un supertipo.
Podemos consultar USER_TYPE_ATTRS para ver la relacin entre los tipos de datos abstractos anidados. Por
ejemplo, el tipo de dato PERSONA_TY usa el tipo DIRECCION_TY, tal como se muestra en el siguiente ejemplo:
SELECT Attr_Name, Length, Attr_Type_Name
FROM USER_TYPE_ATTRS
WHERE Type_Name = 'PERSONA_TY';
ATTR_NAME LENGTH ATTR_TYPE_NAME
-------------------- ------------ ------------------------
NOMBRE 25 VARCHAR2
DIRECCION DIRECCION_TY
Mtodos de tipos de datos: USER_TYPE_METHODS y USER_METHOD_PARAMS
Si un tipo tiene mtodos definidos, entonces podemos consultar la vista USER_TYPE_METHODS para
determinar los nombres de los mtodos. La vista USER_TYPE_METHODS contiene columnas para mostrar el
nombre del tipo (Type_Name), el nombre del mtodo (Method_Name), el nmero del mtodo (Method_No,
usado para mtodos sobrecargados), y el tipo de mtodo (Method_Type). La vista USER_TYPE_METHODS
tambin incluye columnas para mostrar el nmero de parmetros (Parameters) y resultados (Results) retornado
por el mtodo.
Por ejemplo, el tipo ANIMAL_TY tiene un mtodo, una funcin miembro llamada EDAD. El mtodo EDAD
tiene un parmetro de entrada (FechaNacimiento) y uno de salida (la edad, en das).
Consultando USER_TYPE_METHODS se muestra que hay dos parmetros definidos en EDAD y no uno:
SELECT Parameters, Results
FROM USER_TYPE_METHODS
WHERE Type_Name = 'ANIMAL_TY' AND Method_Name = 'EDAD';
PARAMETERS RESULTS
-------------------- ------------
2 1
Por quEDAD tiene dos parmetros si slo hay uno definido? Para entenderlos, podemos consultar la vista
USER_METHOD_PARAMS, la cual describe los parmetros de nuestros mtodos:
SELECT Param_Name, Param_No, Param_Type_Name
FROM USER_METHOD_PARAMS
ORDER BY Param_No;
PARAM_NAME PARAM_NO PARAM_TYPE_NAME
-------------------------- ---------------- --------------------------
SELF 1 ANIMAL_TY
FECHANACIMIENTO 2 DATE
Aqu podemos ver que para cada mtodo Oracle crea un parmetro SELF implcito. Los resultados de
nuestros mtodos son mostrados en USER_METHOD_RESULTS:
SELECT Method_Name, Result_Type_Name
FROM USER_METHOD_RESULTS
WHERE Type_Name = 'ANIMAL_TY';
METHOD_NAME RESULT_TYPE_NAME
-------------------- ---------------------------
EDAD NUMBER
Otros tipos de datos: USER_REFS, USER_COLL_TYPES y USER_NESTED_TABLES
Si usamos referencias a tipos con REF podemos consultar la vista USER_REFS para mostrar los REF's que
hemos definido. La vista USER_REFS muestra el nombre de la tabla que contiene la columna REF (Table_Name)
y el nombre de columna del objeto columna ( Column_Name). Los atributos del REF como si estn o no
almacenados con el ROWID tambin son accesibles mediante USER_REFS.
Los tipos de coleccin (tablas anidadas y arrays variables) son descritos mediante la vista USER_COLL_TYPES
del diccionario de datos. Las columnas de USER_COLL_TYPES incluyen Type_Name, Upper_Bound (para arrays
variables), y la longitud (Length) y precisin (Precision) de los elementos. Podemos usar USER_COLL_TYPES en
conjuncin con las vistas de los tipos de datos abstractos mostrados previamente para determinar el tipo de

Oracle /307
estructura de una coleccin. Podemos tambin consultar USER_NESTED_TABLES y USER_VARRAYS para ver
los detalles de nuestras colecciones.
1.6.2. LOB's: USER_LOBS
La vista USER_LOBS proporciona informacin de los LOB's definidos en nuestras tablas. A continuacin se
muestra un ejemplo:
SELECT Table_Name, Column_Name
FROM USER_LOBS;
TABLE_NAME COLUMN_NAME
------------------- ---------------------
OFERTA TEXTO_OFERTA
OFERTA PRESUPUESTO
USER_LOBS tambin muestra los nombres de los segmentos usados para contener los datos LOB cuando se
agranda; sin embargo, no muestra los tipos de datos de columnas LOB. Para ver los tipos de datos LOB
podemos usar el comando DESCRIBE sobre la tabla que incluye los LOB's o consultar la vista
USER_TAB_COLUMNS.
1.7. Enlaces de base de datos y vistas materializadas.
Los enlaces de base de datos y vistas materializadas se usan para acceder a datos remotos. Dependiendo de
los tipos de vistas materializadas que usemos, podemos habilitar el uso de registros de vistas materializadas.
1.7.1. Enlaces de base de datos: USER_DB_LINKS
Para ver los enlaces de base de datos creados bajo nuestra cuenta podemos consultar la vista USER_DB_LINKS.
Las columnas de esta vista, incluyendo el nombre del enlace (DB_Link), nombre de usuario para conectar
(Username), la contrasea de la cuenta (Password), y la cadena de conexin (Host), muestran la informacin
sobre la conexin remota que el enlace usar para establecerse. Los valores de Username y Password sern
usados para registrarse en la base de datos remota definida por el valor de Host.
La columna Host almacena el nombre del servicio Oracle Net. Esta columna almacena la cadena de caracteres
exacta especificada durante el comando CREATE DATABASE LINK, y no altera su casustica. Por lo tanto,
debemos ser cuidadosos al crear enlaces de base de datos y escribir el nombre del servicio.
Nota. Si estamos usando inicios de conexin por defecto a la base de datos remota, la columna
Password tendr el valor NULL.

Tambin se dispone de las vistas ALL_DB_LINKS y DBA_DB_LINKS. Estas vistas tienen una columna Owner en
vez de la columna Password.
1.7.2. Vistas materializadas.
Podemos consultar USER_MVIEWS para mostrar informacin sobre las vistas materializadas propiedad de
nuestra cuenta. Esta vista muestra la informacin de estructura de la vista materializada as como su
planificacin de refresco. Las columnas de esta vista son:
Nombre col. Descripcin
Owner La cuenta que es propiedad de la vista materializada.
Mview_Name En nombre de la vista materializada.
Container_Name La tabla base (en la base de datos local) con los datos de la vista materializada.
Query La consulta que define la vista materializada.
Query_Len La longitud de la consulta base de la vista materializada.
Updatable Un indicador de si la instantnea puede ser actualizada.
Update_Log El nombre de la tabla que registra los cambios hechos en instantneas actualizables.
Master_Rollback_Seg El segmento de rollback usado cuando se pueblan instantneas y se hacen
operaciones de refresco.
Master_Link El enlace de base de datos usado para acceder a la base de datos maestra.
Rewrite_Enabled Un indicado Yes/No de si ha habilitado rescritura de consultas para la vista.
Rewrite_Capability Reglas y restricciones para consultas rescritas.
Refresh_Mode DEMAND, COMMIT o NEVER, dependiendo del modo de refresco de la vista.
Refresh_Method Valores usando para dirigir un refresco rpido de la vista (Complete, Fast, Never, o
Force).
Build_Mode Instanciacin IMMEDIATE, DEFERRED o PREBUILT de los datos de la vista
materializada durante su creacin.

Oracle /308
Fast_Refreshable Mtodos disponibles para refrescos rpidos de la vista materializada.
Last_Refresh_Type El tipo de refresco ms reciente usado.
Last_Refresh_Date La fecha y hora de registro de la ltima vez que los datos fueron refrescados.
Staleness El estado de los datos de la vista materializada relativos a su tabla maestra.
After_Fast_Refresh Estado siguiente a un refresco rpido.
Compile_State Validez de la vista materializada.
Use_No_Index Indicador Yes/No de si la vista materializada fue creada con la clusula USING NO
INDEX.
Unknown_Trusted_FD Indica si la vista materializada usa restriccin de confianza para el refresco.
Stale_Since El tiempo en que la vista materializada se hizo antigua.
El nombre de la vista materializada se encuentra en la columna Mview_Name de USER_MVIEWS. La tabla base
local de la vista est en la columna Container_Name. Las nuevas columnas de USER_MVIEWS disponibles desde
Oracle Database 10g, incluyen Stale_Since (cundo la vista materializada se hace vieja). Para determinar qu
enlaces de base de datos estn siendo usados por vistas materializadas, podemos consultar la columna
Master_Link, tal se muestra en el siguiente ejemplo:
SELECT Master_Link
FROM USER_MVIEWS;
Los nombres de los enlaces de base de datos retornados por esta consulta pueden ser usados como entradas
para consultas a la vista USER_DB_LINKS. Esta consulta mostrar toda la informacin disponible de todos los
enlaces de base de datos usados en nuestras vistas materializadas:
SELECT *
FROM USER_DB_LINKS
WHERE DB_Link IN (SELECT Master_Link FROM USER_MVIEWS);
Las vistas ALL_MVIEWS y DBA_MVIEWS tienen las mismas definiciones de columnas que USER_MVIEWS.
Dos vistas relacionadas USER_REFRESH y USER_REFRESH_CHILDREN muestran informacin sobre grupos
de refrescos. USER_MVIEW_REFRESH_TIMES muestra la ltima vez que las vistas materializadas fueron
refrescadas. Desde Oracle Database 10g, podemos acceder a los comentarios de las vistas materializadas
mediante la vista USER_MVIEW_COMMENTS, y consultar detalles de rescritura mediante
USER_REWRITE_EQUIVALENCES.
Capacidades adicionales de vistas materializadas.
Podemos consultar la vista USER_MVIEW_ANALYSIS para ver las vistas materializadas que soportan rescritura
de consulta.
Si una vista materializada contiene referencias a tablas remotas, stas no sern mostradas en esta vista.
Podemos consultar el propietario de la vista materializada ( Owner), su nombre (Mview_Name) y el propietario
de la tabla base (Mview_Table_Owner). Muchas de las columnas de esta vista son indicadores, como Summary
('Y' si la vista contiene una agregacin), Known_Stale ('Y' si los datos de la vista son inconsistente con la tabla
base), y Contains_Views ('Y' si la vista materializada referencia una vista).
Si la vista materializada contiene agregaciones, podemos consultar USER_MVIEW_AGGREGATES para ver los
detalles de la agregacin. Las columnas de esta vista son las siguientes:
Owner Propietario de la vista materializada.
Mview_Name Nombre de la vista materializada.
Position_in_Select Posicin dentro de la consulta.
Container_Column Nombre de la columna.
Agg_Function Funcin de agregado.
DistinctFlag 'Y' si la agregacin usa la funcin DISTINCT.
Measure El texto SQL de la medida, excluyendo la funcin agregada
Podemos consultar los detalles de las relaciones dentro de las vistas materializadas usando las vistas
USER_MVIEW_DETAIL_RELATIONS y USER_MVIEW_KEYS. Si la vista materializada est basada en JOIN's,
podemos consultar USER_MVIEW_JOINS para los detalles del JOIN. En general, USER_MVIEW_ANALYSIS se
usar ms habitualmente para consultar datos sobre las vistas materializadas.
1.7.3. Registros de vistas materializadas: USER_MVIEW_LOGS
Los registros de vistas materializadas pueden ser usados por muchas vistas materializadas para determinar qu
registros en la tabla principal necesitan ser refrescados en la vista materializada de esta tabla. Podemos
consultar USER_MVIEW_LOGS para obtener informacin sobre los registros de un usuario, incluyendo el
nombre de la tabla principal ( Master), la tabla que contiene los registros ( Log_Table), y si la vista materializada

Oracle /309
est basada sobre la clave primaria o sobre el ROWID (las columnas Primary_Key y ROWID).
La vista USER_MVIEW_LOGS es normalmente consultada para propsitos de mantenimiento, como para
determinar el nombre del trigger usado para crear los registros de la vista materializada.
La vista DBA_MVIEW_LOGS tiene las mismas columnas que USER_MVIEW_LOGS. Podemos consultar la vista
USER_BASE_TABLE_MVIEWS para obtener las tablas primarias de la vista materializada que usan registros de
vista materializada.
1.8. Triggers, procedimientos, funciones y paquetes.
Podemos usar procedimientos, paquetes y triggers para forzar reglas del negocio o para realizar procesos
complejos.
1.8.1. Triggers: USER_TRIGGERS
La vista USER_TRIGGERS contiene informacin sobre los trigger propiedad de nuestra cuenta. Esta vista
muestra el tipo de trigger y su cuerpo. Las columnas de esta vista son:
Nombre col. Descripcin
Trigger_Name Nombre del trigger.
Trigger_Type El tipo de trigger (BEFORE STATEMENT, BEFORE EACH ROW, y dems).
Triggering_Event El comando que ejecuta el trigger (INSERT, UPDATE, o DELETE).
Table_Owner El propietario de la tabla para el cual se define el trigger.
Base_Object_Type El tipo de objeto sobre el que est basado el trigger (TABLE, VIEW, SCHEMA, o
DATABASE).
Table_Name El nombre de la tabla o vista para el cual est definido el trigger.
Column_Name Para triggers de tablas anidadas, el nombre de la columna de la tabla anidada.
Referencing_Names Nombres usados para referenciar los valores OLD y NEW en el trigger.
When_Clause La clusula WHEN usada por el trigger.
Status Si es trigger est activado (ENABLED) o desactivado (DISABLED).
Description La descripcin del trigger.
Action_Type Tipo de accin del cuerpo del trigger (CALL o PL/SQL).
Trigger_Body El texto del trigger.
Las vistas ALL_TRIGGERS y DBA_TRIGGERS aaden la columna Owner para indicar el propietario del trigger.
Otra vista relacionada con los triggers es USER_TRIGGER_COLS, las cual muestra cmo las columnas son
usadas por el trigger. Lista el nombre de cada columna afectada por un trigger, as cmo el trigger la usa.
Tambin existen las versiones ALL_TRIGGER_COLS y DBA_TRIGGER_COLS.
1.8.2. Procedimientos, funciones y paquetes: USER_SOURCE
El cdigo fuente de procedimientos, funciones, paquetes y cuerpos de paquetes puede ser consultado usando
la vista USER_SOURCE. La columnas Type de USER_SOURCE identifica el objeto procedimental, y puede tomar
los valores: 'PROCEDURE', 'FUNCTION', 'PACKAGE', 'PACKAGE BODY', 'TRIGGER','TYPE', 'TYPE BODY' o 'JAVA
SOURCE'. Cada lnea de cdigo es almacenada en un registro independiente de USER_SOURCE.
Podemos seleccionar informacin de USER_SOURCE mediante una consulta similar a la mostrada a
continuacin. En este ejemplo, se selecciona la columna Text y se ordena por el nmero de la columna Line.
El nombre y tipo del objeto se usan para especificar qu cdigo ser mostrado:
SELECT Text
FROM USER_SOURCE
WHERE Name = '&procedure_name' AND Type = 'PROCEDURE'
ORDER BY Line;

Nota. La secuencia de las lneas es mantenida por la columna Line; por lo tanto, esta columna debe
ser usada para ordenar la consulta.
Las vistas ALL_SOURCE y DBA_SOURCE aaden la columna adicional Owner para indicar el propietario del
objeto.
Nota. Para ver los valores de los parmetros persistentes para unidades PL/SQL hay que consultar
la vista USER_STORED_SETTINGS.
Cdigos de error: USER_ERRORS
El comando SHOW ERRORS de SQL*Plus verifica la vista del diccionario de datos USER_ERRORS para mostrar
los errores asociados con la ltima compilacin de un objeto procedimental. SHOW ERRORS mostrar la lnea

Oracle /310
y nmero de columna de cada error, as como el texto del mensaje de error.
Para ver los errores asociados con los objetos procedimentales creados previamente, podemos consultar
USER_ERRORS directamente. Podemos necesitar hacer esto cuando miramos los errores asociados con
cuerpos de paquetes, donde la compilacin del paquete result en un error no mostrado por el comando
SHOW ERROR. Podemos tambin necesitar consultar USER_ERRORS cuando encontremos errores de
compilacin con varios objetos procedimentales.
Las siguientes son las columnas disponibles en esta vista:
Nombre col. Descripcin
Name El nombre del objeto procedimental.
Type El tipo de objeto ('PROCEDURE', 'FUNCTION', 'PACKAGE', 'PACKAGE BODY',
'TRIGGER', 'TYPE', 'TYPE BODY', 'VIEW', 'JAVA CLASS', o 'JAVA SOURCE').
Sequence El nmero de lnea de secuencia, para usar en la clusula ORDER BY.
Line El nmero de lnea dentro del cdigo fuente en el que ocurri el error.
Position La posicin dentro de la lnea en la que ocurri el error.
Text El texto del mensaje de error.
Attribute Indicador de si la fila seleccionada es un error ('ERROR') o un aviso ('WARNING').
Message_Number Nmero de error, sin prefijo.
Consultas sucesivas a esta vista deberan siempre incluir la columna Sequence en la clusula ORDER BY.
Las vistas ALL_ERRORS y DBA_ERRORS aaden la columna adicional Owner.
Tamao del cdigo: USER_OBJECT_SIZE
Podemos consultar la cantidad de espacio usado en el tablespace SYSTEM por un objeto procedimental
mediante la vista USER_OBJECT_SIZE. Tal como se muestra en el siguiente listado, podemos acumular el
tamao de las cuatro reas separadas para determinar el espacio total usado en las tablas del diccionario de
datos de SYSTEM para almacenar los objetos.
Las cuatro columnas de tamao (_Size), seguidas de las columnas Name y Type, constituyen todas las columnas
de esta vista.
SELECT Source_Size+Code_Size+Parsed_Size+Error_Size AS Total
FROM USER_OBJECT_SIZE
WHERE Name = '&procedure_name' AND Type = 'PROCEDURE';
Tambin existe la vista DBA_OBJECT_SIZE.
1.9. Dimensiones.
Podemos crear y mantener dimensiones y jerarquas.
Podemos consultar la columna Dimension_Name de la vista USER_DIMENSIONS para mostrar los nombres de
nuestras dimensiones. USER_DIMENSIONS tambin contiene columnas para el propietario de la dimensin
(Owner), estado (columna Invalid, asignada a 'Y' o 'N'), y nivel de revisin (columna Revision). Los atributos de
una dimensin son accedidos mediante vistas adicionales del diccionario de datos.
Para ver las jerarquas dentro de una dimensin podemos consultar la vista USER_DIM_HIERARCHIES. Esta
vista tiene slo tres columnas: Owner, Dimension_Name, y Hierarchy_Name. Consultando
USER_DIM_HIERARCHIES para la dimensin GEOGRAFIA obtendremos el nombre de sus jerarquas:
SELECT Hierarchy_Name
FROM USER_DIM_HIERARCHIES
WHERE Dimension_Name=''GEOGRAFIA';
HIERARCHY_NAME
-------------------------
PAISES_ROLLUP
Podemos ver los detalles de la jerarqua para PAISES_ROLLUP consultando la vista USER_DIM_CHILD_OF, tal
como se muestra a continuacin. El primero comando crea una dimensin llamada GEOGRAFIA que registra
las jerarquas de pases y continentes.
CREATE DIMENSION GEOGRAFIA
LEVEL PAIS_ID IS PAIS.Pais
LEVEL CONTINENT_ID IS CONTINENTE.Continente
HIERARCHY PAISES_ROLLUP (
PAIS_ID CHILD OF CONTINENTE_ID JOIN KEY PAIS.Continente REFERENCES CONTINENTE_ID
);

Oracle /311
SELECT Child_Level_Name, Parent_Level_Name, Position, Join_Key_Id
FROM USER_DIM_CHILD_OF
WHERE Hierarchy_Name = 'PAISES_ROLLUP';
CHILD_LEVEL_NAME PARENT_LEVEL_NAME POSITION JOIN
-------------------------- ---------------------------- -------------- --------
PAIS_ID CONTINENTE_ID 1 1
Podemos consultar la vista USER_DIM_JOIN_KEY para ver la clave de join de una jerarqua:
SELECT Level_name, Child_Join_Column
FROM USER_DIM_JOIN_KEY
WHERE Dimension_Name = 'GEOGRAFIA' AND Hierarchy_Name = 'PAISES_ROLLUP';
LEVEL_NAME CHILD_JOIN_COLUMN
----------------------- ----------------------------
CONTINENTE_ID CONTINENTE
Podemos ver los niveles de una dimensin consultando la vista USER_DIM_LEVELS, y ver las columnas claves
mediante USER_DIM_LEVEL_KEY. La informacin de atributos para dimensiones es accesible mediante la vista
USER_DIM_ATTRIBUTES.
Hay versiones ALL_ y DBA_ de las vistas relacionadas con las dimensiones.
1.10. Asignacin y uso de espacio, incluyendo particiones y subparticiones.
Podemos consultar el diccionario de datos para determinar el espacio que est disponible y asignado para los
objetos de base de datos.
1.10.1. Tablespaces: USER_TABLESPACES
Podemos consultar la vista USER_TABLESPACES para determinar sobre qu tablespaces tenemos permisos de
acceso y los parmetros de almacenamiento por defecto de cada uno. Los parmetros de almacenamiento por
defecto del tablespace sern usados para cada objeto almacenado dentro del tablespace a menos que el
comando CREATE o ALTER para estos objetos especifique sus propios parmetros de almacenamiento. Las
columnas relativas al espacio de USER_TABLESPACES, son muy similares a las columnas relativas al espacio de
USER_TABLES.
No hay versin ALL_ de esta vista. DBA_TABLESPACES muestra los parmetros de almacenamiento de todos
los tablespaces.
Nombre col. Descripcin
Tablespace_Name Nombre del tablespace.
Block_Size El tamao de bloque en uso por este tablespace.
Initial_Extent El parmetro INITIAL por defecto para objetos del tablespace.
Next_Extent El parmetro NEXT por defecto para objetos del tablespace.
Min_Extents El parmetro MINEXTENTS por defecto para objetos del tablespace.
Max_Extents El parmetro MAXEXTENTS por defecto para objetos del tablespace.
Pct_Increase El parmetro PCTINCREASE por defecto para objetos del tablespace.
Min_Extlen El tamao mnimo de extensin para los objetos del tablespace.
Status El estado del tablespace ('ONLINE', 'OFFLINE', 'INVALID', 'READ ONLY').
Un tablespace invlido es uno que ha sido borrado; sus registros estn todava
visibles a travs de esta vista.
Contents Un indicador de si el tablespace es usado para almacenar objetos permanentes
('PERMANENT') o solo segmentos temporales ('TEMPORARY').
Logging Indicador del valor por defecto del parmetro LOGGING/NOLOGGING para
objetos del tablespace.
Extent_Management Dnde se realiza la administracin de las extensiones en el tablespace
('DICTIONARY' o 'LOCAL').
Allocation_ Type Tipo de asignacin de extensin efectiva.
Segment_Space_Management Indicador de si el espacio libro es controlado mediante listas libres
('MANUAL') o mapas de bits ('AUTO').
Retention Retencin del tablespace de deshacer ('GUARANTEE', 'NO GUARANTEE', o
'NOT APPLY').
Bigfile Indica si el tablespace es un tablespace de ficheros grandes ( 'YES') o de

Oracle /312
ficheros pequeos ('NO').
Force_Logging Indicador Yes/No de si el tablespace est en modo logging.
1.10.2. Cuotas de espacio: USER_TS_QUOTAS
La vista USER_TS_QUOTAS es muy til para determinar la cantidad de espacio que tenemos actualmente
asignada y la mxima cantidad de espacio disponible para nuestros tablespaces. Una consulta sencilla de
USER_TS_QUOTAS se muestra a continuacin:
SELECT * FROM USER_TS_QUOTAS;
TABLESPACE_NAME BYTES MAX_BYTES BLOCKS MAX_BLOCKS
-------------------------- ---------- ---------------- ---------- ------------------
USERS 67584 0 33 0
USER_TS_QUOTAS contiene un registro por cada nombre de tabla ( Tablespace_Name). La columna Bytes
refleja el nmero de bytes asignados para objetos propiedad del usuario. La columna Max_Bytes es el mximo
nmero de bytes que el usuario puede poseer en este tablespace; si no hay cuota para este tablespaces,
entonces Max_Bytes mostrar el valor 0. Las columnas Bytes y Max_Bytes son trasladadas dentro de bloques de
Oracle en las columnas Blocks y Max_Blocks, respectivamente.
No hay versin ALL_ para esta vista. La vista DBA_TS_QUOTAS muestra las cuotas para todos los usuarios y
tablespaces, y es el modo ms efectivo de mostrar el uso de espacio dentro de toda la base de datos.
1.10.3. Segmentos y extensiones: USER_SEGMENTS y USER_EXTENTS
El espacio se asigna a los objetos (como tablas, clsteres e ndices) en segmentos, las contrapartidas fsicas de
los objetos lgicas creados en la base de datos. Podemos consultar la vista USER_SEGMENTS para ver los
parmetros de almacenamiento actuales y el espacio usado en nuestros segmentos. USER_SEGMENTS es
muy til cuando estamos en peligro de exceder uno de los lmites de almacenamiento. Las columnas de esta
vista son las siguientes:
Nombre col. Descripcin
Segment_Name El nombre del segmento.
Partition_Name NULL si el objeto no esta particionado; sino, el nombre de la particin del segmento.
Segment_Type El tipo de segmento ('TABLE', 'CLUSTER', 'INDEX', 'ROLLBACK', y dems).
Tablespace_Name El nombre del tablespace en el cual el segmento es almacenado.
Bytes El nmero de bytes asignados al segmento.
Blocks El nmero de bloques Oracle asignados al segmento.
Extents El nmero de extensiones en el segmento.
Initial_Extent El tamao de la extensin inicial del segmento.
Next_Extent El valor del parmetro NEXT para el segmento.
Min_Extents El nmero mnimo de extensiones en el segmento.
Max_Extents El valor del parmetro MAXEXTENTS para el segmento.
Pct_Increase El valor del parmetro PCTINCREASE para el segmento.
Freelists El nmero de procesos freelist (lista de bloques de datos en el segmento que pueden
usarse durante inserciones) asignados al segmento; si un segmento tiene varios freelists,
entonces la contencin para los bloques libres durante inserciones actuales disminuir.
Freelist_Groups El nmero de grupos freelist asignados al segmento.
Buffer_Pool Bfer interno en el cual el segmento ser ledo ('DEFAULT', 'KEEP', o 'RECYCLE') si
hemos definido varios grupos de bferes.
Los segmentos consisten de secciones contiguas llamadas extensiones. Las extensiones que constituyen
segmentos son descritas en la vista USER_EXTENTS. En USER_EXTENTS podremos ver el tamao actual de
cada extensin dentro del segmento; esto es til para registrar el impacto de cambios en las opciones NEXT y
PCTINCREASE. Adems de las columnas Segment_Name, Segment_Type y Tablespace_Name, la vista
USER_EXTENTS tiene tres nuevas columnas: Extent_ID (para identificar la extensin dentro del segmento),
Bytes (el tamao de la extensin, en bytes), and Blocks (el tamao de la extensin, en bloques Oracle).
Tanto USER_SEGMENTS como USER_EXTENTS tienen versiones DBA_, que aaden la columna adicional
Owner. Si queremos mostrar todos los propietarios que poseen segmentos en un tablespace, podemos
consultar asignando la columna Tablespace_Name en DBA_SEGMENTS. No hay versin ALL_ de estas vistas.
1.10.4. Particiones y subparticiones.
Un simple dato de tabla puede ser almacenado a travs de varias particiones. Para ver cmo una tabla est
particionada debemos consultar la vista USER_PART_TABLES, cuyas columnas se describen en la siguiente

Oracle /313
tabla.
Columnas de identificacin
Table_Name
Partitioning_Type
Subpartitioning_Type
Partition_Count
Def_Subpartition_Count
Partitioning_Key_Count
Subpartitioning_Key_Count
Def_Logging
Def_Buffer_Pool
Columnas relativas a almacenamiento
Def_Tablespace_Name
Def_Pct_Free
Def_Pct_Used
Def_Ini_Trans
Def_Max_Trans
Def_Initial_Extent
Def_Next_Extent
Def_Min_Extents
Def_Max_Extents
Def_Pct_Increase
Def_Freelists
Def_Freelist_Groups
Def_Compression
La mayora de columnas de USER_PART_TABLES definen los parmetros de almacenamiento por defecto para
las particiones de la tabla. Cuando una particin es aadida a la tabla, por defecto usar los parmetros de
almacenamiento mostrados en USER_PART_TABLES. La vista USER_PART_TABLES tambin muestra el nmero
de particiones de la tabla (Partition_Count), el nmero de columnas en la clave de particin
(Partitioning_Key_Count), y el tipo de particin (Partitioning_Type).
USER_PART_TABLES almacena una fila por cada tabla que ha sido particionada. Para ver informacin sobre
cada particin individual que pertenece a la tabla podemos consultar la vista USER_TAB_PARTITIONS. En
USER_TAB_PARTITIONS veremos una fila por cada particin de una tabla. Las columnas de
USER_TAB_PARTITIONS se muestran en la siguiente tabla.
Columnas de identificacin
Table_Name
Composite
Partition_Name
Subpartition_Count
High_Value
High_Value_Length
Partition_Position
Logging
Buffer_Pool
Columnas relativas a almacenamiento
Tablespace_Name
Pct_Free
Pct_Used
Ini_Trans
Max_Trans
Initial_Extent
Next_Extent
Min_Extent
Max_Extent
Pct_Increase

Oracle /314
Freelists
Freelist_Groups
Compression
Columnas relativas a estadsticas
Num_Rows
Blocks
Empty_Blocks
Avg_Space
Chain_Cnt
Avg_Row_Len
Sample_Size
Last_Analyzed
Global_Stats
User_Stats
La vista USER_TAB_PARTITIONS contiene columnas que identifican la tabla a la cual pertenecen las
particiones y muestra los parmetros de almacenamiento de la particin y las estadsticas para la particin. Las
columnas relacionadas con estadsticas son pobladas cuando la tabla es analizada. Las columnas de
identificacin muestran los valores mayores para el rango usado para definir la particin (High_Value)y la
posicin de la particin dentro de la tabla (Partition_Position).
Las columnas usadas por la clave de particin son accesibles mediante la vista USER_PART_KEY_COLUMNS.
Esta vista contiene slo cuatro columnas.
Name El nombre de la tabla o ndice particionado
Object_Type El tipo de objeto (TABLE o INDEX).
Column_Name El nombre de la columna que es parte de la clave de particin.
Column_Position La posicin de la columna dentro de la clave de particin.
Las estadsticas para las columnas de particin son accesibles mediante la vista USER_PART_COL_STATISTICS.
Las columnas en USER_PART_COL_STATISTICS reflejan las correspondientes en
USER_TAB_COL_STATISTICS.
La informacin de histogramas de datos para particiones es accesible mediante la vista
USER_PART_HISTOGRAMS. Las columnas de esta vista muestran los valores de punto final para cada uno de
los cubos del histograma. Las columnas son Table_Name, Partition_Name, Column_Name, Bucket_Number,
Endpoint_Value y Endpoint_Actual_Value.
Ya que los ndices pueden ser particionados, hay una vista USER_IND_PARTITIONS. Las columnas en
USER_IND_PARTITIONS pueden agruparse en tres categoras, tal como se muestra en la siguiente tabla.
Columnas de identificacin
Index_Name
Composite
Partition_Name
Subpartition_Count
High_Value
High_Value_Length
Partition_Position
Status
Logging
Buffer_Pool
Compression
Domidx_Opstatus
Parameters
Columnas relativas a espacio
Tablespace_Name
Ini_Trans
Max_Trans
Initial_Extent
Next_Extent
Min_Extent

Oracle /315
Max_Extent
Pct_Increase
Pct_Free
Freelists
Freelist_Groups
Columnas relativas a estadsticas
Blevel
Leaf_Blocks
Distinct_Keys
Avg_Leaf_Blocks_Per_Key
Avg_Data_Blocks_Per_Key
Clustering_Factor
Num_Rows
Sample_Size
Last_Analyzed
User_Stats
Pct_Direct_Access
Global_Stats
Las columnas en USER_IND_PARTITIONS son paralelas a las de USER_INDEXES, con unas pocas
modificaciones en las columnas de identificacin. Las columnas de identificacin para ndices particionados
incluyen el nombre de la particin, el mayor valor para la particin, y la posicin de la particin dentro de la
tabla. Las columnas relativas a las estadsticas son pobladas cuando la particin es analizada. Las columnas
relativas al espacio describen la asignacin de espacio para el ndice.
Si una particin tiene subparticiones, podemos ver los detalles de las subparticiones mediante varias vistas del
diccionario de datos. La vista USER_IND_SUBPARTITIONS contiene las mismas columnas relativas al espacio y
a las estadsticas que USER_IND_PARTITIONS, incluyendo columnas para identificar la subparticin
(Subpartition_Name y Subpartition_Position). Similarmente, la vista USER_TAB_SUBPARTITIONS contiene las
mismas columnas relativas al espacio y las estadsticas que USER_TAB_PARTITIONS, adems de las columnas
Subpartition_Name y Subpartition_Position. Por tanto, podemos determinar las definiciones de espacio para cada
particin y subparticin.
Como hemos visto, podemos consultar las vistas USER_PART_COL_STATISTICS y USER_PART_HISTOGRAMS
por informacin de estadsticas independientemente de las particiones. Para subparticiones, podemos
consultar USER_SUBPART_COL_STATISTICS y USER_SUBPART_HISTOGRAMS, cuyas estructuras reflejan las
vistas de estadsticas de particin. Para ver las columnas claves de subparticiones podemos consultar
USER_SUBPART_KEY_COLUMNS, cuya estructura de columnas es idntica a la de USER_PART_KEY_COLUMNS.
1.10.5. Espacio libre: USER_FREE_SPACE
Adems de ver el espacio que hemos usado, podemos tambin consultar el diccionario de datos para ver
cunto espacio esta marcado actualmente como espacio libre. La vista USER_FREE_SPACE muestra las
extensiones libres en todos los tablespaces accesibles por el usuario. Esta vista cataloga por el nombre de
tablespace (Tablespace_Name) el ID de fichero (File_ID), el ID de bloque (Block_ID), y el nmero de archivo
relativo al punto de partida de la extensin libre. El tamao de la extensin libre es mostrado tanto en bytes
como en bloques.
La vista DBA_FREE_SPACE es usado con frecuencia por DBA's para supervisar la cantidad de espacio libre
disponible y el grado en el cual est fragmentado.
1.11. Usuarios y permisos.
Los usuarios y sus permisos son registrados dentro del diccionario de datos.
1.11.1. Usuarios: USER_USERS
Podemos consultar la vista USER_USERS para mostrar informacin sobre nuestra cuenta. La vista
USER_USERS incluye nuestro nombre de usuario ( Username), un ID asignado por la base de datos ( User_ID), el
tablespace por defecto (Default_Tablespace), el tablespace temporal (Temporary_Tablespace), y la fecha de
creacin de la cuenta (Created). La columna Account_Status de USER_USERS muestra el estado de nuestra
cuenta, si est bloqueada, desbloqueada ('OPEN'), o ha expirado. Si una cuenta est bloqueada, la columna
Lock_Date mostrar la fecha en que fue la cuenta bloqueada y la columna Expiry_Date mostrar la fecha de
expiracin. Podemos tambin consultar informacin sobre los grupos de recursos consumidos

Oracle /316
(Initial_Rsrc_Consumer_Group) asignados a nosotros por el DBA, y nuestro nombre externo (External_Name).
La vista ALL_USERS contiene slo el nombre de usuario (Username), identificador (User_ID) y fecha de
creacin (Created).ALL_USERS es til cuando necesitamos saber los nombres de usuarios que estn disponibles
(por ejemplo, durante comandos GRANT). La vista DBA_USERS contiene las mismas columnas que
USER_USERS, ms dos columnas adicionales: Password (la contrasea cifrada de la cuenta) y Profile (el perfil de
recurso del usuario).
1.11.2. Lmites de los recursos: USER_RESOURCE_LIMITS
En Oracle, se pueden usar perfiles para poner lmites a la cantidad de recursos disponibles del sistema y base
de datos para un usuario. Si no son creados perfiles en la base de datos, el perfil por defecto especificar
recursos ilimitados para todos los usuarios. Los perfiles fuerzan medidas de seguridad adicionales, como
fechas de expiracin sobre cuentas y la longitud mnima de contraseas.
Para ver los lmites que estn puestos en nuestra sesin actual podemos consultar la vista
USER_RESOURCE_LIMITS. Sus columnas son las siguientes:
Resource_Name El nombre del recurso (por ejemplo, SESSIONS_PER_USER).
Limit El lmite puesto sobre el recurso.
La vista USER_PASSWORD_LIMITS describe los parmetros de perfil de contrasea para el usuario. Tiene las
mismas columnas que USER_RESOURCE_LIMITS.
No hay versiones ALL_ o DBA_ de esta vista. Para ver el coste asociado con cada recurso disponible podemos
consultar la vista RESOURCE_COST.
Los DBA's pueden acceder a la vista DBA_PROFILES para ver los lmites de recursos para todos los perfiles. La
columna Resource_Type de DBA_PROFILES indica si el perfil de recurso es un perfil 'PASSWORD' o 'KERNEL'.
1.11.3. Permisos de tabla: USER_TAB_PRIVS
Podemos usar la vista USER_TAB_PRIVS(Permisos de tabla de usuario) para ver los permisos que nos fueron
concedidos, el otorgador del permiso y el propietario del objeto. Adems de sus columnas Grantee, Grantor y
Owner, esta vista contiene columnas Table_Name, Hierarchy, Privilege, y un indicador (asignado a 'YES' o 'NO')
para ver si el permiso fue concedido con WITH ADMIN OPTION (Grantable).
La vista USER_TAB_PRIVS_MADE muestra los registros de USER_TAB_PRIVS para los cuales el usuario es el
propietario (y por lo tanto carece de una columna Owner). La vista USER_TAB_PRIVS_RECD (Permisos
recibidos de tabla de usuario) muestra los registros de USER_TAB_PRIVS con los permisos concedidos al
usuario (y por tanto carece de una columna Grantee). Por tanto, tanto USER_TAB_PRIVS_MADE como
USER_TAB_PRIVS_RECD son subconjuntos de USER_TAB_PRIVS.
Hay versiones ALL_ para las vistas USER_TAB_PRIVS, USER_TAB_PRIVS_MADE y USER_TAB_PRIVS_RECD. Las
versiones ALL_ catalogan aquellos objetos para los cuales el usuario o PUBLIC es el cesionario o el otorgador.
Hay una versin DBA_ de USER_TAB_PRIVS llamada DBA_TAB_PRIVS.
Permisos de columna: USER_COL_PRIVS
Adems de conceder permisos sobre tabla, podemos tambin conceder permisos al nivel de columnas. Las
vistas del diccionario de datos usada para mostrar los permisos de columnas son la mayora idnticos en
disea a las vistas de permisos de tablas. Hay una columna adicional Column_Name en cada vista COL_, y la
columna Hierarchy se ha suprimido. La vista USER_COL_PRIVS es anloga a USER_TAB_PRIVS, la vista
USER_COL_PRIVS_MADE es anloga a USER_TAB_PRIVS_MADE, y la vista USER_COL_PRIVS_RECD es anloga a
USER_TAB_PRIVS_RECD.
Versiones ALL_ tambin estn disponibles para todas estas vistas. Y DBA_COL_PRIVS muestra todos los
permisos de columna concedidos a los usuarios de la base de datos.
1.11.4. Permisos del sistema: USER_SYS_PRIVS
La vista USER_SYS_PRIVS muestra los permisos del sistema que han sido concedidos al usuario. Sus columnas
son Username, Privilege, y Admin_Option (un indicador 'YES' o 'NO' que dice si el permiso fue concedido con
WITH ADMIN OPTION). Todos los permisos de sistema concedidos directamente a un usuario son mostrados
mediante esta vista. Los permisos de sistema concedidos a un usuario mediante un rol no son mostrados aqu.
La siguiente consulta muestra la salida para la cuenta EMPLEADO:
SELECT Username, Privilege * FROM USER_SYS_PRIVS;
USERNAME PRIVILEGE
---------------- ----------------------------------
EMPLEADO CREATE DIMENSION
EMPLEADO UNLIMITED TABLESPACE

Oracle /317
No hay versin ALL_ para esta vista. La vista DBA_SYS_PRIVS permite consultar todos los permisos de sistema
concedidos a todos los usuarios de la base de datos.
1.12. Roles.
Adems de los permiso concedidos directamente a los usuarios, podemos agrupar conjuntos de permisos
dentro de roles. Los roles pueden ser concedidos a los usuarios o a otros roles, y pueden consistir de ambos
objetos y permisos de sistema.
Para ver qu roles nos han sido concedidos debemos consultar la vista USER_ROLE_PRIVS. Cualquier rol que
hay sido concedido como PUBLIC ser mostrado aqu. Las columnas de esta vista son:
Username El nombre de usuario (puede ser 'PUBLIC').
Granted_Role El nombre del rol concedido al usuario.
Admin_Option Un indicador de si el rol fue concedido con WITH ADMIN OPTION.
Default_Role Un indicador de si el rol es un rol por defecto de usuario.
OS_Granted Un indicador de si el sistema operativo est siendo usado para gestionar roles.
Para mostrar todos los roles disponibles en la base de datos, necesitamos tener autoridad de DBA; entonces
podemos usar la vista DBA_ROLES para consultar todos los roles. La vista DBA_ROLE_PRIVS muestra todas las
asignaciones de estos roles a todos los usuarios de la base de datos.
Los roles pueden recibir tres tipos diferentes de concesiones, cada una de las cuales se corresponde con una
vista del diccionario de datos:
De tabla/columna ROLE_TAB_PRIVS. Similar a USER_TAB_PRIVS y USER_COL_PRIVS, excepto que
tienen una columna Role en vez de la columna Grantee, y no tiene la columna Grantor.
Permisos de sistema ROLE_SYS_PRIVS. Similar a USER_SYS_PRIVS, excepto que tiene una columna Role
en vez de la columna Username.
De rol ROLE_ROLE_PRIVS. Muestra todos los roles que han sido concedidos a otros roles.

Nota. Si no somos DBA, estas vistas del diccionario de datos muestran solo los roles que nos han
sido concedidos.
Adems de estas vistas, hay dos vistas, cada una con una nica columna, que muestran los permisos y roles
habilitados para la sesin actual:
SESSION_PRIVS La columna Privilege muestra todos los permisos de sistema habilitados para la
sesin, tanto concedidos directamente o a travs de roles.
SESSION_ROLES La columna Role muestra todos los roles de la sesin actual.
Las vistas SESSION_PRIVS y SESSION_ROLES estn disponibles para todos los usuarios.
1.13. Auditora.
Si no se es un usuario DBA dentro de una base de datos de Oracle no se pueden habilitar las caractersticas
de auditora de la base de datos. Si la auditora ha sido habilitada hay varias vistas del diccionario de datos que
alguien puede usar para ver los resultados de auditora.
Hay muchos resultados de auditora que podemos ver mediante vistas del diccionario de datos. La mayora de
estas vistas estn basadas sobre una nica tabla de resultados de auditora llamada SYS.AUD$. La ms genrica
de las vistas de resultados de auditora se denomina USER_AUDIT_TRAIL. Sus columnas se describen a
continuacin.
Nombre col. Descripcin
OS_Username La cuenta del sistema operativo del usuario.
Username El nombre de usuario Oracle del usuario auditado.
UserHost Un ID numrico de la instancia usada por el usuario auditado.
Terminal El identificador de terminal del sistema operativo del usuario.
TimeStamp La fecha y hora en que fue creado el registro auditado.
Owner El propietario del objeto afectado por una accin (para acciones de auditora).
Obj_Name El nombre del objeto afectado por una accin (para acciones de auditora).
Action El cdigo numrico para la accin de auditora.
Action_Name El nombre de la accin de auditora.
New_Owner El propietario del objeto nombrado en la columna New_Name.
New_Name El nuevo nombre de un objeto que ha sido renombrado.

Oracle /318
Obj_Privilege El permiso de objeto que ha sido concedido o revocado.
Sys_Privilege El permiso de sistema que ha sido concedido o revocado.
Admin_Option Un indicador Y/N de si el rol o permiso de sistema fue concedido con WITH ADMIN
OPTION.
Grantee El nombre de usuario especificado en un comando GRANT o REVOKE.
Audit_Option Las opciones de auditora asignadas mediante el comando AUDIT.
Ses_Actions Una cadena de caracteres que sirve como resumen de sesin, registrando sucesos y
fallos de diferentes acciones.
Logoff_Time La fecha y hora de la salida de sesin del usuario.
Logoff_LRead El nmero de lecturas lgicas realizadas durante la sesin.
Logoff_PRead El nmero de lecturas fsicas realizadas durante la sesin.
Logoff_LWrite El nmero de escrituras lgicas realizadas durante la sesin.
Logoff_DLock El nmero de bloqueos detectados durante la sesin.
Comment_Text Un comentario de texto sobre la entrada de seguimiento de auditora.
SessionID El ID numrico de la sesin.
EntryID Un ID numrico de la entrada de seguimiento de auditora.
StatementID El ID numrico para cada comando que fue ejecutado.
ReturnCode El cdigo de retorno de cada comando que fue ejecutado; si el comando sucedi sin
fallos, el cdigo de retorno ser cero.
Priv_Used El permiso de sistema usado para ejecutar la accin.
Client_ID El ID cliente.
Session_CPU La sesin de CPU usada.
Extended_Timestamp Fecha y hora de la creacin de la entrada se seguimiento de auditora en la zona
horaria de la sesin.
Proxy_SessionID Nmero de serie del proxy de sesin, si el usuario empresarial ha iniciado sesin
mediante un mecanismo de proxy.
Global_UID Identificador global del usuario, si el usuario ha iniciado sesin como un usuario
empresarial.
Instance_Number Nmero de instancia especificado en el fichero de inicializacin de parmetros.
OS_Process Identificador del proceso del sistema operativo del proceso servidor de Oracle.
TransactionID Identificador de transaccin de la transaccin en la cual el objeto es accedido o
modificado.
SCN SCN de la consulta.
SQL_Bind Variable de enlace de la consulta.
SQL_Text Texto de la consulta.
Aunque esta vista muestra registros de auditora para muchos tipos diferentes de acciones, muchas de las
columnas pueden ser inaplicables para alguna de las filas. La versin DBA_ de esta vista, DBA_AUDIT_TRAIL,
muestra todas las entradas de la tabla de seguimiento de auditoras; USER_AUDIT_TRAIL muestra slo aquellas
relevantes para el usuario.
Desde Oracle Database 10g, hay nuevas columnas en USER_AUDIT_TRAIL, incluyendo SQL_Text, SQL_Bind,
OS_Process, y SCN.
Cada tipo de auditora puede ser accedido mediante su propia vista del diccionario de datos. Las siguientes
son las vistas disponibles:
USER_AUDIT_OBJECT Para comandos concernientes a objetos.
USER_AUDIT_SESSION Para conexiones y desconexiones.
USER_AUDIT_STATEMENT Para comandos GRANT, REVOKE, AUDIT, NOAUDIT, y ALTER SYSTEM
realizados por el usuario.
Hay versiones DBA_ de esas tres vistas.
Podemos ver las opciones de auditora que actualmente afectan a nuestros objetos consultando la vista
USER_OBJ_AUDIT_OPTS. Para cada objeto mostrado en USER_OBJ_AUDIT_OPTS, las opciones de auditoria
de cada comando que puede ser ejecutado sobre estos objetos (identificados por las columnas Object_Name y
Object_Type) se muestran en USER_OBJ_AUDIT_OPTS. Los nombres de columna de USER_OBJ_AUDIT_OPTS
se corresponden a las primeras letras del comando (por ejemplo, Alt para ALTER, Upd para UPDATE, etc.). Cada
columna ser registrada si el comando es auditado para el objeto cuando suceda el comando ( 'S'), no suceda
('U') o ambos. Las opciones de auditora por defecto en efecto para cualquier nuevo objeto de la base de

Oracle /319
datos pueden ser mostradas mediante la vista ALL_DEF_AUDIT_OPTS, la cual tiene las mismas columnas que
USER_OBJ_AUDIT_OPTS. La vista USER_OBJ_AUDIT_OPTS incluye las columnas Object_Name y Object_Type.
Los comandos que pueden ser auditados son almacenados en una tabla de referencia llamada
AUDIT_ACTIONS, la cual tiene dos columnas: Action (el cdigo numrico de la accin) y Name (el nombre de la
accin o comando). Action y Name se corresponden con las columnas Action y Action_Name de
USER_AUDIT_TRAIL.
Los DBA's pueden usar varias vistas de auditora adicionales que no tienen su contrapartida USER_,
incluyendo DBA_AUDIT_EXISTS, DBA_PRIV_AUDIT_OPTS, DBA_STMT_AUDIT_OPTS, y
STMT_AUDIT_OPTION_MAP.
1.14. Supervisin: las tablas de rendimiento dinmico V$.
Las vistas que supervisan el rendimiento del entorno de base de datos son llamadas vistas de rendimiento
dinmico. Estas vistas son referenciadas normalmente como tablas V$, porque todas ellas comienzan con este
trmino.
La definicin y uso de columnas dentro de las vistas de supervisin estn sujetos a cambios con cada versin
de la base de datos. Las tablas V$ son usadas normalmente slo por el DBA.
1.14.1. La tabla CHAINED_ROWS.
Se puede usar el comando ANALYZE para generar un listado de las filas encadenadas o migradas dentro de una
tabla. Este listado de filas encadenadas puede ser almacenado en una tabla llamada CHAINED_ROWS. Para
crear la tabla CHAINED_ROWS en nuestro esquema podemos ejecutar el script utlchain.sql (que normalmente se
encuentra en el subdirectorio /rdbms/admin del directorio de instalacin de Oracle).
Fichero utlchain.sql
rem
rem $Header: utlchain.sql 07-may-96.19:40:01 sbasu Exp $
rem
Rem Copyright (c) 1990, 1995, 1996, 1998 by Oracle Corporation
Rem NAME
REM UTLCHAIN.SQL
Rem FUNCTION
Rem Creates the default table for storing the output of the
Rem analyze list chained rows command
Rem NOTES
Rem MODIFIED
Rem syeung 06/17/98 - add subpartition_name
Rem mmonajje 05/21/96 - Replace timestamp col name with analyze_timestam
Rem sbasu 05/07/96 - Remove echo setting
Rem ssamu 08/14/95 - merge PTI with Objects
Rem ssamu 07/24/95 - add field for partition name
Rem glumpkin 10/19/92 - Renamed from CHAINROW.SQL
Rem ggatlin 03/09/92 - add set echo on
Rem rlim 04/29/91 - change char to varchar2
Rem Klein 01/10/91 - add owner name for chained rows
Rem Klein 12/04/90 - Creation
Rem

create table CHAINED_ROWS (


owner_name varchar2(30),
table_name varchar2(30),
cluster_name varchar2(30),
partition_name varchar2(30),
subpartition_name varchar2(30),
head_rowid rowid,
analyze_timestamp date
);
Para poblar la tabla CHAINED_ROWS hay que usar la clusula LIST CHAINED ROWS INTO del comando
ANALYZE, tal como se muestra a continuacin:
ANALYZE TABLE Festivos LIST CHAINED ROWS INTO CHAINED_ROWS;

Oracle /320
La tabla CHAINED_ROWS muestra las columnas Owner_Name, Table_Name, Cluster_Name (si la tabla es un
clster), Partition_Name (si la tabla est particionada), Subpartition_Name (si la tabla contiene subparticiones),
Head_RowID (el ROWID de la fila) y Analyze_TimeStamp (que muestra la ltima vez que la tabla o clster fue
analizado). Podemos consultar la tabla segn los valores de Head_RowID, como en el siguiente ejemplo:
SELECT *
FROM Festivos
WHERE RowID IN
(SELECT Head_RowID FROM CHAINED_ROWS WHERE Table_Name = 'Festivo');
Si la fila encadenada es de poca longitud, entonces podemos eliminar el encadenamiento borrando y
reinsertando la fila.
1.14.2. La tabla PLAN_TABLE.
Cuando afinamos comandos SQL podemos querer determinar los pasos que el optimizador realiz para
ejecutar nuestra consulta. Para ver la ruta de la consulta debemos primero crear una tabla en nuestro esquema
llamada PLAN_TABLE. El script usando para crear esta tabla se denomina utlxplan.sql, y normalmente se
almacena en el subdirectorio /rdbms/admin.
Fichero utlxplan.sql
rem
rem $Header: utlxplan.sql 08-may-2004.12:53:19 bdagevil Exp $ xplainpl.sql
rem
Rem Copyright (c) 1988, 2004, Oracle. All rights reserved.
Rem NAME
REM UTLXPLAN.SQL
Rem FUNCTION
Rem NOTES
Rem MODIFIED
Rem bdagevil 05/08/04 - add other_xml column
Rem bdagevil 06/18/03 - rename hint alias to object_alias
Rem ddas 06/03/03 - increase size of hint alias column
Rem bdagevil 02/13/03 - add plan_id and depth column
Rem ddas 01/17/03 - add query_block and hint_alias columns
Rem ddas 11/04/02 - revert timestamp column to DATE (PL/SQL problem)
Rem ddas 10/28/02 - change type of timestamp column to TIMESTAMP
Rem ddas 10/03/02 - add estimated_time column
Rem mzait 04/16/02 - add row vector to the plan table
Rem mzait 10/26/01 - add keys and filter predicates to the plan table
Rem ddas 05/05/00 - increase length of options column
Rem ddas 04/17/00 - add CPU, I/O cost, temp_space columns
Rem mzait 02/19/98 - add distribution method column
Rem ddas 05/17/96 - change search_columns to number
Rem achaudhr 07/23/95 - PTI: Add columns partition_{start, stop, id}
Rem glumpkin 08/25/94 - new optimizer fields
Rem jcohen 11/05/93 - merge changes from branch 1.1.710.1 - 9/24
Rem jcohen 09/24/93 - #163783 add optimizer column
Rem glumpkin 10/25/92 - Renamed from XPLAINPL.SQL
Rem jcohen 05/22/92 - #79645 - set node width to 128 (M_XDBI in gendef)
Rem rlim 04/29/91 - change char to varchar2
Rem Peeler 10/19/88 - Creation
Rem
Rem This is the format for the table that is used by the EXPLAIN PLAN
Rem statement. The explain statement requires the presence of this
Rem table in order to store the descriptions of the row sources.

create table PLAN_TABLE (


statement_id varchar2(30),
plan_id number,
timestamp date,
remarks varchar2(4000),

Oracle /321
operation varchar2(30),
options varchar2(255),
object_node varchar2(128),
object_owner varchar2(30),
object_name varchar2(30),
object_alias varchar2(65),
object_instance numeric,
object_type varchar2(30),
optimizer varchar2(255),
search_columns number,
id numeric,
parent_id numeric,
depth numeric,
position numeric,
cost numeric,
cardinality numeric,
bytes numeric,
other_tag varchar2(255),
partition_start varchar2(255),
partition_stop varchar2(255),
partition_id numeric,
other long,
distribution varchar2(30),
cpu_cost numeric,
io_cost numeric,
temp_space numeric,
access_predicates varchar2(4000),
filter_predicates varchar2(4000),
projection varchar2(4000),
time numeric,
qblock_name varchar2(30),
other_xml clob
);
Despus de crear esta tabla podemos usar el comando EXPLAIN PLAN, el cual generar registros en nuestra
tabla PLAN_TABLE, etiquetando el valor Statement_ID podemos especificar la consulta que queremos
desgranar.
Las columnas ID y Parent_ID de la tabla PLAN_TABLE establecen la jerarqua de pasos (Operations) que el
optimizador sigue cuando ejecuta la consulta.
1.14.3. Interdependencias: USER_DEPENDENCIES y IDEPTREE.
Unos objetos dentro de las bases de datos de Oracle pueden depender de otros. Por ejemplo, un
procedimiento almacenado puede depender de una tabla, o un paquete pude depender de un cuerpo de
paquete. Cuando un objeto dentro de la base de datos cambia, cualquier objeto procedimental que depende
de l tendr que ser recompilado. Esta recompilacin puede ser automtica (con una penalizacin
consecuente del rendimiento) o manualmente.
Dos conjuntos de vistas del diccionario de datos estn disponibles para ayudarnos a trazar dependencias. El
primero es USER_DEPENDENCIES, el cual muestra todas las dependencias directas de los objetos. Sin embargo,
esta vista slo muestra el primer nivel de dependencias. Para evaluar completamente el rbol de dependencias
debemos crear objetos de seguimiento de dependencias recursivas en nuestro esquema. Para crear estos
objetos hay que ejecutar el script utldtree.sql (normalmente localizado en el subdirectorio /rdbms/admin). Este
script crea dos objetos que podemos consultar: DEPTREE y IDEPTREE. Estos objetos contienen informacin
idntica, pero IDEPTREE est indentada segn la pseudo-columna Level, y por tanto es fcil de leer e
interpretar.
Parte del contenido del fichero utldtree.sql
drop sequence deptree_seq
/
create sequence deptree_seq cache 200 /* cache 200 to make sequence faster */

Oracle /322
/
drop table deptree_temptab
/
create table deptree_temptab
(
object_id number,
referenced_object_id number,
nest_level number,
seq# number
)
/
create or replace procedure deptree_fill (type char, schema char, name char) is
obj_id number;
begin
delete from deptree_temptab;
commit;
select object_id into obj_id from all_objects
where owner = upper(deptree_fill.schema)
and object_name = upper(deptree_fill.name)
and object_type = upper(deptree_fill.type);
insert into deptree_temptab
values(obj_id, 0, 0, 0);
insert into deptree_temptab
select object_id, referenced_object_id, level, deptree_seq.nextval
from public_dependency
connect by prior object_id = referenced_object_id
start with referenced_object_id = deptree_fill.obj_id;
exception
when no_data_found then
raise_application_error(-20000, 'ORU-10013: ' ||
type || '' || schema || '.' || name || ' was not found.');
end;
/
drop view deptree
/

create view sys.deptree (nested_level, type, schema, name, seq#)


as
select d.nest_level, o.object_type, o.owner, o.object_name, d.seq#
from deptree_temptab d, dba_objects o
where d.object_id = o.object_id (+)
union all
select d.nest_level+1, 'CURSOR', '<shared>', '"'||c.kglnaobj||'"', d.seq#+.5
from deptree_temptab d, x$kgldp k, x$kglob g, obj$ o, user$ u, x$kglob c,
x$kglxs a
where d.object_id = o.obj#
and o.name = g.kglnaobj
and o.owner# = u.user#
and u.name = g.kglnaown
and g.kglhdadr = k.kglrfhdl
and k.kglhdadr = a.kglhdadr /* make sure it is not a transitive */
and k.kgldepno = a.kglxsdep /* reference, but a direct one */
and k.kglhdadr = c.kglhdadr
and c.kglhdnsp = 0 /* a cursor */
/

create view deptree (nested_level, type, schema, name, seq#)


as
select d.nest_level, o.object_type, o.owner, o.object_name, d.seq#

Oracle /323
from deptree_temptab d, all_objects o
where d.object_id = o.object_id (+)
/

drop view ideptree


/
create view ideptree (dependencies)
as
select lpad('',3*(max(nested_level))) || max(nvl(type, '<no permission>')
|| '' || schema || decode(type, NULL, '', '.') || name)
from deptree
group by seq# /* So user can omit sort-by when selecting from ideptree */
/

1.14.4. Seguridad de etiquetas de Oracle.


Los usuarios de la Seguridad de etiquetas de Oracle disponen de vistas adicionales del diccionario de datos,
incluyendo ALL_SA_GROUPS, ALL_SA_POLICIES, ALL_SA_USERS, y ALL_SA_USER_PRIVS.
1.14.5. Vistas de carga directa de SQL*Loader.
Para controlar la opciones de carga directa de SQL*Loader, Oracle mantiene varias vistas del diccionario de
datos. stas son generalmente slo consultadas para propsitos de depuracin. Las vistas que soportan la
opcin de carga directa son LOADER_COL_INFO, LOADER_CONSTRAINT_INFO, LOADER_FILE_TS,
LOADER_PARAM_INFO, LOADER_PART_INFO, LOADER_REF_INFO, LOADER_TAB_INFO y
LOADER_TRIGGER_INFO.
Estas vistas son creadas mediante el script catldr.sql, normalmente localizado en el subdirectorio /rdbms/admin.
1.14.6. Vista para soportar globalizacin.
Tres vistas del diccionario de datos muestran informacin sobre los parmetros de soporte de globalizacin
que se estn aplicando actualmente en la base de datos. Valores no estndar para los parmetros NLS (como
NLS_DATE_FORMAT y NLS_SORT) pueden asignarse mediante el fichero de parmetros de la base de datos o
mediante el comando ALTER SESSION.
Para ver las asignaciones NLS de nuestra sesin, instancia y base de datos podemos consultar las vistas
NLS_SESSION_PARAMETERS, NLS_INSTANCE_PARAMETERS, y NLS_DATABASE_PARAMETERS,
respectivamente.
1.14.7. Libreras.
Nuestras rutinas PL/SQL pueden ser programas C externos. Para ver de qu libreras externas somos
propietarios, podemos consultar la vista USER_LIBRARIES, la cual muestra el nombre de la librera
(Library_Name), el fichero asociado (File_Spec), si la librera es no dinmica (Dynamic), y el estado de la librera
(Status). Tambin estn disponibles las vistas ALL_LIBRARIES y DBA_LIBRARIES, que incluyen la columna
adicional Owner.
1.14.8. Servicios heterogneos.
Para soportar la gestin de servicios heterogneos, Oracle proporciona varias vistas del diccionario de datos.
Todas las vistas de esta categora comienzan con HS_ en vez de DBA_. En general, estas vistas son usadas
principalmente por los DBA's.
1.14.9. Tipos de ndices y operadores.
Los operadores y tipos de ndices estn estrechamente relacionados. Podemos usar el comando CREATE
OPERATOR para crear un nuevo operador y definir sus enlaces. Podemos referenciar operadores en tipos de
ndices en comandos SQL. Los operadores, a su vez, referencian funciones, paquetes, tipos y otros objetos
definidos por el usuario.
Podemos consultar la vista USER_OPERATORS para ver de cada operador su propietario ( Owner), nombre
(Operator_Name), y nmero de enlaces (Number_of_Binds). La informacin auxiliar para los operadores es
accesible mediante la vista USER_OPANCILLARY, y podemos consultar USER_OPARGUMENTS para ver los
argumentos de los operadores. Podemos consultar USER_OPBINDINGS para ver los enlaces de operadores.
La vista USER_INDEXTYPE_OPERATORS muestra los operadores soportados por tipos de ndices. Los tipos de
ndices pueden ser mostrados mediante la vista USER_INDEXTYPES.
Existen versiones ALL_ y DBA_ de estas vistas. Desde Oracle Database 10g, podemos ver los tipos de ndices
de tipos de arrays mediante la vista USER_INDEXTYPE_ARRAYTYPES.

Oracle /324
1.14.10. Outlines.
Cuando usamos outlines almacenados, podemos recuperar sus nombres y detalles mediante la vista
USER_OUTLINES. Para ver las marcas que constituyen los outlines, podemos consultar
USER_OUTLINE_HINTS.
Hay versiones ALL_ y DBA_ de USER_OUTLINES y USER_OUTLINE_HINTS.
1.14.11. Consejeros.
Desde Oracle Database 10g, los usuarios pueden acceder a vistas del diccionario de datos relacionadas con las
recomendaciones para afinar. Estas vistas empiezan con USER_ADVISOR_ y tienen sus correspondientes
versiones DBA_.
Por ejemplo, USER_ADVISOR_ACTIONS contiene datos sobre las acciones asociadas con todas las
recomendaciones en la base de datos. Cada accin se especifica en la columna Command, con seis columnas de
atributos relacionados. USER_ADVISOR_LOG muestra informacin sobre el estado actual de todas las tareas,
como los datos especficos de ejecucin, el progreso de supervisin y el estado completo.
Los parmetros para los consejeros son accesibles mediante la vista USER_ADVISOR_PARAMETERS; podemos
ver las exposiciones razonadas para recomendaciones mediante la vista USER_ADVISOR_RATIONALE.
Para los resultados de un anlisis de todas las recomendaciones en la base de datos podemos consultar la vista
USER_ADVISOR_RECOMMENDATIONS. Una recomendacin puede tener varias acciones asociadas (ver
USER_ADVISOR_ACTIONS) basadas en las exposiciones razonadas usadas.
1.14.12. Planificadores.
Desde Oracle Database 10g, podemos acceder a un conjunto de vistas relacionadas con las tareas de
planificacin en la base de datos. Estas vistas incluyen USER_SCHEDULER_JOBS (todas las tareas planificadas
propiedad del usuario), USER_SCHEDULER_PROGRAMS (las tareas programadas), y
USER_SCHEDULER_PROGRAM_ARGS (los argumentos para los programas programados). Podemos ver los
detalles de ejecucin mediante las vistas USER_SCHEDULER_JOB_LOG, USER_SCHEDULER_JOB_RUN_DETAILS,
y USER_SCHEDULER_RUNNING_JOBS. Podemos ver los planificadores mediante
USER_SCHEDULER_SCHEDULES.

2. Administracin de la base de datos.


En este captulo veremos los pasos involucrados en la administracin de Oracle Database 11g. Hay muchos
componentes para las tareas de los administradores de base de datos (DBA). Las tareas bsicas consisten de la
creacin de una base de datos, iniciar y parar la base de datos, dar tamao y controlar las reas de memoria de
la base de datos, asignar y gestionar espacio para los objetos, crear y gestionar recuperaciones y realizar copias
de respaldo.
2.1. Creacin de una base de datos.
El modo ms simple de generar un script de creacin de una base de datos es mediante el Instalador
Universal de Oracle (OUI). Cuando instalamos Oracle, el OUI nos da la opcin de crear una base de datos. Si
usamos esta opcin, OUI crear una base de datos que es normalmente usada para practicar o que ser la
base para el desarrollo de nuestras aplicaciones.
El comando CREATE DATABASE se utiliza con SQL*Plus, a travs de una cuenta con el permiso de sistema
SYSDBA:
CONNECT system/contrasea AS SYSDBA
STARTUP NOMOUNT
CREATE DATABASE . . .
Para intentar conectarse como un SYSDBA debemos tener la apropiada autorizacin en los niveles del
sistema operativo y la base de datos.
2.1.1. Usando el Oracle Enterprise Manager.
Oracle Enterprise Manager (OEM), es una herramienta con interfaz grfica de usuario. Las herramientas
incluidas en OEM proporcionan una interfaz robusta para administrar bases de datos remotas. Todos los
DBA's pueden usar el mismo repositorio central OEM (un conjunto de tabla creadas en una base de datos)
para realizar sus trabajos. Adems, OEM incluye un planificador de tareas.
Debemos tomar varias decisiones clave antes de instalar y configurar OEM. Necesitamos decidir donde se
crear el repositorio OEM y cmo y cundo se harn copias de respaldo para proteger este repositorio.
Aunque podemos usar OEM como una interfaz para el Oracle Recovery Manager (RMAN), la informacin
de recuperacin puede ser almacenada en el repositorio OEM. Se puede crear una base de datos mnima

Oracle /325
independiente para almacenar el repositorio OEM. Deberemos asegurarnos de que esta base de datos sea
respaldada con frecuencia de forma que la recuperacin del repositorio mismo est asegurada.
2.2. Iniciacin y parado de la base de datos.
Para iniciar una base de datos se usa el comando STARTUP dentro de SQL*Plus, tal como se muestra en el
siguiente ejemplo:
CONNECT system/contrasea AS SYSDBA;
STARTUP OPEN MiBD;
Alternativamente, podemos montar la base de datos:
CONNECT system/contrasea AS SYSDBA;
STARTUP MOUNT MiBD;
Cuando la base de datos es montada pero no abierta, podemos gestionar sus ficheros. Por ejemplo, si
movemos alguno de los ficheros de la base de datos mientras sta fue parada, necesitamos decirle a Oracle
saber dnde encontrarlos antes de reiniciarla. Para obtener la nueva ubicacin de los ficheros, podemos
montar la base de datos y entonces usar el comando ALTER DATABASE para renombrar los antiguos ficheros a
su nueva localizacin. Una vez que hemos finalizado de decirle a Oracle la nueva localizacin para los
ficheros, podemos abrir la base de datos mediante al comando ALTER DATABASE OPEN.
Hay cuatro opciones primarias para parar la base de datos. En una parada normal ( SHUTDOWN NORMAL),
Oracle espera a que todos los usuarios salgan de la base de datos antes de pararla. En una parada
transaccional (SHUTDOWN TRANSACTIONAL), Oracle espera que las transacciones activas se completen antes
de parar. En una parada inmediata ( SHUTDOWN IMMEDIATE), Oracle da marcha atrs a las transacciones no
confirmadas y finaliza la sesin de cualquier usuario). En una parada abortada ( SHUTDOWN ABORT), la base
de datos se para inmediatamente y cualquier transaccin no confirmada se pierde.
Nota. Cuando la base de datos est en proceso de parar o iniciarse, no se permiten nuevos inicios
de sesin.
Por ejemplo, para realizar una parada inmediata de la base de datos:
CONNECT system/contrasea AS SYSDBA;
SHUTDOWN IMMEDIATE
2.3. Tamao y gestin de las reas de memoria.
Cuando iniciamos una base de datos, Oracle asignar un rea de memoria (el System Global Area, o SGA)
compartida por todos los usuarios de la base de datos. Las dos reas ms grandes del SGA son normalmente
el bfer cach de la base de datos y el "pool" compartido; sus tamaos impactan directamente en los
requerimientos de memoria de la base de datos y el rendimiento de sus operaciones. Sus tamaos son
controlados por parmetros del fichero de inicializacin de la base de datos.
El bfer cach de la base de datos es un rea del SGA usado para contener los bloques de datos que son
ledos desde los segmentos de datos de la base de datos, como las tablas e ndices. El tamao del bfer cach
de la base de datos es determinados por el parmetro DB_CACHE_SIZE (expresado en nmero de bytes) en el
fichero de parmetros de inicializacin de la base de datos. Por su parte, el tamao por defecto para los
bloques de la base de datos se asigna mediante el parmetro DB_BLOCK_SIZE.
Gestionar el tamao del bfer cach es una parte importante de controlar y afinar la base de datos. La base de
datos tiene un tamao de bloque por defecto, pero podemos establecer reas de cach para diferentes
tamaos de bloques y entonces crear tablespaces para que usen estas cachs. Por ejemplo, podemos crear un
bloque de 4 KB con algunos tablespaces asignados a 8 KB. El tamao de cach de 8 KB debera ser asignado
mediante el parmetro DB_8K_CACHE_SIZE. Para crear tablespaces que usen esta cach debemos especificar
BLOCKSIZE 8K como parte del comando CREATE TABLESPACE. Si el tamao de bloque por defecto de la base
de datos es 4 KB no deberamos asignar un valor para DB_4K_CACHE_SIZE; el tamao especificado por
DB_CACHE_SIZE debera ser usado por la cach de 4 KB.

Nota. La cach para el tamao de bloque debe existir antes de crear un tablespace que use este
tamao de bloque.
Las diferentes reas de cach pueden ser redimensionadas mientras la base de datos se est ejecutando. Las
cachs deben ser incrementadas o decrementadas en grnulos. Para una base de datos con un SGA menor de
128M, el tamao de grnulo es 4M as DB_8K_CACHE_SIZE puede ser 4M, 8M, 12M, y dems. Si
intentamos usar cualquier otro valor, Oracle lo redondear al tamao de grnulo mayor ms prximo. El

Oracle /326
siguiente comando muestra cmo asignar el parmetro DB_8K_CACHE_SIZE.
ALTER SYSTEM SET DB_8K_CACHE_SIZE = 8M;
Si creamos un tablespace que use un tamao de bloque distinto del de por defecto, debemos asegurarnos de
que el parmetro de tamao de cach relacionado (como DB_8K_CACHE_SIZE) sea actualizado en nuestro
fichero de parmetros de base de datos. Si estamos usando un fichero init.ora, debemos actualizarlo con el
nuevo valor. Si estamos usando un fichero de parmetros de sistema (el mtodo preferido), se actualizar
automticamente cuando ejecutemos el comando ALTER SYSTEM con la clusula SCOPE=BOTH.
Nota. No podemos alterar el valor de los parmetros SGA_MAX_SIZE o JAVA_POOL_SIZE mientras
la base de datos est abierta.
Oracle gestionar el espacio en el bfer cach usando un algoritmo que guarde los bloques usados ms
activos en lo que sea posible. Cuando es necesario espacio libre en la cach, los nuevos bloques intentarn
usar el espacio ocupado por boques accedidos con poca frecuencia o el espacio ocupado por un bloque
modificado una vez que ha sido escrito al disco.
Si el SGA no es suficientemente grande para contener los datos ms frecuentemente usados, diferentes
objetos competirn por el espacio de la cach. La competicin se producir particularmente cuando varias
aplicaciones usen la misma base de datos y compartan el mismo SGA. En este caso, las tablas e ndices
usados ms recientemente para cada aplicacin constantemente competirn por espacio en el SGA. Como
resultado, solicitudes de datos provocan frecuentes lecturas/escrituras fsicas de datos, provocando
degradacin en el rendimiento.
El "pool" compartido almacena la cach del diccionario de datos (informacin sobre la estructura de base de
datos) y la cach de librera (informacin sobre los comandos que se ejecutan sobre la base de datos).
Mientras la cach de bloque de datos y la cach del diccionario permiten compartir la estructura e
informacin de datos entre usuarios de la base de datos, la cach de biblioteca permite compartir los
comando SQL ms usados normalmente. El "pool" compartido contiene el plan de ejecucin y rbol de
reconocimiento de los comandos SQL que se ejecutan sobre la base de datos. La segunda vez que un
comando SQL idntico se ejecuta (por algn usuario), Oracle es capaz de tomar ventajas de la informacin
del "pool" compartido para servir la ejecucin del comando.
El tamao en bytes del "pool" compartido se asigna mediante el parmetro de inicializacin
SHARED_POOL_SIZE. Como con otras cachs, el "pool" compartido puede ser modificado mientras la base de
datos est abierta.
Desde Oracle Database 10g, podemos usar el Automatic Shared Memory Management (ASMM). Para activar
el ASMM, se asigna un valor no cero al parmetro de inicializacin SGA_TARGET. Despus de asignar
SGA_TARGET al tamao de SGA deseado entonces debemos asignar los otros parmetros de cach
relacionados (DB_CACHE_SIZE, SHARED_POOL_SIZE, JAVA_POOL_SIZE, y LARGE_POOL_SIZE) a cero.
Debemos parar y reiniciar la base de datos para que estos cambios sean efectivos.
Podemos supervisar el tamao de las cachs mediante la vista de rendimiento dinmica V$SGASTAT.
Nota. Mientras la base de daos se est ejecutando, podemos modificar el parmetro SGA_TARGET y
Oracle modificar automticamente el tamao de las cachs relacionadas.
Si la carga de trabajo en la base de datos cambia, la base de datos modificar los tamaos de cach para
reflejar las necesidades de la aplicacin. Por ejemplo, si hay un proceso por lotes intensivo durante la noche y
una transaccin en lnea intensiva durante el da, la base de datos puede modificar los tamaos de cach cada
vez que cambie la carga. Estos cambios ocurren automticamente, si la intervencin del DBA.
2.4. Asignar y gestionar espacio para objetos.
Cuando una base de datos se crea, se divide en varias secciones lgicas llamadas tablespaces. El tablespace
SYSTEM es el primero es ser creado, y el tablespace SYSAUX es creado como parte de cada base de datos de
Oracle Database 11g. Podemos crear tablespaces adicionales para contener varios tipos de datos (como
tablas, ndices y segmentos de deshacer). Desde Oracle Database 10g, los tablespaces pueden ser
renombrados mediante la clusula RENAME del comando ALTER TABLESPACE.
Cuando se crea un tablespace, se crean ficheros de datos para contener los datos. Estos ficheros son
inmediatamente asignados al espacio especificado durante su creacin. Cada fichero de datos puede estar en
un nico tablespace. Los ficheros de datos se pueden extender automticamente cuando se ejecutan fuera del
espacio asignado; podemos asignar el incremento por el cual se extiende y su tamao mximo. Cada esquema

Oracle /327
de usuario es una coleccin de objetos lgicos de la base de datos, como tablas e ndices, que referencian
estructuras de datos fsicas almacenadas en los tablespaces. Los objetos de un esquema de usuario pueden
almacenar varios tablespaces, y un nico tablespace puede contener objetos de varios esquemas.
Cuando un objeto de base de datos (como una tabla o ndice) se crea, es asignado a un tablespace mediante
una asignacin por defecto o especificndolo en la instruccin. Se crea un segmento en el tablespace para
contener los datos asociados con el objeto.
Un segmento est constituido por secciones llamadas extensiones (conjunto de bloques Oracle contiguos).
Una vez las extensiones existentes no puede contener ms datos, el segmento obtendr otra extensin. Si el
segmento est compuesto de varias extensiones, no hay garantas de que las extensiones sean contiguas.
Los tablespaces pueden ser creados para gestionar localmente (por defecto) o por el diccionario. En un
tablespace gestionado por diccionario, la informacin de localizacin de extensiones se almacena en el
diccionario de datos. En un tablespace gestionado localmente, los datos son almacenados en las cabeceras de
los ficheros de datos. Oracle recomienda el uso de tablespaces gestionados localmente.
2.4.1. Implicaciones de la clusula storage.
La cantidad de espacio usado por un segmento est determinado por sus parmetros de almacenamiento.
Estos parmetros se determinan en el momento de creacin de los segmentos de base de datos; si no
especificamos parmetros de almacenamiento en el comando CREATE TABLE, CREATE INDEX, o CREATE
CLUSTER, entonces la base de datos usar los parmetros de almacenamiento por defecto del tablespace el
cual es segmento se almacena.
Nota. Podemos asignar un tablespace por defecto a los usuarios, y asignar cuotas de espacio dentro
de estos tablespaces, mediante los comandos CREATE USER, ALTER USER, y GRANT.
Cuando creamos una tabla, ndice u otro segmento, podemos usar los valores por defecto para tablespaces
gestionados localmente (la opcin recomendada) o especificar una clusula STORAGE como parte del
comando CREATE. Tambin podemos especificar una clusula TABLESPACE, habilitando que Oracle
directamente almacene datos en un tablespace en particular. Por ejemplo, un comando CREATE TABLE en un
tablespace gestionado por diccionario puede incluir las siguientes clusulas:
TABLESPACE USERS
STORAGE (INITIAL 1M NEXT 1M PCTINCREASE 0 MINEXTENTS 1 MAXEXTENTS 200)
Si no especificamos la clusula STORAGE, los parmetros de almacenamiento por defecto del tablespace sern
usados. Para un tablespace USERS gestionado localmente, el comando CREATE TABLE debera slo necesitar
incluir TABLESPACE USERS.
Los parmetros de almacenamiento especifican el tamao de extensin inicial, el tamao de la extensin
siguiente, el PCTINCREASE (un factor por el cual la siguiente extensin ser geomtricamente dimensionada),
la mxima extensin (MAXEXTENTS), y el nmero mnimo de extensiones (MINEXTENTS). Despus de creado
el segmento, los valores INITIAL y MINEXTENTS no pueden modificarse a menos que realicemos una
reorganizacin del objeto. Los valores por defecto de los parmetros de almacenamiento estn disponibles en
las vistas DBA_TABLESPACES y USER_TABLESPACES.
Cuando creamos un tablespace, podemos especificar los valores por defecto de los parmetros de
almacenamiento. El siguiente comando crea un tablespace gestionado localmente y especifica los parmetros
por defecto:
CREATE TABLESPACE Tablas_Codigos
DATAFILE '/u01/oracle/VLDB/codes_tables.dbf' SIZE 10M
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 256K;
Cuando se crea un segmento, adquiere al menos una extensin. La extensin inicial ser usada para almacenar
datos hasta que no hay ms espacio disponible (puede usarse la clusula PCTFREE para reservar un porcentaje
de espacio dentro de cada bloque en el segmento para actualizaciones de los registros existentes). Si creamos
un tablespace gestionado por diccionario, los tamaos de extensiones pueden ser no uniformes; el segmento
se extender obteniendo una segunda extensin del tamao especificado por el parmetro NEXT.
Asumiendo que en este ejemplo, el tamao de bloque de una base de datos es de 4KB, y el tablespace es
creado gestionado localmente con un tamao uniforme de 256KB, cada bit en el mapa de bits describe 64
bloques (256/4). Si la clusula UNIFORM SIZE se omite, el valor por defecto es AUTOALLOCATE. El SIZE por
defecto para UNIFORM es 1MB.
Nota. Si especificamos LOCAL en un comando CREATE TABLESPACE, no podemos especificar la
clusula DEFAULT STORAGE, MINEXTENTS, o TEMPORARY.
Oracle /328
Los tablespaces gestionados localmente puede asumir algunas de las tareas de gestin de espacio realizadas
por los DBA's en tablespaces gestionados por diccionario. A causa de su arquitectura, tiene menos
probabilidades de fragmentarse, y sus objetos tienen menos probabilidades de tener problemas de espacio.
Podemos crear un conjunto de tablespaces gestionados localmente con un pequeo nmero de parmetros de
almacenamiento y resolver la mayora de solicitudes de espacio en nuestra base de datos. Por ejemplo,
podemos crear tres tablespaces DATA como sigue:
CREATE TABLESPACE DATA_SMALL
DATAFILE '/u01/oracle/VLDB/data_small.dbf' SIZE 10M
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;
CREATE TABLESPACE DATA_MEDIUM
DATAFILE '/u01/oracle/VLDB/data_medium.dbf' SIZE 100M
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 4M;
CREATE TABLESPACE DATA_LARGE
DATAFILE'/u01/oracle/VLDB/data_large.dbf' SIZE 1000M
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 16M;
Si tenemos una tabla pequea podemos ubicarla en el tablespace DATA_SMALL. Si aumenta significativamente
en tamao podemos moverla al tablespace DATA_MEDIUM o DATA_LARGE.
2.4.2. Segmentos de tabla.
Los segmentos de tabla, tambin llamadas segmentos de datos, almacenan las filas de datos asociados con las
tablas o clsteres. Cada segmento de datos contiene un bloque de cabecera que sirve como un espacio de
directorio para el segmento.
Una vez que un segmento de datos adquiere una extensin, mantiene esta extensin hasta que el segmento es
borrado, trucando o comprimido mediante las opciones de Oracle Database 11g. Borrar filas de una tabla
mediante el comando DELETE no afecta a la cantidad de espacio asignado a la tabla. El nmero de extensiones
se incrementar hasta que (1) el valor de MAXEXTENTS se sobrepase (si est asignado), (2) la cuota de usuario
en el tablespace se sobrepasa, o (3) el tablespace se ejecuta fuera del espacio (si los ficheros de datos no puede
auto-extenderse).
Para minimizar la cantidad de espacio gastado en un bloque de datos se puede afinar el parmetro PCTFREE.
El parmetro PCTFREE especifica la cantidad de espacio que quedar libre dentro de cada bloque de datos. El
espacio libre puede ser entonces usado cuando columnas con valores NULL sean actualizadas para tener
valores, o cuando actualizaciones de otros valores en la fila fuercen que la longitud total de la fila se
incremente.
Podemos usar el comando ALTER TABLE para modificar la mayora de parmetros de almacenamiento de una
tabla existente. Podemos usar la opcin MOVE del comando ALTER TABLE para cambiar la asignacin del
tablespace de una tabla.
3. Auditora de Seguridad
Oracle tienen la capacidad de auditar todas las acciones que tienen lugar en la base de datos. Se pueden
auditar tres tipos de acciones:
Intentos de entrada en cuentas de la base de datos.
Accesos a los objetos de la base de datos.
Acciones sobre la base de datos.
La base de datos registra todos los intentos de accin, tanto los exitosos como los infructuosos, aunque es un
parmetro configurable.
Para habilitar la capacidad de auditora se debe fijar el parmetro AUDIT_TRAIL en el fichero init.ora. Los
registros de auditora se almacenan en la tabla SYS.AUD$ o bien su gestin se deja al sistema operativo.
Cuando se decide utilizar la tabla SYS.AUD$ sta debe revisarse peridicamente, por si hiciera falta truncarla
debido a que su aumento de tamao puede causar problemas de espacio en el tablespace SYSTEM. Los valores
del parmetro AUDIT_TRAIL son los que se exponen en la siguiente tabla:
Valor Descripcin
NONE Deshabilita la auditora.
BD Habilita la auditora, escribiendo en la tabla SYS.AUD$.
OS Habilita la auditora, dejando al sistema operativo su gestin.

Oracle /329
3.1. Auditando conexiones.
Todo intento de conexin con la base de datos ser registrado. El comando para iniciar la auditora es:
AUDIT SESSION;
Para determinar si se deben registrar slo los xitos, o slo los fracasos, se pueden utilizar los siguientes
comandos:
AUDIT SESSION WHENEVER SUCCESSFUL;
AUDIT SESSION WHENEVER NOT SUCCESSFUL;
Si los registros de auditora se almacenan en la tabla SYS.AUD$, entonces pueden verse a travs de la vista
DBA_AUDIT_SESSION.
SELECT
OS_USERNAME, /* nombre de usuario SO */
USERNAME, /* nombre de usuario BD */
TERMINAL,
DECODE(RETURNCODE,'0','Conectado',
'1005', 'Solo username, sin password',
'1017','Password incorrecto', returncode), /* comprobacion de error */
TO_CHAR(TIMESTAMP,'DD-MON-YY HH24:MI:SS'), /* hora de entrada */
TO_CHAR(LOGOFF_TIME,'DD-MON-YY HH24:MI:SS') /* hora de salida */
FROM DBA_AUDIT_SESSION;
Para deshabilitar la auditoria de las conexiones basta con ejecutar la siguiente sentencia:
NOAUDIT SESSION;
3.2. Auditando Acciones
Se puede auditar cualquier accin que afecte a cualquier objeto de la base de datos. Para facilitar la gestin, las
acciones a auditar se encuentran agrupadas segn los grupos que se muestran en la siguiente tabla:
Grupo Comandos auditados
CLUSTER Todas las sentencias que afecten a clusters.
DATABASE LINK Todas las sentencias que afecten a enlaces de base de datos.
EXISTS Todas las sentencias que fallen porque ya existe un objeto en la base de datos.
INDEX Todas las sentencias que afecten a ndices.
NOT EXISTS Todas las sentencias que fallen porque un determinado objeto no existe.
PROCEDURE Todas las sentencias que afecten a procedimientos.
PROFILE Todas las sentencias que afecten a perfiles.
PUBLIC DATABASE LINK Todas las sentencias que afecten a enlaces pblicos de base de datos.
PUBLIC SINONYM Todas las sentencias que afecten a sinnimos pblicos.
ROLE Todas las sentencias que afecten a roles.
ROLLBACK SEGMENT Todas las sentencias que afecten a segmentos de rollback.
SEQUENCE Todas las sentencias que afecten a secuencias.
SESSION Todas las sentencias de acceso a la base de datos.
SYNONYM Todas las sentencias que afecten a sinnimos.
SYSTEM AUDIT Todas las sentencias AUDIT y NOAUDIT.
SYSTEM GRANT Todas las sentencias afecten a privilegios.
TABLE Todas las sentencias que afecten a tablas.
TABLESPACE Todas las sentencias que afecten a espacios de tablas.
TRIGGER Todas las sentencias que afecten a disparadores.
USER Todas las sentencias que afecten a las cuentas de usuarios.
VIEW Todas las sentencias que afecten a vistas.
Por ejemplo, para auditar todas acciones que tienen que ver con las tablas se usa el siguiente comando:
AUDIT TABLE;
Y para deshabilitar la auditora se utilizar el siguiente comando:
NOAUDIT TABLE;
Tambin se puede afinar un poco ms en la auditora fijando un usuario concreto al que seguir la pista:
AUDIT TABLE BY Usuario1;
Cada accin auditada recibe un cdigo numrico al que se puede acceder a travs de la vista AUDIT_ACTIONS.
Una vez que conocemos el cdigo de la accin, podemos utilizarlo para determinar cmo dicha accin ha
afectado a un objeto, consultado la vista DBA_AUDIT_OBJECT.

Oracle /330
3.3. Auditando objetos.
Adems de la auditora de acciones sobre los objetos, se puede seguir el rastro a las operaciones de
manipulacin de tablas: SELECT, INSERT, UPDATE y DELETE. Estas auditoras se pueden hacer por sesin o por
acceso.
Un ejemplo de sentencias de auditoras sobre objetos se puede ver en el siguiente grupo de sentencias:
AUDIT INSERT ON Usuario1.EMP;
AUDIT ALL ON Usuario1.EMP BY SESSION;
AUDIT DELETE ON Usuario1.EMP BY ACCESS;
Los registros de auditora se pueden ver en la misma vista DBA_AUDIT_OBJECT anteriormente mencionada.
3.4. Protegiendo los registros de auditora.
Los registros de la tabla SYS.AUD$ pueden ser objeto de intentos de acceso para ser eliminados, ya que
pueden reflejar acciones no autorizadas en la base de datos. As, resulta interesante reflejar ese tipo de
acciones. Esto se consigue con el siguiente comando:
AUDIT ALL ON SYS.AUD$ BY ACCESS;
De este modo, cualquier accin contra la tabla SYS.AUD$ quedar registrada. Adems, las acciones contra la
tabla SYS.AUD$ slo pueden ser borradas por los usuarios que puedan conectarse como INTERNAL.

Oracle /331

También podría gustarte