You are on page 1of 331

PEDRO SALGUEIRO GMEZ 2011

Tabla de contenidos
I. NOCIONES SOBRE BASES DE DATOS Y ORACLE 6
1. Arquitectura de Oracle Database 11g....................................... 6 1.1. Fundamentos de bases de datos. ........................................ 6 1.2. Fundamentos de bases de datos relacionales....................... 8 1.3. Bases de datos e instancias en Oracle. .............................. 11 1.4. Organizacin de las bases de datos en Oracle. .................. 11 1.5. Seleccin de arquitecturas y opciones. ............................. 14 2. Instalar Oracle Database 11g y crear una base de datos .......... 15 2.1. Descripcin de la licencia y opciones de instalacin. ........ 15 3. Servidor de Oracle ................................................................ 24 3.1. Elementos del servidor Oracle ......................................... 24 3.2. Conexiones. .................................................................... 24 3.3. Estructura de las bases de datos Oracle. ........................... 25 3.4. Instancia de la base de datos. ........................................... 25 3.5. Procesamiento de instrucciones SQL. .............................. 26 3.6. Archivos de inicializacin ............................................... 27 3.7. Arranque y parada de la base de datos.............................. 28 4. Introduccin a los conceptos del sistema Oracle .................... 29 4.1. Almacenamiento. ............................................................ 29 4.2. Transacciones. ................................................................ 29 4.3. Usuarios. ........................................................................ 29 4.4. Prdidas de informacin. ................................................. 30 4.5. Copias de seguridad. ....................................................... 30 4.6. Bases de datos distribuidas. ............................................. 30 4.7. Herramientas de Oracle. .................................................. 30 6.1. Reunin de una tabla consigo misma. .............................. 78 6.2. Consultas de unin internas. ............................................ 78 6.3. Consultas con operaciones de conjuntos........................... 80 7. Agrupaciones ....................................................................... 80 7.1. Funciones de agregado. ................................................... 80 7.2. La clusula Group by. ................................................. 83 8. Subconsultas ........................................................................ 84 8.1. Introduccin. .................................................................. 84 8.2. Recuperacin de datos con subconsulta............................ 84 8.3. Subconsultas correlacionadas. ......................................... 85 8.4. Subconsultas con operador de comparacin distinto de IN. .................................................................................... 85 8.5. Funciones de agregado en subconsultas. .......................... 86 8.6. Subconsultas con EXISTS. .......................................... 86 8.7. Expresiones de columna con subconsultas ....................... 86 8.8. Subconsultas como origen de registros para FROM. ..... 87 9. Vistas ................................................................................... 87 9.1. Introduccin. .................................................................. 87 9.2. Crear y consultar vistas. .................................................. 88 9.3. Ejecucin de comandos DML sobre vistas. ...................... 88 9.4. Estabilidad de una vista. .................................................. 88 9.5. Mostrar la lista de vistas. ................................................. 89 9.6. Borrar vistas. .................................................................. 89 10. Comandos internos en SQL*PLUS e iSQL*Plus .................. 89 10.1. Variables de sustitucin................................................. 89 10.2. Comando SET. .......................................................... 90 10.3. Encabezado y pie de informe. ........................................ 90 10.4. Comando COLUMN. ................................................ 91 10.5. Comando BREAK. .................................................... 91 10.6. Comando COMPUTE. .............................................. 92 10.7. Guardar consultas en ficheros. ....................................... 93 10.8. Redirigir la salida de SQL*Plus con SPOOL. ............. 93 11. Consultas avanzadas ........................................................... 94 11.1. Consultas con ROWNUM. ........................................ 94 11.2. Consultas con ROWID. ............................................. 94 11.3. Consultas con RANK. ............................................... 95 11.4. Consultas sobre estructuras jerrquicas. ......................... 96 11.5. Consultas de agrupacin avanzada. ................................ 98

II. LENGUAJE DE CONSULTAS.................................. 32


1. SQL para Oracle ................................................................... 32 1.1. Introduccin. .................................................................. 32 1.2. Cdigo SQL y normas de escritura. ................................. 32 1.3. SQL*Plus. ...................................................................... 32 1.4. Versin grfica de SQL*Plus. ......................................... 33 1.5. iSQL*Plus. ..................................................................... 33 2. Estructura del lenguaje SQL.................................................. 34 2.1. Tipos de datos................................................................. 34 2.2. Operadores ..................................................................... 35 2.3. Funciones predefinidas.................................................... 36 3. Trabajando con objetos ......................................................... 52 3.1. Introduccin. .................................................................. 52 3.2. Diccionario de datos de Oracle. ....................................... 52 3.3. Crear y usar bases de datos. ............................................. 53 3.4. Crear y usar tablespaces. ................................................. 53 3.5. Crear esquemas............................................................... 55 3.6. Crear y usar tablas. ......................................................... 56 3.7. Restricciones. ................................................................. 59 3.8. Crear y eliminar ndices. ................................................. 61 3.9. Uso de tablas particionadas. ............................................ 64 3.10. Clsteres (o cubos)........................................................ 67 3.11. Secuencias. ................................................................... 68 3.12. Sinnimos..................................................................... 69 3.13. Insercin de registros. ................................................... 69 3.14. Actualizacin de registros. ............................................ 72 3.15. Eliminacin de registros. ............................................... 72 3.16. Combinar registros con MERGE. .................................. 73 4. Consultas de seleccin .......................................................... 73 4.1. Consultas bsicas. ........................................................... 74 4.2. Alias............................................................................... 74 4.3. Ordenar los registros. ...................................................... 74 4.4. Consultas con predicado.................................................. 75 4.5. Recuperacin de valores calculados. ................................ 75 4.6. La clusula WHERE. .................................................. 76 4.7. Consultas que incluyen nulos .......................................... 76 5. Criterios de seleccin............................................................ 76 5.1. Operadores lgicos. ........................................................ 76 5.2. Intervalos de valores. ...................................................... 77 5.3. El operador Like. ........................................................ 77 5.4. El operador In. ............................................................ 77 6. Consultas sobre ms de una tabla .......................................... 78

III. PL/SQL.................................................................... 101


1. Estructura del lenguaje PL/SQL .......................................... 101 1.1. Fundamentos de PL/SQL. ............................................. 101 1.2. Estructuras de control en PL/SQL. ................................. 102 2. Bloques PL/SQL................................................................. 103 2.1. Introduccin. ................................................................ 103 2.2. Estructura de un Bloque. ............................................... 103 2.3. Seccin de declaracin de variables. .............................. 104 2.4. El paquete DBMS_OUTPUT. .................................... 105 2.5. Asignacin de variables................................................. 106 3. Excepciones en PL/SQL. .................................................... 107 3.1. Manejo de excepciones. ................................................ 107 3.2. Excepciones predefinidas. ............................................. 107 3.3. Excepciones definidas por el usuario. ............................ 108 3.4. Uso de SQLCODE y SQLERRM. .......................... 109 3.5. Excepciones personalizadas en PL/SQL. ........................ 109 3.6. Propagacin de excepciones en PL/SQL. ....................... 109 4. Cursores ............................................................................. 109 4.1. Cursores implcitos. ...................................................... 110 4.2. Cursores explcitos. ....................................................... 110 4.3. Cursores con parmetros. .............................................. 111 4.4. Cursores de actualizacin. ............................................. 111 5. Subprogramas en PL/SQL................................................... 112 5.1. Permisos requeridos. ..................................................... 112 5.2. Procedimientos, funciones y paquetes. ........................... 113 5.3. Procedimientos almacenados. ........................................ 113 5.4. Funciones en PL/SQL. .................................................. 114 5.5. Subprogramas en bloques procedimentales. ................... 115 5.6. Depurando procedimientos. ........................................... 115

5.7. Paquetes en PL/SQL. .................................................... 115 5.8. Viendo el cdigo fuente de objetos procedimentales....... 118 5.9. Compilando procedimientos, funciones y paquetes......... 118 6. Transacciones..................................................................... 119 6.1. Estado de los datos durante la transaccin. ..................... 119 6.2. Control de transacciones en PL/SQL. ............................ 119 6.3. Puntos de ruptura. ......................................................... 120 6.4. Transacciones autnomas .............................................. 120 7. Triggers ............................................................................. 121 7.1. Permisos requeridos. ..................................................... 121 7.2. Tipos de triggers. .......................................................... 121 7.3. Triggers asociados a tablas. ........................................... 122 7.4. Triggers para eventos DDL. .......................................... 125 7.5. Triggers para eventos del sistema. ................................. 128 7.6. Triggers de sustitucin. ................................................. 129 7.7. Activar y desactivar triggers. ......................................... 130 8. Tipos de datos complejos y operaciones masivas. ................ 131 8.1. Registros (RECORD).................................................... 131 8.2. Arrays asociativos (TABLE). ........................................ 132 8.3. Arrays variables (VARRAY)......................................... 133 8.4. Acceso masivo a los datos (BULK COLLECT). ............ 135 8.5. Funciones en lnea. ....................................................... 136 8.6. Instruccin FORALL. ............................................... 137 8.7. Objetos grandes (LOB). ................................................ 138 9. SQL Dinmico ................................................................... 142 9.1. Sentencias DML con SQL dinmico. ............................. 143 9.2. Cursores con SQL dinmico. ......................................... 143 9.3. Un ejemplo de cmo usar y cmo no usar SQL dinmico.146 10. PL/SQL y Java ................................................................. 146 10.1. Creacin de Objetos Java en la base de datos ORACLE.146 10.2. Ejecucin de programas Java con PL/SQL ................... 147 10.3. Correspondencia de tipos entre Java y Oracle. .............. 148 10.4. Paso de cursores Oracle a mtodos de Java. ................. 148 10.5. Paso de objetos Oracle a mtodos de Java. ................... 149 10.6. Paso de arrays desde un programa Java a un procedimiento almacenado de Oracle. .................................. 150 10.7. Cmo pasar y retornar un array de objetos a travs de un procedimiento almacenado................................................... 151 10.8. Paquete DBMS_JAVA. ........................................... 152

IV. CARACTERSTICAS DE ORACLE GRID........... 155

1. Arquitectura de Rejilla ........................................................ 155 1.1. Hardware y elementos de configuracin del sistema operativo. ............................................................................ 155 1.2. Aadiendo servidores a la rejilla. ................................... 157 1.3. Compartir datos entre la rejilla. ..................................... 157 1.4. Administracin de la rejilla. .......................................... 158 1.5. Lanzar OEM. ................................................................ 159 2. Oracle Real Application Clusters ........................................ 160 2.1. Pasos de preinstalacin. ................................................ 160 2.2. Instalacin de RAC. ...................................................... 161 2.3. Inicia y parar instancias RAC. ....................................... 163 2.4. Transparencia de sobrefallos de aplicacin..................... 164 2.5. Aadir nodos e instancias a un clster. ........................... 165 2.6. Administracin de registro y servicios del clster. .......... 165 3. Seguridad en Oracle ........................................................... 166 3.1. Creacin de usuarios. .................................................... 166 3.2. Eliminacin de usuarios. ............................................... 167 V. SOPORTE DE OBJETOS Y XML ........................... 263 3.3. Gestin de contraseas. ................................................. 167 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

4.5. Cmo usar grupos de polticas. ...................................... 187 5. Trabajando con espacios de tabla......................................... 187 5.1. Tablespaces y la estructura de las bases de datos. ........... 188 5.2. Planificando el uso de nuestro tablespace. ...................... 196 6. Usar SQL*Loader para cargar datos .................................... 197 6.1. El fichero de control...................................................... 197 6.2. Comienzo de la carga. ................................................... 199 6.3. Sobre la sintaxis del fichero de control. .......................... 201 6.4. Administracin de la carga de datos. .............................. 202 6.5. Ajustar la carga de datos. .............................................. 203 6.6. Funcionalidades adicionales. ......................................... 205 7. Importar y exportar con Data Pump ................................. 205 7.1. Creando un directorio.................................................... 205 7.2. Opciones de Data Pump Export. ................................ 206 7.3. Iniciando una tarea de Data Pump Export. .................. 207 7.4. Opciones para Data Pump Import. ............................. 210 7.5. Iniciando una tarea de Data Pump Import. .................. 211 8. Acceso a datos remotos ....................................................... 214 8.1. Enlaces de base de datos. .............................................. 214 8.2. Usando sinnimos para transparencia de localizacin. .... 218 8.3. Usando la pseudo-columna USER en vistas................ 219 8.4. Enlaces dinmicos: usando el comando de copia de SQL*Plus............................................................................ 220 8.5. Conectndose a una base de datos remota. ..................... 221 9. Vistas materializadas. ......................................................... 222 9.1. Funcionalidad. .............................................................. 222 9.2. Permisos requeridos. ..................................................... 222 9.3. Solo-lectura contra actualizable. .................................... 223 9.4. Sintaxis de creacin de vistas materializadas. ................. 223 9.5. Usando vistas materializadas para modificar rutas de ejecucin de consultas. ........................................................ 227 9.6. Usando DBMS_ADVISOR. ...................................... 228 9.7. Refrescando vista materializadas. .................................. 229 9.8. Sintaxis para crear registros de vista materializada. ........ 233 9.9. Modificando vistas materializadas y registros. ............... 234 9.10. Eliminando vistas materializadas y registros. ............... 234 10. Oracle Text....................................................................... 235 10.1. Aadiendo texto a la base de datos. .............................. 235 10.2. Consultas de texto e ndices de texto. ........................... 235 10.3. Conjuntos de ndices. .................................................. 243 11. Uso de tablas externas....................................................... 244 11.1. Accediendo a datos externos. ....................................... 244 11.2. Creando una tabla externa. .......................................... 245 11.3. Modificacin de tablas externas. .................................. 250 11.4. Limitaciones, beneficios y usos potenciales de las tablas externas............................................................................... 251 12. Consultas flashback .......................................................... 252 12.1. Ejemplo de consulta flashback basada en el tiempo. ..... 253 12.2. Guardando los datos. ................................................... 254 12.3. Ejemplo de consulta flashback basada en SCN. ............ 254 12.4. Qu ocurre si falla una consulta flashback? ................ 255 12.5. Qu SCN est asociado con cada registro? ................. 255 12.6. Consultas de versin flashback. ................................... 256 12.7. Planificacin de las consultas flashback. ...................... 257 13. Tablas y bases de datos flashback ...................................... 258 13.1. El comando FLASHBACK TABLE. ........................ 258 13.2. El comando FLASHBACK DATABASE. ................ 260

2.1. XMLType. ................................................................ 281 2.2. Mapeado de XMLType dado un esquema XML. ........ 281 2.3. Crear tablas/columnas XMLType. ............................. 282 2.4. Operaciones con columnas XMLType. .......................... 283 2.5. Validar los documentos XML sobre un esquema. ........... 286 2.6. Indexar elementos XMLType. ................................... 287 2.7. SQLX, generar XML de los datos relacionales. .............. 287 2.8. Vistas XMLType. ..................................................... 291

VI. PROCEDIMIENTOS DE GESTIN DE LA BASE DE DATOS. ................................................................... 294


1. Diccionario de datos de Oracle............................................ 294 1.1. Las vistas DICTIONARY (DICT) y DICT_COLUMNS. ......................................................... 294 1.2. Cosas que podemos seleccionar de: tablas (y columnas), vistas, sinnimos y secuencias. ............................................ 295 1.3. Papelera: USER_RECYCLEBIN y DBA_RECYCLEBIN300 1.4. Restricciones y comentarios. ......................................... 300 1.5. ndices y clsteres. ........................................................ 303 1.6. Tipos de datos abstractos, estructuras ORDBMS y LOB's.306

1.7. Enlaces de base de datos y vistas materializadas. ............ 308 1.8. Triggers, procedimientos, funciones y paquetes.............. 310 1.9. Dimensiones. ................................................................ 311 1.10. Asignacin y uso de espacio, incluyendo particiones y subparticiones. .................................................................... 312 1.11. Usuarios y permisos. ................................................... 316 1.12. Roles. ......................................................................... 318 1.13. Auditora. ................................................................... 318 1.14. Supervisin: las tablas de rendimiento dinmico V$. .... 320 2. Administracin de la base de datos. ..................................... 325 2.1. Creacin de una base de datos. ...................................... 325 2.2. Iniciacin y parado de la base de datos........................... 326 2.3. Tamao y gestin de las reas de memoria. .................... 326 2.4. Asignar y gestionar espacio para objetos. ....................... 327 3. Auditora de Seguridad ....................................................... 329 3.1. Auditando conexiones. .................................................. 330 3.2. Auditando Acciones ...................................................... 330 3.3. Auditando objetos. ........................................................ 331 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 23444325 65335544 11143442 66442444 Nombre Pedro Salgueiro Jos Martnez Esther Lpez Jos Martnez Fecha 20/12/64 14/07/72 03/07/72 12/10/65 Ocupacin Profesor Carpintero Carpintero 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 reg istros 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 DNI Nombre Apellidos 11252111 PEDRO PREZ 12323253 JUAN GARCA 56344323 LUSA GMEZ

TipoPago CONTADO PLAZOS PLAZOS

TABLA DE COCHES Matrcula Marca M-2345-AF OPEL M-3443-HW CITROEN M-1278-HZ CITROEN

Precio 1200000 2100000 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 1 DNI Nombre Apellidos TipoPago Matrcula Matrcula Marca Precio 1 DNI Nombre Apellidos TipoPago COCHES CLIENTES 1 Matrcula Marca Precio DNI COCHES

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 1 DNI Nombre Apellidos TipoPago COCHES Matrcula Marca Precio 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 1 DNI Nombre Apellidos TipoPago Matrcula Matrcula Marca Precio COCHES

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 DNI Nombre Apellidos TipoPago Matrcula


1

COMPRA DNI Matrcula


1

COCHES Matrcula Marca Precio

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 y habilitar xhost previamente para empezar el OUI a travs del script runInstaller.
DISPLAY

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: Bajo UNIX, debemos usar: o bien:
SET ORACLE_SID=rjbdb EXPORT ORACLE_SID=rjbdb 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:

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: 7) Empezar la instancia usando el siguiente comando: 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 STARTUP NOMOUNT CREATE spfile FROM pfile;

SQLPLUS /NOLOG CONNECT SYS/contrasea AS SYSDBA

Oracle /23

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.

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;

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 h acer 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: En este caso hemos cambiado el parmetro y estos cambios se han recogido en el archivo permanecer cuando sea reiniciada la base de datos.
ALTER SYSTEM SET shared_pool_size= 150 SCOPE=memory ALTER SYSTEM SET shared_pool_size= 150 SCOPE=spfile spfile,

por lo tanto

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 Fixed Size Variable Size Database Buffers Redo Bufers Database mounted. Database opened. 4512688 bytes. 39732 bytes. 4055164 bytes. 409600 bytes. 8192 bytes.

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: 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; STARTUP OPEN Test

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: 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: Ejemplo:
slplus usuario/contrasea@nombreServicioBaseDeDatos slplus usr1/miContra@inicial.forempa.net SQL>

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: 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
slplusw usuario/contrasea@nombreServicioBaseDeDatos

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) Number Number(m,d) ROWID

Equivale al tipo Integer, Int o SamllInt Equivale al tipo Float, Double o Real Nmeros decimales de coma fija, con m cifras en total y d decimales Valor hexadecimal que representa la direccin nica de una fila en su tabla. 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. Almacena n caracteres en formato ASCII (como mximo 4000). Al recuperar los datos, slo se recupera el texto asignado con su longitud original. Almacena n caracteres en formato UNICODE. Siempre se utilizan los n caracteres indicados, incluso si la entrada de datos es inferior. Almacena n caracteres en formato UNICODE. Almacena fechas en formato da, mes, ao, hasta el nivel de segundos. Almacena fechas hasta el nivel de fracciones de segundo. 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');

Datos de carcter:
Char(n)

Varchar2(n) Nchar(n) Nvarchar2(n)

Datos de fecha:
Date TimeStamp Interval

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

da respectivamente.

del ao y del

Datos binarios grandes:


Raw Long Raw Blob, Clob, Nclob y Bfile

Sirve para almacenar valores binarios de hasta 2000 bytes (se puede especificar el tamao mximo entre parntesis). Almacena hasta 2GB. Almacenan datos binarios de varios gigas (imgenes, vdeos, etc.).

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 Significado Y lgico O lgico Complementario Significado Indica si una expresin es nula
Oracle /35

Operadores lgicos
AND OR NOT

Operadores para nulos


IS NULL

IS NOT NULL

Indica si una expresin no es nula Significado Concatenador de texto Evala un texto contra una expresin regular

Operadores para texto


|| LIKE

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: Muestra una tabla con el contenido del clculo SQRT(5) (la raz cuadrada de 5). 2.3.1. Funciones de cadena.
ASCII(texto) SELECT SQRT(5) FROM DUAL;

Retorna la representacin decimal (en el juego de caracteres de la base de datos) del primer caracter del texto. Retorna el caracter que se corresponde con el cdigo dado en el juego de CHR(cdigo) caracteres de la base de datos. CONCAT(texto1, texto2) Concatena dos textos (igual que el operador ||). Coloca la primera letra de cada palabra en maysculas. INITCAP(texto) Obtiene la posicin en la que se encuentra el texto buscado en el texto inicial. Se INSTR(texto, textoBuscado puede empezar a buscar a partir de una posicin inicial concreta e incluso indicar [,posInicial [, nAparicin]]) 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. Obtiene el tamao del texto. LENGTH(texto) Convierte el texto a minsculas. LOWER(texto) Alarga por la izquierda. Crea un nuevo texto a partir del dato con la longitud LPAD(texto,longitud,pad) especificada aadiendo por la izquierda el caracter pad especificado o espacios en blanco si no se especifica. Elimina los espacios a la izquierda que posea el texto. LTRIM(texto) REPLACE(texto, textoABuscar, Buscar el texto a buscar en un determinado texto y lo cambia por el indicado como texto de reemplazo. textoReemplazo) Alarga por la derecha. Crea un nuevo texto a partir del dato con la longitud RPAD(texto,longitud,pad) especificada aadiendo por la derecha el caracter pad especificado o espacios en blanco si no se especifica. Elimina los espacios a la derecha del texto. RTRIM(texto) Retorna la representacin fontica de un texto. SOUNDEX(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. Elimina los espacios en blanco a la izquierda y la derecha del texto y los espacios TRIM(texto) dobles del interior. Convierte el texto a maysculas. UPPER(texto) 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 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
LTRIM( RTRIM('000012345......','.'), '0')

evala a verdadero. 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.
ver t')=SOUNDEX('abierto') SOUNDEX 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); dos registros de VENTA aparecen los nombres 'Jos Prez' y 'Jose Perez' obtendremos

Si en 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 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)) REGEXP_SUBSTR('123-ABC-456', '-[^-]+-')

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 ^ Indica una A opcional. El ? es vlido para hacer opcional cualquier expresin A?
Oracle /38

A{3} A{3,} A{3,8} [aBcD] [C-G] [^aBcD] [.ch.] \t \r \n \a \e \f \v \x00A2 \d \w \s \D \W \S \A \Z \b \B

Tres A'es seguidas. Las llaves indican repeticin exacta de expresiones Al menos tres A'es seguidas Al menos tres A'es y menos de ocho A'es Alguno de los caracteres a, B, c o D Un caracter en el rango entre C y G inclusive Cualquier carcter distinto de a, B, c o D Especifica el caracter ch espaol El caracter tabulador El caracter retorno de carro El caracter de nueva lnea El caracter beep El caracter de escape El caracter salto de pgina El caracter tabulador vertical El caracter de cdigo ASCII 0042 Un dgito del 0 al 9 Cualquier carcter alfanumrico Un espacio en blanco Cualquier caracter que no sea un dgito Cualquier caracter no alfanumrico Cualquier carcter que no sea un espacio en blanco Representa el inicio de la cadena. No un caracter sino una posicin Representa el final de la cadena. No un carcter sino una posicin Marca el inicio y el final de una palabra 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
[:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:]

Descripcin Todos los caracteres alfanumricos Todos los caracteres alfabticos Todos los caracteres de espacio en blanco Todos los caracteres de control (no imprimibles) Todos los dgitos numricos Todos los caracteres[:punct:], [:upper:], [:lower:], y [:digit:] Todos los caracteres alfabticos en minsculas Todos los caracteres imprimibles Todos los caracteres de puntuacin Todos los caracteres de espacio (no imprimibles) Todos los caracteres alfabticos en maysculas 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 c n

Se usa para indicar bsquedas no sensibles a maysculas y minsculas. Se usa para indicar bsquedas sensibles a maysculas y minsculas. Permite que el caracter punto (.) tambin case con el salto de lnea.

Oracle /39

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: 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, 'i')

Trata la cadena de origen como una cadena de varias lneas. Oracle tratar ^ y $ como el inicio y final, respectivamente, de cada lnea.

El Por defecto, las bsquedas son sensibles a maysculas y minsculas. En el siguiente ejemplo, se busca el segundo dgito: 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: 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: 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:]]') REGEXP_INSTR (source_string, pattern[, position [, ocurrence[, return_option[, match_parameter ]]]]) REGEXP_SUBSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940', '[[:digit:]]', 1, 2)

REGEXP_SUBSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940', 'mi', 1, 1, 'c') resultado ser el valor NULL.

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': En este caso la funcin se evala a verdadero. El formato de esta funcin es:
REGEXP_LIKE('111-222-333', '111+')

REGEXP_INSTR('MI LIBRO DE CONTABILIDAD: Dbitos, Crditos y Facturas 1940', '[[:digit:]]', 1, 1, 1)

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: 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: Produce el resultado 'EGOREG', y:
REPLACE('GEORGE', 'GE', 'EG') REPLACE('GEORGE', 'GE', NULL) Produce el resultado 'OR'. La funcin REGEXP_REPLACE extiende REPLACE (source_string, search_string [, replace_string])

REGEXP_LIKE(source_string, pattern, [match_parameter ])

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 ]]]]) REGEXP_REPLACE ('111222333', '([[:digit:]]{3})([[:digit:]]{3})([[:digit:]]{3})', '(\1) (\2) (\3)')

En el siguiente ejemplo se pone entre parntesis cada terna de un nmero telefnico:


Oracle /40

El resultado de este ejemplo es '(111) (222) (333)'. 2.3.3. Funciones numricas.


ABS(n) ACOS(n) ASIN(n) ATAN(n) ATAN2(n, m) BITAND (n, m) CEIL(n) COALESCE(n, m, ) COS(n) COSH(n) EXP(n) FLOOR(n) GREATEST(n, m, ) LEAST(n, m, ) LN(n) LOG(n) MOD(n1,n2) NANVL(n,m)

NVL(n, m) NVL2(n,m,p) POWER(valor, exponente) REMAINDER(n, m) ROUND(n, decimales) SIGN(n) SIN(n) SINH(n) SQRT(n) TAN(n) TANH(n) TRUNC(n, decimales) VSIZE(n)

Devuelve el valor absoluto del argumento. Devuelve, en radianes, el arcocoseno del argumento. Devuelve, en radianes, el arcoseno del argumento Devuelve, en radianes, el arcotangente del argumento Devuelve, en radianes, la arcotangente de dos argumentos. Realiza una operacin AND a nivel de bits entre los argumentos y devuelve un entero con el resultado. Devuelve el valor entero ms pequeo mayor o igual que el argumento. Retorna el primer valor no NULL de la lista de argumentos. Devuelve el coseno del argumento (el cual tiene que estar en radianes). Devuelve el coseno hiperblico del argumento. Devuelve el valor de e elevado al argumento n. Devuelve el valor entero ms grande menor o igual que el argumento Retorna el valor ms grande de la lista de argumentos, o NULL si uno de ellos es nulo. Retorna el valor ms pequeo de la lista de argumentos, o NULL si uno de ellos es nulo. Devuelve el logaritmo neperiano del argumento. Devuelve el logaritmo en base 10 del argumento n. Devuelve el resto de la divisin entera de los argumentos. 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 Retorna el segundo argumento si el primero es NULL, sino retorna el primer argumento. Retorna el tercer argumento si el primero es NULL, sino retorna el segundo argumento. Retorna el resultado de elevar un valor al exponente indicado. Retorna el resto de dividir dos nmeros. Redondea el nmero al siguiente nmero con el nmero de decimales indicado ms cercano. Devuelve 1 si el argumento es positivo, cero si vale cero y -1 si es negativo Devuelve el seno del argumento (el cual tiene que estar en radianes). Devuelve el seno hiperblico del argumento. Devuelve la raz cuadrada del argumento. Devuelve la tangente del argumento (el cual tiene que estar en radianes). Devuelve la tangente hiperblica del argumento. Los decimales del nmero se cortan para devolver slo el nmero de decimales indicado. 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) CEIL(1.3) CEIL(-2) CEIL(-2.3) = = = = 2 2 -2 -2

La funcin FLOOR es la opuesta a CEIL. La siguiente tabla muestra algunos ejemplos:


FLOOR(2) FLOOR(1.3) FLOOR(-2) FLOOR(-2.3) = = = = 2 1 -2 -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) MOD(22,23) MOD(10,3) MOD(-30.23,7) MOD(4.1,.3) MOD(44, 1) = = = = = = 0 22 1 -2.23 .2 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: Si no se especifica la precisin se toma por defecto precisin cero. La siguiente tabla muestra ejemplos de ambas funciones:
ROUND(11, 2) ROUND(-22, 2) ROUND(33.33, 2) ROUND(55.5, 2) ROUND(66.666, 2) = = = = = 11 -22 33.33 55.5 66.67 TRUNC(11, 2) TRUNC(-22, 2) TRUNC(33.33, 2) TRUNC(55.5, 2) TRUNC(66.666, 2) = = = = = 11 -22 33.33 55.5 66.66 ROUND(valor, precisin) TRUNC(valor, precisin)

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 ROUND(-22, -1) = -20 ROUND(33.33, -1) = 30 ROUND(55.5, -1) = 60 ROUND(66.666, -1) = 70 usar precisin -1 se redondea al TRUNC(11, -1) TRUNC(-22, -1) TRUNC(33.33, -1) TRUNC(55.5, -1) TRUNC(66.666, -1) = = = = = 10 -20 30 50 60

En estos ejemplos al nivel 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: 2.3.4. Funciones que trabajan con nulos.
NVL(valor, sustituto) NVL2(valor,sustituto1,sustituto2) NANVL(valor, sustituto) COALESCE( NULL, 4, NULL, 7) = 4

Si el valor es NULL, devuelve el valor sustituto; de otro modo, devuelve valor. Variante de la anterior, devuelve el valor sustituto1 si valor no es nulo. Si valor es nulo devuelve el sustituto2. 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: 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) SELECT idVenta, NVL(cantidad, 0) FROM Ventas;

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: 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) CURRENT_DATE CURRENT_TIMESTAMP DBTIMEZONE EXTRACT(valor FROM fecha) NVL2 ( expr1 , expr2 , expr3 )

Aade a la fecha el nmero de meses indicado por n. Retorna la fecha y hora actual en la zona horaria de la sesin. Retorna la fecha y hora actual con la informacin de zona horaria activa. Retorna la zona horaria actual en formato UTC. 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. Devuelve la fecha ms moderna de la lista. GREATEST(fecha1, ...) Obtiene el ltimo da del mes al que pertenece la fecha. Devuelve un valor LAST_DAY(fecha) DATE. Devuelve la fecha ms antigua de la lista. LEAST(fecha1, fecha2,...) Retorna el timestamp local en la zona horaria activa, pero sin mostrar la LOCALTIMESTAMP 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 Indica cual es el da que corresponde a aadir a la fecha el da indicado. El NEXT_DAY(fecha,da) 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'. Redondea la fecha al valor de aplicar el formato a la fecha. El formato ROUND(fecha [,'formato']) puede ser 'YEAR', 'MONTH', 'HH24' o 'DAY'. Retorna el valor de la zona horaria de la sesin actual. SESSIONTIMEZONE Extrae de la fecha actual al valor UTC (Coordinated Universal Time). SYS_EXTRACT_UTC Obtiene la fecha y hora actuales. SYSDATE SYSTIMESTAMP Obtiene la fecha y hora actuales en formato TIMESTAMP. Da formato a una fecha segn el patrn especificado en el segundo TO_CHAR(fecha,formato) argumento. Interprete un texto como una fecha segn el patrn especificado en el TO_DATE(texto,formato) 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. Trunca la fecha al valor de aplicar el formato a la fecha. El formato puede TRUNC(fecha, [formato]) ser 'YEAR', 'MONTH', 'HH24' o 'DAY'. Retorna la diferencia de zona horaria correspondiente al valor del TZ_OFFSET(texto) 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: 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: 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; SELECT NEXT_DAY(FechaInicial, 'Viernes') FROM Citas; SELECT SYSDATE FROM DUAL;

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':

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

SELECT FLOOR( MONTHS_BETWEEN(SYSDATE, '23/4/1987') / 12 ) FROM DUAL;

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. SELECT TO_DATE('28/3/2011') ROUND(SYSDATE) FROM DUAL;

Para obtener el nmero redondeado de das debemos usar la siguiente consulta: 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: El de fecha vlido) o una columna de tipo DATE. El numrico 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
/, -:.; A.D. AD A.M. AM B.C. BC CC SCC D DAY DD DDD DL DS DY E TO_CHAR( fecha [, formato [, parametrosNLS]]) TO_DATE( cadena [, formato [, parametrosNLS]]) argumento fecha debe ser un valor literal (con un formato argumento cadena debe ser un literal de texto, un literal

Significado Signos de puntuacin que sern incorporados en TO_CHAR e ignorados en TO_DATE. Indicador de AD. Muestra A.M. o P.M., dependiendo del momento del da. Indicador de BC. Siglo (por ejemplo, 21 para 2004). Siglo, para fechas BC prefijadas con guin. Nmero del da de la semana: de 1 a 7. El da con nombre completo. Nmero del da en el mes: de 1 a 31. Nmero del da en el ao (desde el 1 de enero): 1 a 366. La fecha en un formato largo, como por ejemplo 'Martes 14 de Junio de 2011'. La fecha en un formato corto, como por ejemplo '14/06/2011'. Las tres letras de abreviatura del da. Por ejemplo, VIE para el viernes. Abreviatura del nombre de era (para calendarios Japanese Imperial, ROC Official y Thai Buddha).
Oracle /46

EE FF [1..9] FM FX HH HH12 HH24 I IW IY IYY IYYY J MI MM MON MONTH P.M. Q RM RR RRRR SS SSSSS TS TZD TZH TZM TZR W WW X YEAR SYEAR YYYY SYYYY Y,YYY Y YY YYY

Versin a nombre completo del formato E. Fracciones de segundo. El nmero que sigue a FF especifica el nmero de dgitos en la parte de fracciones de segundo. Suprime espacios en blanco de rastreo y administracin. Sin FM, todos los meses y das son mostrados con el mismo ancho. Especifica que case el formato exacto para el argumento de texto y de formato. Hora del da: 1 a 12. Hora del da: 0 a 23. Un dgito de ao del estndar ISO. Semanas en el ao del estndar ISO: 1 a 53. Dos dgitos de ao del estndar ISO. Tres dgitos de ao del estndar ISO. Cuatro dgitos de ao del estndar ISO. Valor Juliano (das desde el 31 de Diciembre de 4712 B.C.). Minutos de la hora: 0 a 59. Nmero del mes: 1 a 12. Abreviatura de tres letras del mes (por ejemplo, AGO para agosto). El nombre completo del mes. Anlogo a A.M. Cuatrimestre del ao: 1 a 4. Nmero romano del mes. ltimos dos dgitos del ao relativo a la fecha actual. Ao redondeado, aceptando dos o cuatro dgitos. Segundos del minuto: 0 a 59. Segundos desde medianoche: 0 a 86399. Formato de hora corta, para usar con DL o DS. Informacin de tiempo de ahorros de luz del da. Hora de la zona horaria. Minuto de la zona horaria. Regin de la zona horaria. Nmero de semanas en un mes (desde 1 para la primera semana del mes). Nmero de semanas en un ao (desde 1 para la primera semana del ao). Carcter de raz local. El ao hablado en ingls. Por ejemplo, una fecha con el ao 2011 se corresponde con 'twenty eleven'. El ao con cuatro dgitos. Ao con separador de miles. ltimo dgito del ao. Dos ltimos dgitos del ao. 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: 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: En 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. SELECT TO_CHAR( TO_DATE( numeroMes , 'MM') , 'MONTH' ) FROM Tabla; este ejemplo, la funcin TO_DATE convierte previamente un nmero en una SELECT fecha, NEW_TIME(fecha, 'EST', 'HST') FROM Amigo;

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: 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
CREATE TABLE X1 (TSCOLTIMESTAMP(5) WITH TIME ZONE);

TIMESTAMP.

Adems del tipo TIMESTAMP, Oracle soporta dos tipos de datos para intervalos:

El 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 UID

INTERVALYEAR(precisin_del_ao) TO MONTH INTERVAL DAY (precisin_del_da) TO SECOND (precisin_fraccin_segundos) tipo INTERVAL YEAR TO MONTH almacena un periodo de tiempo en aos y meses,

USERENV('atributo')

SYS_CONTEXT('namespace', 'atributo' [, len])

Pseudo-columna de SQL*Plus que devuelve un valor VARCHAR2 que contiene el nombre de usuario actual de Oracle. 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. 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. Esta funcin permite recuperar informacin (como un VARCHAR2) asociada a un 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: Podemos aadir un atributo (usuario) al espacio de nombres con el siguiente comando: Y
DBMS_SESSION.SET_CONTEXT('MiContexto', 'usuario', 'Pedro'); podemos recuperar el valor del atributo como un VARCHAR2 con: CREATE OR REPLACE CONTEXT Mi_Contexto USING Paquete_Contexto;

Oracle /49

SYS_CONTEXT('Mi_Contexto', 'usuario')

2.3.7. Funciones de conversin.


ASCIISTR BIN_TO_NUM CAST CHARTOROWID COMPOSE CONVERT DECODE DECOMPOSE HEXTORAW NUMTODSINTERVAL NUMTOYMINTERVAL RAWTOHEX RAWTONHEX ROWIDTOCHAR ROWIDTONCHAR SCN_TO_TIMESTAMP TIMESTAMP_TO_SCN TO_BINARY_DOUBLE TO_BINARY_FLOAT TO_CHAR TO_CLOB TO_DATE TO_DSINTERVAL TO_LOB TO_MULTI_BYTE TO_NCHAR TO_NCLOB TO_NUMBER TO_SINGLE_BYTE TO_TIMESTAMP TO_TIMESTAMP_TZ TO_YMINTERVAL TRANSLATE UNISTR

Traslada un string a algn juego de caracteres y retorna un string ASCII en el juego de caracteres de la base de datos. Convierte valores binarios en su equivalente numrico. Moldea un tipo predefinido o de coleccin a otro. Se usa normalmente con tablas anidadas y arrays variables. Cambia un string de caracteres para que acten como un identificador de fila interno de Oracle, o RowID. Traslada un string de algn tipo de dato o un string Unicode a una forma completa normalizada. Convierte una cadena de caracteres desde un lenguaje nacional a otro. Selecciona un valor CHAR, VARCHAR2 o NUMBER de una lista segn un valor. Traslada un string de algn tipo a un string Unicode despus de su descomposicin cannica en el mismo juego de caracteres. Cambia una cadena de caracteres de nmeros hexadecimales en un valor binario. Convierte un nmero a un literal INTERVAL DAY TO SECOND. Convierte un nmero a un literal INTERVAL YEAR TO MONTH. Cambia un string de nmeros binarios a un string de caracteres de nmeros hexadecimales. Convierte un raw a un valor NVARCHAR2 que contiene su equivalente hexadecimal. Cambia un identificador de fila interno de Oracle, o RowID, a un string. Convierte un valor RowID a un valor NVARCHAR2. Convierte un nmero de cambio de sistema a su aproximado TIMESTAMP. Convierte un TIMESTAMP a nmero de cambio de sistema aproximado. Cambia un valor binario a un nmero de doble precisin con coma flotante. Cambia un valor binario a un nmero de simple precisin con coma flotante. Convierte un NUMBER o DATE a un string. Convierte un valor NCLOB a un valor CLOB. Convierte un NUMBER, CHAR o VARCHAR2a DATE. Convierte un string del tipo CHAR, VARCHAR2, NCHAR oNVARCHAR2a un valor INTERVAL DAY TO SECOND. Convierte un LONG a un LOB como parte de una insercin o seleccin. Convierte caracteres de un byte en un string de caracteres de varios bytes. Convierte un string, NUMBER o DATE a al formato nacional. Convierte valores CLOB a valores NCLOB. Convierte un CHAR o VARCHAR2 a nmero. Convierte un CHAR o VARCHAR2a bytes simples. Convierte un string a un valor TIMESTAMP. Convierte un string a un valor TIMESTAMP WITH TIME ZONE. Convierte un string del tipo CHAR, VARCHAR2, NCHAR o NVARCHAR2 a un valor INTERVAL YEAR TO MONTH. Traslada caracteres en un string dentro de diferentes caracteres. 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: 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 SELECT 5 + '3' FROM DUAL SELECT 5 || '3' FROM DUAL -- El resultado es 8 -- El resultado es 53

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,

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: 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; DECODE ( expresinBase, comparando1, valor1, comparando2, valor2, ... [, valorPorDefecto] )

234567890, 'BCDEFGHIJ') 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:

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;

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

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: 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
catlogo.esquema.objeto

Vistas con prefijo USER_: Puede utilizarlas cualquier usuario de la base de datos y se refieren a objetos posedos por dicho usuario. Por ejemplo: 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%'; 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 SELECT * FROM USER_TABLES;

Por ejemplo, para ver todas las vistas relacionadas con tablas podramos ejecutar: (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: Una vez creada la base de datos, debemos indicar explcitamente que queremos trabajar con ella:
USE MiBaseDeDatos; CREATE DATABASE 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:

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;

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.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

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: 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; CREATE TABLESPACE "APPIDX" LOGGING DATAFILE '/export/home/oracle/oradata/datafiles/APPIDX.dbf' SIZE 512M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; CREATE UNDO TABLESPACE undotbs02 DATAFILE 'c:\oraclexe\oradata\ex\undo02.dbf'SIZE 25M REUSE AUTOEXTEND ON;

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.

para los datos, con tamao inicial de 1024 Mb, y auto extensible; y usaremos

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 Si 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: 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. En el momento que el usuario crea el primer objeto en la BD, se crea automticamente el esquema.
Oracle /55
GRANT "CONNECT" TO "APP"; GRANT "RESOURCE" TO "APP"; CREATE INDEX mi_indice ON mi_tabla(mi_campo) TABLESPACE APPIDX; CREATE USER "APP" PROFILE "DEFAULT" IDENTIFIED BY "APPPWD" DEFAULT TABLESPACE "APPDAT" TEMPORARY TABLESPACE "TEMP" ACCOUNT UNLOCK; no se especifica un tablespace, la BD le asignar el tablespace USERS, que es el tablespace

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:

En 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 tabla ( campo1 tipo (tamao) restricciones1 , ..., campoN tipo (tamao) restriccionesN , CONSTRAINT nombre_restriccin tipo_restriccin (columnas) ... ); donde tabla es el nombre de la tabla que se va a crear; campo1...campoN

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: 3.6.4. Cambiar de nombre. La orden RENAME permite el cambio de nombre de cualquier objeto. Sintaxis: 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. 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: Para cambiar el tipo de datos y propiedades de una determinada columna:
ALTER TABLE Empleado MODIFY (Tipo INT); ALTER TABLE Empleado ADD Tipo VARCHAR(20) NULL; TRUNCATE TABLE nombreTabla ; RENAME nombreViejo TO nombreNuevo ; DROP TABLE nombreTabla ;

Para eliminar un campo existente de una tabla:

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);

ALTER TABLE Empleado DROP COLUMN Tipo;

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:

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;

ALTER TABLE Empleado SET UNUSED COLUMN Fecha_Nacimiento;

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: Y aparecern los campos de la tabla Empleado, de forma parecida a la siguiente:
Nombre ------------------------ID NOMBRE APELLIDOS FECHA_NACIMIENTO CATEGORIA Null? ------- -----NOT NULL NOT NULL NOT NULL Tipo ---------------------NUMBER(38,0) VARCHAR2(25) VARCHAR2(50) DATE VARCHAR2(1) DESCRIBE Empleado;

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: 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: 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'; SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME='MITABLA' COMMENT ON { TABLE NombreTabla | COLUMN tabla.nombreColumna } IS 'Comentario'

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) ; 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

Se puede crear una clave primaria sobre ms de un campo:

integridad referencial. En la siguiente instruccin,

clave fornea, y de esta forma activar la

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');

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 se relaciona con la columna cod de la tabla pelcula.

el campo cod_pelicula

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 seguidos, sin comas). Por ejemplo:
Oracle /59

CONSTRAINT

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:

En 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), (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:

CREATE TABLE ingreso ( cod NUMBER(5) PRIMARY KEY, importe NUMBER(11,2), CONSTRAINT importe_rango_ck CHECK (importe>0 AND importe<8000) ); este caso, CHECK prohbe aadir datos cuyo importe no est entre 0 y 8000.

PK

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:

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: 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: 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; ALTER TABLE tabla ENABLE CONSTRAINT nombre [CASCADE] ALTER TABLE tabla DISABLE CONSTRAINT nombre [CASCADE]

ALTER TABLE tabla DROP PRIMARY KEY | UNIQUE (campos) | CONSTRAINT nombreRestriccin [CASCADE]

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: 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: 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
CREATE INDEX nombre_completo ON cliente (apellido1, apellido2, nombre); CREATE [BITMAP | UNIQUE] INDEX nombreIndice ON nombreTabla (columna [,columna] . . .) [REVERSE];

- 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. 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

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);

ALTER TABLE Biblioteca ADD CONSTRAINT B_UK UNIQUE (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: 2: 3: 4: 5: 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 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; este ejemplo, B_Indices es el nombre de un

En 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: 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; CREATE INDEX Biblioteca$UPPER_Titulo ON Biblioteca (UPPER(Titulo));

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 reali zarse 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 ); este ejemplo, la tabla Biblioteca_Partida ser particionada segn el valor de la

En columna 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: 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
PARTITIONS 2 STORE IN (Parte_TS, Parte2_TS);

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; clusula GLOBAL de este comando CREATE INDEX

La 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: 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: 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, CREATE INDEX LibroAutorNDX ON CLUSTER LibroAutor; CREATE CLUSTER LibroAutor (Col1 INT); CREATE CLUSTER nombreCluster (columna tipoDeDato [, columna tipoDeDato] . . . ) [otras opciones];

debemos crear un ndice de clster:

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,

uno en uno.

indica cunto se incrementa la secuencia cada vez que se usa. Por defecto se incrementa de

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:

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}]

INSERT INTO plantas (num, uso) VALUES (numeroPlanta.NEXTVAL, 'Suites');

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: 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: De esta forma, si el usuario Juan tiene permisos de consulta sobre la tabla VENTAS, podr consultarla desde su cuenta con el siguiente comando: 3.12.2. Borrar sinnimos. Se puede eliminar un sinnimo con el comando DROP SYNONYM seguido del nombre del sinnimo.
DROP SYNONYM sinnimo; SELECT * FROM VENTAS; CREATE PUBLIC SYNONYM VENTAS FOR Andres.VENTAS; CREATE [PUBLIC] SYNONYM nombre FOR objeto;

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). 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 INSERT INTO Empleado DEFAULT VALUES

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;

que proporcione un valor para cada campo

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: 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 Metal Celsius Fahrenheit
Hierro Plata Cobre Oro -18 12,5 -9,8 14,4 -2 54 14 57 INSERT /*+ APPEND */ INTO Nombre_Tabla . . .

Tabla Temp Metal Escala Valor

Tabla TempC Metal Valor Tabla TempF Metal Valor

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
Hierro Plata Cobre Oro Hierro Plata Cobre Oro

Escala
Celsius Celsius Celsius Celsius Fahrenheit Fahrenheit Fahrenheit Fahrenheit

Valor
-18 12,5 -9,8 14,4 -2 54 14 57 TempF

Pero si ahora queremos poblar la tabla TempC con las temperaturas en Celsius y la tabla 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

con las

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 este caso, como resultado, la tabla Temp se puebla con los siguientes datos:

En

Metal Escala
Plata Oro Plata Cobre Oro Celsius Celsius Fahrenheit Fahrenheit Fahrenheit

Valor
12,5 14,4 54 14 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
Plata Oro Cobre Celsius Celsius Fahrenheit

Valor
12,5 14,4 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 no son enviados a la tabla Temp. Con INSERT FIRST podemos subordinar varios INTO a una misma condicin:

WHEN,

y por ello

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 provocaron una insercin en Temp:

de

Temperaturas

que no

Metal
Hierro

Celsius Fahrenheit
-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 Tabla "Persona" 1
2 3 4 Juan Prez Mara Lpez Ramn Llull Jos Prez

ID Nombre Tabla "Cliente"


2 4 6 Mara Lpez Jos Prez Javier Llull

Saldo
10000 90000 15000

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 6 Ramn Llull Javier Llull 100 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 1 nif nombre apellidos localidad MATRICULA n idMatricula nif ao

1 n

NOTA idNota valor nif idModulo FALTA n idFalta fecha idMatricula idModulo

MODULO 1 1 idModulo nombre

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: 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; SELECT campos FROM Tabla;

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 ----------------Juan Marian APELLIDOS -------------------------Martnez Pan 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: 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; SELECT apellidos AS Alumno FROM Alumno; SELECT apellidos Alumno FROM Alumno; -- o bien: -- no es necesaria la palabra AS

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: 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: 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; SELECT nif, nombre, apellidos FROM Cliente ORDER BY apellidos, nombre; SELECT nif, nombre, apellidos FROM Alumno ORDER BY apellidos;

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: 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. 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; SELECT * FROM FALTA ORDER BY EXTRACT(MONTH FROM fecha) SELECT nif, nombre, localidad AS Ciudad FROM Cliente ORDER BY Ciudad;

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: 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 DISTINCT SELECT nombre, apellidos FROM ALUMNO ORDER BY localidad;

Devuelve todos los campos de la tabla. 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; SELECT * FROM Alumno; -- es equivalente a:

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: 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 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
SELECT idAlumno, idModulo, valor + 1FROM Nota; SELECT DISTINCT apellidos FROM Alumno;

apellidos de los alumnos con el formato: "apellidos, nombre".

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: -----------------------------Apellidos y nombre: Apellidos y nombre: Nombre completo ---------------------------------Martnez Pan, Juan Lpez Sobrado, Marian

SELECT 'Apellidos y nombre:' , apellidos ||', '|| nombre AS "Nombre completo" FROM Alumno;

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: 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

expresin1 Operador expresin2 Verdad Falso AND Verdad Verdad AND Falso Verdad AND Falso Falso AND Verdad Falso OR Verdad Verdad OR Falso Verdad OR Falso Falso OR

Resultado Falso Verdad Falso Falso Verdad Verdad Verdad 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: 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 Varios caracteres Varios caracteres Un solo carcter Modelo Planteado Coincide
a%a ab% a_a expresin LIKE modelo

No coincide

'aa', 'aBa', 'aBBBa' 'aBC' 'abcdefg', 'abc' 'cab', 'aab' '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

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. 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) ); SELECT * FROM Alumno WHERE localidad IN ('Madrid', 'Barcelona', 'Sevilla');

expresin [NOT] IN (valor1, valor2, ...) ; expresin [NOT] IN ( subconsulta ) ;

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: 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, SELECT A.nif, N.idModulo, N.valor FROM Alumno A LEFT JOIN Nota N ON A.nif = N.nif;

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: 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 SELECT M.idModulo, N.nif, N.valor FROM Nota N RIGHT JOIN Modulo M ON N.idModulo = M.idModulo;

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: 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); SELECT N.idModulo, N.nif, N.valor, F.fecha FROM Nota N FULL JOIN FaltaF ON N.idModulo = F.idModulo;

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);

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:
JOIN/ON 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:

Por 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: 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: 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; SELECT nif FROM Alumno UNION SELECT nif FROM Matricula ORDER BY nif; SELECT nif FROM Alumno UNION SELECT nif FROM Matricula ; consulta1 UNION [ALL] consulta2 [UNION [ALL] . . . consultaN]

SELECT N.nif FROM Matricula M JOIN (Falta F JOIN Modulo M ON F.idModulo=M.idModulo) ON M.idMatricula=F.idMatricula; ltimo, dos reglas de anidamiento de JOIN:

O bien:

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': COUNT. Calcula el nmero de registros devueltos por una consulta. Su sintaxis es la siguiente 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; COUNT(expr) SELECT AVG(valor) AS "Nota media" FROM Nota WHERE nif='11111111A';

Si el campo localidad admite valores nulos, la siguiente consulta calcula el nmero de alumnos registrados que tengan asignada alguna localidad: 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: una consulta. Su sintaxis es:
MIN(expr) MAX(expr) En donde expr SELECT COUNT( DISTINCT localidad) AS Total FROM Alumno; MAX, MIN. Devuelven el mnimo o el mximo de un conjunto SELECT COUNT(localidad) AS Total FROM Alumno;

de valores obtenidos de una expresin de

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 SUM(expr)

es:

expresin de una consulta. Su sintaxis

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': 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
SELECT SUM(valor) AS 'Suma de notas' FROM Nota WHERE nif = '11111111A';

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: Sin embargo, no podemos obtener un resultado razonable para sumas de edades con: 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: Retorna el valor 20, puesto que en 80 filas el valor para edad es NULL. Sin embargo, la consulta:
SELECT COUNT(*) FROM Amigo; SELECT COUNT(edad) FROM Amigo; SELECT SUM(edad) FROM Amigo; SELECT AVG(edad) 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 Provocar el error:
SELECT SUM( AVG(valor)) FROM NOTA; 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: 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: Un posible resultado podra ser el siguiente
SELECT COUNT(DISTINCT localidad) "N localidades", COUNT(localidad) "N registros", COUNT(*) FROM ALUMNO; N localidades ----------------10 COUNT cuente N registros -------------25 COUNT(*) ------------30 SELECT MAX(valor) - MIN(valor) FROM NOTA;

La opcin DISTINCT fuerza que 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 ; consulta realiza el join entre las tablas Alumno, Matricula y Nota, descartando aquellas

La 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 ; consideracin: en la consulta anterior no podramos incluir el campo fecha

Una

como una columna del 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
SELECT.

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 INSERTINTO, DELETE, o UPDATE o dentro de otra subconsulta. Se pueden utilizar tres formas de sintaxis para crear una subconsulta:
SELECT, SELECT...INTO,

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") esta consulta se compara el nif de cada registro de MATRICULA con el valor del nif del alumno

En 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:

En 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) ); estrategia en esta subconsulta es obtener el listado de registros de la tabla Falta excluyendo el registro

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 )); este caso las subconsultas se utilizan mediante una condicin IN. Para evaluar la consulta completa, el

La 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

que han cursado.

y el nmero de mdulos

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:

Donde:

CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW nombre_vista [(alias[, alias2...]] AS consultaSelect [WITH CHECK OPTION [CONSTRAINT restriccin]] [WITH READ ONLY [CONSTRAINT restriccin]]

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;

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

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: Y entonces alteramos la tabla subyacente:
CREATE OR REPLACE VIEW Alumno_View AS SELECT * FROM Alumno;

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: 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; SELECT * FROM USER_VIEWS;

ALTER TABLE Alumno ADD (pais VARCHAR2(30));

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: 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: 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; SELECT * FROM Piezas WHERE tipo='&tip'; SELECT * FROM Piezas WHERE modelo=&mod;

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 variable tip.

tipo sea

TU.

SQL*Plus no preguntar por el valor de la

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: Las variables ms interesantes a utilizar son:
Variable Explicacin Repite el comando SQL antes de mostrar su resultado. ECHO Permite mostrar estadsticas sobre el tiempo de ejecucin en TIMING cada consulta SQL que se ejecute (interesante para estadsticas). Hace que el encabezado con los alias de las columnas se active HEADING ON y OFF o no. Activado, trunca un texto si sobrepasa la anchura mxima. WRAP ON y OFF Permite indicar la versin con la que se comprueba la COMPATIBILITY V7, V8, NATIVE 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. n Indica el nmero de filas que se muestran antes de repetir el PAGESIZE encabezado de la consulta n Indica la anchura mxima de la lnea de la consulta. Si una lnea LINESIZE 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. valor Indica qu valor se muestra cuando hay nulos. NULL formato Permite especificar un formato que se aplicar a todos los NUMFORMAT nmeros. (Vase formato de columnas, ms adelante). valor Indica la anchura mxima utilizada para mostrar nmeros. Si NUMWIDTH un nmero sobrepasa esta anchura, es redondeado. Hace que se muestren el nmero total de registros de la FEEDBACK n, ON y OFF consulta cuando el resultado supera los n registros. ancho LONG Anchura mxima para los campos de tipo LONG. Posibles valores ON y OFF ON y OFF
SET nombreVariable valor

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 El texto es lo que se desea en el encabezado o pie. Ese texto puede incluir las palabras 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'; {B|T}TITLE {texto|ON|OFF} LEFT, RIGHT

o CENTER

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. 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; COLUMN precio_venta HEADING 'Precio de|venta'; SELECT tipo, modelo, precio_venta FROM piezas;

Para los nmeros se usan cdigos de posicin:


Cdigo Significado Posicin para un nmero. Si el valor es 0 o vaco, entonces no se muestra nada 9 Posicin para un nmero. Si el valor es 0 o vaco, entonces se muestra 0 0 Posicin para el signo de dlar $ Muestra un signo menos tras el nmero, si el nmero es negativo (ejemplo: '999MI') MI Muestra el signo del nmero (+ -) en la posicin en la que se coloca el signo S Muestra los nmeros negativos entre < y > PR Muestra el signo decimal en esa posicin D Muestra el signo de grupo en esa posicin G Muestra el punto (separador decimal) . Muestra la coma (separador de miles) , Muestra el smbolo de moneda nacional en esa posicin L Muestra el nmero en romano (maysculas) RN Muestra el nmero en romano (minsculas) rn

Las fechas deben ser formateadas desde la propia instruccin SQL mediante la funcin 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;

TO_CHAR

(vista en un

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: Hace que las columnas con alias
BREAK ON tipo; 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: La 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} BREAK ON tipo ON modelo; orden CLEAR BREAK elimina todos

Donde:

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;

funcin, es el nombre de la funcin de clculo que se usa ( SUM, AVG, MIN, MAX, NUM, STD LABEL, permite indicar un texto previo al resultado del clculo, si no se utiliza se pone

o VAR). el nombre de la

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: O bien:


SQL> @comandos.sql 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. 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 SQL> SPOOL /tmp/mi_fichero_de_texto.lst

Oracle /93

Si ahora leemos el contenido del archivo pantalla.

SQL> SPOOL d:\tmp\listado.lst SQL> PROMPT TEST SQL> SPOOL OFF

listado.lst

veremos que contiene lo mismo que se mostr por

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'; ORDEN 1 2 3 NIF 44444444L 55555555V 33333333H APELLIDOS Lpez Martn Senn Rivas Garca Gmez

Produce un resultado como ste:

Si aplicamos una ordenacin por nif: Se producir el siguiente resultado:

SELECT ROWNUM AS "Orden", nif, apellidos FROM Alumno WHERE localidad = 'Madrid' ORDER BY nif; ORDEN 3 1 2 NIF 33333333H 44444444L 55555555V APELLIDOS Garca Gmez Lpez Martn 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

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

un nmero,

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: Donde:
OOOOOOFFFBBBBBBRRR

Oracle /94

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: 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; SELECT ROWID, nombre, apellidos FROM Alumno;

OOOOOO:

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. 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; NIF ---------------00000000A 22222222B 33333333C 44444444D 55555555E CREATE VIEW NOTAS_AVG AS (nif, notaMedia) SELECT nif, AVG(valor) FROM Nota GROUP BY nif;

Siendo un posible resultado el siguiente:

NOTAMEDIA ----------------9,8 8 8 6,5 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; RANKING ---------------4

Siendo el resultado:

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: Siendo el resultado:
SELECT PERCENT_RANK(7) WITHIN GROUP (ORDER BY notaMedia DESC) "Ranking" FROM NOTAS_AVG;

Oracle /95

Es decir, estara en una posicin casi intermedia 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)); CODIGO -----------1 2 3 4 5 6

RANKING ---------------,6 (con el 60%).

E insertamos los siguientes registros:

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: Obtendramos por ejemplo:
SELECT E.nombre AS empleado, J.nombre AS jefe FROM Empleado EJOIN Empleado J ON (E.codigoJefe=J.codigo); EMPLEADO -------------Antonio ngel Eva Carmen Andrs Carmelo JEFE ---------ngel ngel Eva Eva Andrs

NOMBRE -----------ngel Eva Andrs Antonio Carmen Carmelo

CODIGOJEFE -----------------1 2 1 2 3

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 apartado CONNECT permite indicar qu relacin hay que

El 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:

Sin embargo, la siguiente consulta:

NOMBRE -----------Andrs Eva ngel

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:

Para eliminar recorridos se utilizan

En este ejemplo, Eva no sale en los resultados. En este otro:

SELECT LEVEL, nombre FROM Empleado WHERE nombre<>'Eva' START WITH nombre='ngel' CONNECT BY codigoJefe= PRIOR codigo;

LEVEL NOMBRE -------- -----------1 ngel 2 Antonio 2 Eva 3 Carmen 3 Andrs 4 Carmelo condiciones en WHERE o en el

propio CONNECT. De modo que:

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

SELECT LEVEL, nombre FROM Empleado START WITH nombre='ngel' CONNECT BY codigoJefe= PRIOR codigo AND nombre<>'Eva';

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 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);

AVG(valor)

es el mismo

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 11111111A 11111111A 11111111A 22222222B 22222222B 22222222B 33333333C 33333333C 33333333C NOMBRE Modulo1 Modulo2 Modulo1 Modulo2 Modulo1 Modulo2 NOTA MEDIA 5 6 5,5 4 7 5,5 8 9 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 11111111A 11111111A 22222222B 22222222B 33333333C 33333333C NOMBRE Modulo1 Modulo2 Modulo1 Modulo2 Modulo1 Modulo2 NOTA MEDIA 5 6 4 7 8 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; NIF 11111111A 22222222B 33333333C NOMBRE Modulo1 Modulo1 Modulo1 Modulo1

Con lo cual se obtiene filas de resumen donde slo los campos incluidos en ROLLUP estarn a nulo:
NOTA MEDIA 5 4 8 5,6

Oracle /98

11111111A 22222222B 33333333C

Modulo2 Modulo2 Modulo2 Modulo2

6 7 9 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); NIF 11111111A 11111111A 11111111A 22222222B 22222222B 22222222B 33333333C 33333333C 33333333C NOMBRE Modulo1 Modulo2 Modulo1 Modulo2 Modulo1 Modulo2 Modulo1 Modulo2

Y el resultado es:

NOTA MEDIA 5 6 5,5 4 7 5,5 8 9 8,5 5,6 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); NIF 11111111A 11111111A 11111111A 22222222B 22222222B 22222222B 33333333C 33333333C 33333333C NOMBRE Modulo1 Modulo2 Modulo1 Modulo2 Modulo1 Modulo2 Modulo1 Modulo2 NOTA MEDIA 5 6 5,5 4 7 5,5 8 9 8,5 5,6 7,3 6,5 SW_NIF 0 0 0 0 0 0 0 0 0 1 1 1 SW_MOD 0 0 1 0 0 1 0 0 1 0 0 1

Genera el siguiente resultado:

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)) ; 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) );

Que mostrara un informe espectacular sobre las tablas anteriores. As como:

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* BINARY_FLOAT* BINARY_INTEGER BOOLEAN CHAR CHARACTER DATE DEC DECIMAL DOUBLE PRECISION FLOAT INT INTEGER INTERVAL DAY TO SECOND INTERVAL YEAR TO MONTH LONG LONG RAW NATURAL NATURALN NCHAR NUMBER NUMERIC NVARCHAR2 PLS_INTEGER POSITIVE POSITIVEN RAW REAL ROWID SIGNTYPE SMALLINT STRING TIMESTAMP TIMESTAMP WITH LOCAL TIME ZONE TIMESTAMP WITH TIME ZONE UROWID VARCHAR VARCHAR2

* 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; IFV=1 THEN -- hacer algo; ELSE IFV=2THEN -- hacer algo; ELSE -- hacer algo; END IF; END IF;

Si queremos encadenar varios bloques IF debemos hacerlo de la siguiente manera:

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; siguiente ejemplo accede al campo nombre de la tabla Producto y los FOR p IN (SELECT nombre FROM Producto) LOOP DBMS_OUTPUT.PUT_LINE( p.nombre ); -- se imprime el nombre END LOOP;

El

imprime:

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: Donde:
nombre_variable [CONSTANT] tipo_de_dato [NOT NULL] [:=valor_inicial]

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.
tipo_de_dato 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; CREATE PROCEDURE simple_procedure IS

Ejemplo de estructura de un subprograma:

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);

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);

Retorna una nica lnea del bfer. El siguiente ejemplo muestra como 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); DECLARE lo DBMSOUTPUT_LINESARRAY := DBMSOUTPUT_LINESARRAY(10); fetchln INTEGER := 15; BEGIN lo(1) := 'ABC'; lo.EXTEND;

Recupera un array de lneas desde el bfer. El siguiente ejemplo muestra cmo usar este procedimiento:

Recupera un array de lneas desde el bfer. El siguiente ejemplo muestra cmo usar este procedimiento:

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)); END; / DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE(a IN VARCHAR2);

-- 5

Inserta una marca de fin de lnea en el bfer.

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:

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;

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;

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
ACCESS_INTO_NULL COLLECTION_IS_NULL CURSOR_ALREADY_OPEN

DUP_VAL_ON_INDEX

INVALID_CURSOR INVALID_NUMBER

Se ejecuta ... El programa intent asignar valores a los atributos de un objeto no inicializado El programa intent asignar valores a una tabla anidada an no inicializada El programa intent abrir un cursor que ya se encontraba abierto. Recuerde que un cursor de ciclo FOR automticamente lo abre y ello no se debe especificar con la sentencia OPEN El programa intent almacenar valores duplicados en una columna que se mantiene con restriccin de integridad de un ndice de unicidad El programa intent efectuar una operacin no vlida sobre un cursor En una sentencia SQL, la conversin de una cadena de caracteres hacia un nmero falla cuando esa cadena no representa un nmero vlido
Oracle /107

SQLCODE
-6530 -6531 -6511

-1

-1001 -1722

LOGIN_DENIED

El programa intent conectarse a Oracle con un nombre de usuario o contrasea invlido Una sentencia SELECT INTO no devolvi valores o el NO_DATA_FOUND programa referenci un elemento no inicializado en una tabla indexada El programa efectu una llamada a Oracle sin estar conectado NOT_LOGGED_ON PL/SQL tiene un problema interno PROGRAM_ERROR Los elementos de una asignacin (el valor a asignar y la variable ROWTYPE_MISMATCH que lo contendr) tienen tipos incompatibles. Tambin se presenta este error cuando un parmetro pasado a un subprograma no es del tipo esperado El parmetro SELF (el primero que es pasado a un mtodo SELF_IS_NULL MEMBER) es nulo La memoria se termin o est corrupta STORAGE_ERROR SUBSCRIPT_BEYOND_COUNT El programa est tratando de referenciar un elemento de un 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 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 fall porque la cadena no representa un nmero Se excedi el tiempo mximo de espera por un recurso en TIMEOUT_ON_RESOURCE Oracle Una sentencia SELECT INTO devuelve ms de una fila TOO_MANY_ROWS Ocurri un error aritmtico, de conversin o truncamiento. Por VALUE_ERROR ejemplo, sucede cuando se intenta calzar un valor muy grande dentro de una variable ms pequea El programa intent efectuar una divisin por cero ZERO_DIVIDE

-1017 100

-1012 -6501 -6504

-30625 -6500 -6533

-6532

-1410 -51 -1422 -6502

-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 subbloques 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

Con 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

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; la sentencia RAISE podemos lanzar una excepcin definida

sta devolver el mensaje asociado.

negativo que represente un error de Oracle y

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; operaciones de tipo SELECT, los cursores implcitos

Para 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: 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: Cuando queramos recuperar informacin del cursor, deberemos utilizar el comando sintaxis:
FETCH nombreCursor INTO variable1, variable2, ...; OPEN nombreCursor; CLOSE nombreCursor; FETCH CURSOR nombreCursor IS sentencia_Select;

con la siguiente

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

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;

... END LOOP;

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 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;

LOOP

de la siguiente

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; valor del parmetro es pasado en este caso al referenciar el cursor en la instruccin FOR. En otros casos OPEN c1('Madrid');

El pasar el parmetro al abrir el cursor con la instruccin OPEN:

se

4.4. Cursores de actualizacin. Se utilizan los cursores de actualizacin para determinar los registros afectados por una operacin Para ello, tanto el cursor como el comando UPDATE deben utilizar la misma tabla base.
Oracle /111

UPDATE.

Los cursores de actualizacin se declaran igual que los cursores explcitos, aadiendo la sentencia SELECT.
CURSOR nombre_cursor IS instruccin_SELECT FOR UPDATE

FOR UPDATE

al final de

Para utilizar este tipo de cursor hay que ejecutar una sentencia CURRENT OF nombre_cursor. La sintaxis es:
UPDATE nombre_tabla SET campo_1 = valor_1 [, campo_2 = valor_2] WHERE CURRENT OF nombre_cursor

UPDATE

especificando la clusula WHERE

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: 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: 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]; uso de OR REPLACE permite sobrescribir un procedimiento existente. Si se omite, y el procedimiento EXECUTE PAQUETE_LIBRO.NUEVO_LIBRO('Un libro'); GRANT EXECUTE ON un_precedimiento TO un_usuario;

El 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

Tambin podemos asignar un valor por defecto a los parmetros, utilizando la clusula operador de asignacin (:=) .

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;

DEFAULT

o el

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;

CREATE PROCEDURE Actualiza_Nota(pNif IN VARCHAR2, pIdModulo NUMBER, pNota NUMBER DEFAULT 5) ...

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. un error el ejecutar el comando CREATE FUNCTION.

Si se omite, y la funcin existe, se producir

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:

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

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 ;

Oracle /114

Las funciones pueden utilizarse en sentencias SQL de manipulacin de datos ( SELECT, DELETE) siempre y cuando no realicen operaciones de actualizacin en su cdigo:
SELECT nif, nombre, apellidos, fn_NotaMedia( nif )FROM Alumno;

notaMedia NUMBER; BEGIN notaMedia := fn_NotaMedia ('2222222B'); END;

UPDATE, INSERT

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

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.
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 SELECT

(numrico)

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; siguiente ejemplo crea un paquete llamado PKG_ACADEMIA que incluye CREATE OR REPLACE PACKAGE PKG_ACADEMIA IS -- Declaraciones de tipos y registros pblicas TYPE Reg_ResumenNotas IS RECORD (

El funciones y procedimientos para procesar los datos de alumnos, matrculas, notas, etc. Para crear la especificacin del paquete:

Oracle /116

); -- 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;

minima NUMBER(2,0), maxima NUMBER(2,0), media NUMBER(2,2)

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 PROCEDURE. Para recompilar una funcin se usa el comando ALTER FUNCTION con la clusula COMPILE:
ALTER FUNCTION Libros_Cambiados COMPILE;

ALTER ANY

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]; ALTER PACKAGE GESTOR_LIBRO COMPILE;

Para recompilar un paquete se usa el comando precedente con la clusula COMPILE, tal como sigue: 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

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...

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;

Para regresar a un punto de ruptura concreto se utiliza el comando: 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; END; ROLLBACK TO SAVEPOINT nombreSavepoint;

-- Se lanza una excepcin.

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; uso de OR REPLACE permite sobrescribir un trigger existente.

El 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
INSERT OLD NEW

No definido; todos los campos toman Valores que sern insertados cuando se complete la
Oracle /123

UPDATE DELETE

orden. valor NULL. Valores originales de la fila, antes de la Nuevos valores que sern escritos cuando se actualizacin. complete la orden. 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 ; trigger se ejecutar automticamente cuando sobre la tabla Alumno se ejecute una sentencia INSERT INSERT INTO Alumno (nif, nombre, apellidos, localidad) VALUES ('66666666H', 'Juan' , 'Salgado Rey', 'Madrid');

El

como:

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
INSERTING TRUE UPDATING TRUE DELETING TRUE

Retorna si el comando de disparo es INSERT; FALSE en otro caso. si el comando de disparo es UPDATE; FALSE en otro caso. 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 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 idMatricula como si no, se lanzar un trigger que asigne automticamente el valor.

2) Creamos un trigger como el siguiente:

CREATE SEQUENCE SQ_IDMatricula;

si pasamos un valor para

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

ORA_DICT_OBJ_NAME,

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; /

ejemplo, podemos referenciar atributos del sistema (en el ejemplo, recupera el nombre del objeto creado). Los atributos disponibles se listan en la tabla

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

queramos mostrar al usuario.

para personalizar un mensaje de usuario que

Oracle /125

La siguiente tabla describe los atributos de sistema que podemos usar en este tipo de triggers.
Atributo
ora_client_ip_address

Tipo
VARCHAR2

Descripcin y ejemplo 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 OUT ora_name_list_t)

BINARY_INTEGER

Retorna la lista de nombres de objetos que estn 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 OUT ora_name_list_t)

BINARY_INTEGER

Retorna la lista de propietarios de los objetos 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); Retorna los permisos de un evento GRANT

ora_grantee (user_list OUT ora_name_list_t)

BINARY_INTEGER

en el parmetro de salida; retorna el nmero de concesiones.


if (ora_sysevent='GRANT') then number_of_users:=ora_grantee(user_list); end if; if (ora_instance_num=1) then insert into event_table('1'); end if;

ora_instance_num

NUMBER

Nmero de instancia.

Oracle /126

ora_is_alter_column (column_name IN VARCHAR2)

BOOLEAN

Retorna TRUE si la columna especificada es modificada.


if (ora_sysevent='ALTER' and ora_dict_obj_type='TABLE') then alter_column:=ora_is_alter_column('FOO'); end if; Retorna TRUE si el evento actual es creando una

ora_is_creating_nested_table

BOOLEAN

tabla anidada.

ora_is_drop_column (column_name IN VARCHAR2)

BOOLEAN

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; Retorna TRUE si la columna especificada

borrada.

es

ora_is_servererror

BOOLEAN

if (ora_sysevent='ALTER' and ora_dict_obj_type='TABLE') then drop_column:=ora_is_drop_column('FOO'); end if; 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 ora_partition_pos

VARCHAR2(30) BINARY_INTEGER

Nombre de usuario en un registro.


select ora_login_user from dual;

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 OUT ora_name_list_t)

BINARY_INTEGER

Retorna la lista de permisos que estn siendo 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 ora_name_list_t)

BINARY_INTEGER

Retorna las revocaciones de un evento REVOKE 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 binary_integer)

VARCHAR2

Dada una posicin (1 para el tope de la pila), 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 (position in binary_integer)

BINARY_INTEGER

Dada una posicin (1 para el tope de la pila), 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 binary_integer, param in binary_integer)

VARCHAR2

Dada una posicin (1 para el tope de la pila) y un nmero de parmetro, retorna la coincidencia "%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 ora_name_list_t)

BINARY_INTEGER

Retorna el texto SQL del comando dentro del 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); 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; Retorna TRUE si el error es relativo a una

ora_with_grant_option

BOOLEAN

space_error_info (error_number OUT NUMBER, error_type OUT VARCHAR2, object_owner OUT VARCHAR2, table_space_name OUT VARCHAR2, object_name OUT VARCHAR2, sub_object_name OUT VARCHAR2)

BOOLEAN

condicin fuera-de-espacio, y rellena los parmetros de salida con informacin acerca del objeto que caus el error.
if (space_error_info(eno, typ, owner, ts, obj, subobj) = TRUE) then 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 eventos del sistema igualmente separados por OR. La siguiente tabla describe los diversos disparadores de sistema.
Evento
STARTUP SHUTDOWN LOGON LOGOFF SERVERERROR CREATE DROP ALTER TRUNCATE GRANT REVOKE DLL

OR

y la lista de

Momento
AFTER BEFORE AFTER BEFORE AFTER BEFORE|AFTER BEFORE|AFTER BEFORE|AFTER BEFORE|AFTER BEFORE|AFTER BEFORE|AFTER BEFORE|AFTER

Se disparan: Despus de arrancar la instancia. Antes de apagar la instancia. Despus de que el usuario se conecte a la base de datos. Antes de la desconexin de un usuario. Cuando ocurre un error en el servidor. Antes o despus de crear un objeto en el esquema. Antes o despus de borrar un objeto en el esquema. Antes o despus de cambiar un objeto en el esquema. Antes o despus de ejecutar un comando TRUNCATE. Antes o despus de ejecutar un comando GRANT. Antes o despus de ejecutar un comando REVOKE. 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); SELECT NombreAutor, Titulo FROM AUTOR_LIBRO

Podemos seleccionar valores de esta vista. Consideremos los siguientes registros:

Oracle /129

WHERE NombreAutor = 'Emilio Salgari'; NombreAutor ------------------------Emilio Salgari Emilio Salgari UPDATE AUTOR_LIBRO SET NombreAutor = 'Emil Salgari' WHERE NombreAutor = 'Emilio Salgari'; Titulo --------------------------Sandokn El Corsario Negro

Si intentamos actualizar el valor del nombre del autor, la actualizacin fallar:

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. triggers INSTEAD OF son muy potentes. Como

Los 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: La sintaxis para desactivar todos los triggers sobre una tabla es:
ALTER TABLE nombre_de_tabla DISABLE ALL TRIGGERS; ALTER TRIGGER nombre_del_trigger ENABLE; ALTER TRIGGER nombre_del_trigger DISABLE;

La sintaxis para volver a activar un trigger es:

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, ...]); nombreRecord Nombre_del_tipo;

Y para declarar una variable del tipo de registro personalizado: 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: 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; 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; nombreRecord.nombreVariable1 := valor;

Puede asignarse un registro a otro cuando sean del mismo tipo:

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

Lo cual significa que el registro

alum1 tendr la siguiente apellidos VARCHAR2(50), localidad VARCHAR2(50) ).

Alum1Alumno%ROWTYPE; BEGIN Alumn1.nif := '2222222B'; END;

estructura: ( nif VARCHAR2(9), nombre VARCHAR2(100),

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: Si 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; que fijarse que, en la declaracin de la variable valores, debemos TYPE nombreTabla IS TABLE OF tipoDato [INDEX BY tipoIndice]; TYPE nombreTabla IS TABLE OF tipoRegistro [INDEX BY tipoIndice]; definimos la coleccin sin la clusula INDEX BY deberemos inicializar

Hay inicializar 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:

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,

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;

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 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 ;

tipo RECORD. En

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: 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 %ROWTYPE. En este caso debemos sustituir el tipo RECORD por un tipo OBJECT. TYPE nombreTipo IS VARRAY (tamaoMaximo) OF tipoElementos;

los atributos

%TYPE

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: 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 CREATE [OR REPLACE] TYPE nombre_tipo AS VARRAY (tamao_maximo) OF tipo_elementos;

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; CLOSE c1; -- se procesa la coleccin 'v_apellidos' END;

-- Lee como mximo 10 registros

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; DECLARE TYPE T_Alumnos IS TABLE OF Alumno%ROWTYPE; v_alumnos T_Alumnos; BEGIN

Tambin podemos aplicarlo en una instruccin de borrado para acumular los datos de los registros borrados:

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: Y ahora creamos el tipo del array:
CREATE TYPE OAlumno AS OBJECT (nif VARCHAR2(9), nombre VARCHAR2(60)); 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 SELECT * FROM TABLE( OBTEN_ALUMNOS() );

de la siguiente forma:

Un resultado posible de esta consulta puede ser el siguiente:


NIF ----------------11111111A 22222222B NOMBRE -------------------------Juan Marian

A veces puede ser necesario forzar el tipo devuelto por la funcin en lnea: 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; SELECT * FROM TABLE (VARR_Ordinales(3, 4, 7)); COLUMN_VALUE --------------------3 4 7 SELECT * FROM TABLE( CAST (OBTEN_ALUMNOS() AS TARR_Alumnos );

Y ejecutamos la siguiente consulta: El resultado ser el siguiente:

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: Y ahora ya podemos crear la funcin:

CREATE OR REPLACE TYPE Tabla_Alumnos AS TABLE OF Reg_Alumno;

Al 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: 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; SELECT * FROM TABLE ( fn_AlumnosDeLocalidad('Madrid') );

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; usar la palabra clave PIPELINED en la cabecera se mejoran los tiempos de respuesta

8.6. Instruccin FORALL. La instruccin FORALL permite realizar una serie de comandos normalmente ms rpidamente que el bucle FOR equivalente. Este comando admite varias sintaxis:

INSERT, UPDATE,

DELETE

de forma masiva

La 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

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; clusula opcional SAVE EXCEPTIONS provoca que si falla una de las operaciones no se produzca

asignados en una coleccin:

cuyos id's estn

DECLARE TYPE T_Lista_ids IS VARRAY(5) OF INTEGER;

-- El tipo de una coleccin para 5 elementos enteros

Oracle /137

Las 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 exis tir. 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

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; siguientes restricciones se aplican al comando FORALL:

cero si son distintos.

ellos. Retornan cero si son iguales y no

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.

abierto y 1 si lo est.

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 DBMS_LOB.FILEISOPEN (file_loc INBFILE) RETURN INTEGER;

El procedimiento FILEOPEN abre un archivo en un modo de apertura.

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 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,

DBMS_LOB.FILEOPEN (file_loc IN OUT BFILE,open_mode IN BINARY_INTEGER := file_readonly);

el

Oracle /139

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

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);

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. 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; CREATE OR REPLACE DIRECTORY DirImagenes AS 'C:\Oracle\Blob\Imagenes';

Lo siguiente que vamos a necesitar es una tabla con un campo 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) ;

BLOB

para almacenar la imagen. En este caso

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: 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 contenido actual. Ntese el uso de la clusula FOR UPDATE en la consulta que recupera la SELECT * FROM Documento WHERE DBMS_LOB.SUBSTR(Contenido, 4000, 1) LIKE '%loquesea%';

texto al principio del referencia 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 declarar un nuevo tipo del cursor generado con SQL dinmico.
DECLARE TYPE CURSOR_DINAMICO IS REF CURSOR; c_cursor CURSOR_DINAMICO; fila Alumno%ROWTYPE; v_queryVARCHAR2(255); BEGIN v_query := 'SELECT * FROM Alumno'; OPEN c_cursor FOR v_query; LOOP FETCH c_cursor INTO fila; EXIT WHEN c_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE(fila.nif); END LOOP; CLOSE c_cursor; END; -- Se crea un tipo de cursor dinmico -- Se declara una variable del nuevo tipo

REF CURSOR

para

-- Se abre el cursor dinmico

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: Un ejemplo sencillo sera el siguiente:
GRANT EXECUTE ON DBMS_SQL TO usuario; 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: Tambin podemos usar variables host del siguiente modo:
DBMS_SQL.PARSE(ID, 'GRANT CREATE ANY TABLE TO ' || USER ); 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: 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; OrdenarPor('nombre; DROP TABLE OtraTabla;');

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.

Un

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

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED FuentesJava AS public class OracleJavaClass { public static String saluda(String nombre) { return ("Hola desde Java " + nombre); } }; mismo objeto JAVA SOURCE puede contener varias clases 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); } };

de Java.

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]' ; 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';

El

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
byte, short, int, long, float, double Char, String java.sql.Date java.sql.ResultSet

Tipos de Oracle
Number Char, Varchar2, Nchar, Nvarchar2 Date Ref Cursor

La siguiente tabla muestra la correspondencia de conversin de los tipos Oracle a tipos Java:
Tipos de Oracle
Number Char, Varchar2, Nchar, Nvarchar2 Date Blob Clob VARRAY o TABLE Tipo de objeto de Oracle

Tipos de Java
java.math.BigDecimal String oracle.sql.TIMESTAMP oracle.sql.BLOB oracle.sql.CLOB oracle.sql.ARRAY 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; DECLARE mc MI_PAQUETE.Mi_Cursor; BEGIN OPEN mc FOR 'SELECT ''Ejemplo de cursor'' AS texto FROM DUAL'; MI_PAQUETE.Procesa_Consulta(mc);

Ahora podemos invocar el procedimiento, por ejemplo desde el siguiente bloque:

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; } }; CREATE OR REPLACE FUNCTION NombreCompleto(c Cliente_t) RETURN NVARCHAR2 AS LANGUAGE JAVA NAME "MiClase.nombreCompleto(oracle.sql.STRUCT) return java.lang.String";

La funcin de Oracle que mapear la funcin de Java es:

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: 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. 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: El 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; public void setAutoBuffering(boolean enable) public boolean getAutoBuffering() mtodo setAutoBuffering(boolean) habilita o STRUCT struct = new STRUCT(structdesc, conexion, atributos); StructDescriptor structdesc = StructDescriptor.createDescriptor(nombre_tipo_sql, conexion);

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

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;

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(); }

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: 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) dbms_java.revoke_permission('MIESQUEMA', 'SYS:java.io.FilePermission', 'miarchivo.txt', 'write' );

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:

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.

CALL dbms_java.set_preference('SCOTT', 'U', '/my/package/method/three', 'windowsize', '22:32');

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 m isma 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 com partido 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: Podemos usar esta configuracin para buscar y descargar parches desde la interfaz de OEM.
http://oracle.com/support/metalink/index.html

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: Y para parar el servicio: Podemos comprobar su estado mediante: Para comenzar todos los componentes del servidor de aplicaciones, incluyendo el Management Service: Para parar todos los componentes: 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: Podemos parar un agente mediante:
emctl stop agent emctl start agent opmnctl stopall. opmnctl startall emctl status oms emctl stop oms emctl start oms

Y podemos comprobar su estado mediante: 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: 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
http://nombre_del_host_mgmtserver.dominio:puerto/em emctl status agent

en la cual el repositorio es almacenado. Nota. No hay que asignar valor para RESOURCE_MANAGER_PLAN.
Parmetro
job_queue_processes db_block_size remote_login_passwordfile timed_statistics open_cursors shared_pool_size dispatchers aq_tm_processes compatible

Valor mnimo
10 8192 EXCLUSIVE TRUE 300 67108864 NULL o no presente en 1 o mayor 9.0.1.3 o ms grande

el fichero

La siguiente tabla lista parmetros adicionales recomendados para el Oracle Management Repository.
Parmetro
db_cache_size session_cached_cursors large_pool_size processes fast_start_mttr_target hash_area_size sort_area_size pga_aggregate_target undo_management undo_retention undo_tablespace

Valor
134217728 200 0 150 300 1048576 1048576 33554432 AUTO 10800 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
ACTIVE_INSTANCE_COUNT

Descripcin 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. Especifica uno o ms nombres de ficheros de control, separados CONTROL_FILES por comas. Especifica (en bytes) el tamao de los bloques de base de datos de DB_BLOCK_SIZE Oracle. Especifica la localizacin lgica de la base de datos dentro de la DB_DOMAIN 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. Especifica el nmero mximo de ficheros de base de datos que DB_FILES 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. Especifica el identificador de la base de datos de hasta 8 caracteres. DB_NAME Este parmetro debe ser especificado y debe corresponder al nombre especificado en el comando CREATE DATABASE. Especifica la localizacin por defecto del rea de recuperacin DB_RECOVERY_FILE_DEST 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. Especifica (en bytes) el lmite del espacio total usado por los DB_RECOVERY_FILE_DEST_SIZE ficheros de recuperacin de base de datos creados en el rea de recuperacin instantnea. Especifica un nombre nico global para la base de datos. Cada DB_UNIQUE_NAME 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. Nombres del fichero de parmetro de servidor en uso. Este SPFILE 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. Valor booleano que controla el trazado de Oracle. Cuando se TRACE_ENABLED asigna a TRUE, Oracle registra informacin en ficheros de registro cuando ocurren errores. Oracle registra esta informacin para todas las instancias. Especifica qu modo de gestin de espacio de deshacer debera UNDO_MANAGEMENT usar el sistema. Cuando se asigna a AUTO, la instancia comienza en modo automtico.

Oracle /162

Nota. La asignacin para cero.

DML_LOCKS

debe ser idntica para todas las instancias slo si se asignar a

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 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. Si se especifica, este parmetro deber tener valores nicos sobre todas las instancias. THREAD El parmetro especifica el nmero de hilos de deshacer que sern usados por una instancia. Especifica el tablespace de deshacer que ser usado cuando una instancia arranca. Si UNDO_TABLESPACE este parmetro se especifica cuando la instancia est en un modo manual de administracin de deshacer, entonces ocurrir un error y el arranque fallar.
INSTANCE_NUMBER

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. Se asigna este parmetro para habilitar una configuracin de servidor DISPATCHERS 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: 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
SRVCTL START INSTANCE -d <db_name> -i <inst_name_list> [-o <start_options>] [-c <connect_str> | -q]

especifica, le dice a SRVCTL que solicite al usuario informacin de conexin cuando 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: 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 inicio (-o), como en el siguiente ejemplo: SRVCTL START ASM -n MYNODE1 -i ASM1 o OPEN SRVCTL START database d MYDB o OPEN

SRVCTL

se ejecute; por

nodo ( -n), el nombre de instancia (-i), y la opcin de

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
srvctl add {database | instance | service | nodeapps | asm}

srvctl config {database | service | nodeapps|asm} srvctl disable {database | instance | service|asm} srvctl enable {database | instance | service|asm} srvctl getenv {database | instance | service | nodeapps} srvctl modify {database | instance | service | nodeapps} srvctl relocate service srvctl remove {database | instance | service | nodeapps | asm} srvctl setenv {database | instance | service | nodeapps} srvctl start {database | instance | service | nodeapps | asm} srvctl status {database | instance | service | nodeapps | asm} srvctl stop {database | instance | service | nodeapps | asm} srvctl unsetenv {database | instance | service | nodeapps}

Descripcin Aade una configuracin a nuestra configuracin del clster de 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. Muestra la informacin de configuracin almacenada en el Registro de Clster de Oracle. Desactiva el objeto indicado y evita que sea iniciado automticamente. Activa el objeto indicado para ser iniciado automticamente. Muestra el estado de entorno. Modifica la configuracin del objeto indicado sin quitar y aadir los recursos CRS. Traslada los nombres de servicio desde una instancia a otra. Elimina el objeto indicado del entorno del clster. Asigna valores de entorno en el fichero de configuracin. Inicia el CRS habilitado, aplicaciones no ejecutndose en la base de datos, todas o las instancia indicadas, todos o los servicios indicados, o aplicaciones del nivel de nodo. Muestra el estado actual del objeto indicado. Para las aplicaciones CRS para la base de datos, todas o las instancias indicadas, todos o los servicios indicados, o aplicaciones del nivel de nodo. Desasigna los valores de entorno en el fichero de configuracin.

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: Si el 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
listeners_db.us.acme.com= (address=(protocol=tcp)(host=db1-server)(port=1521)) (address=(protocol=tcp)(host=db2-server)(port=1521)) usuario ha cambiado variables del entorno dentro de la sesin (mediante ALTER SESSION), o ha asignado

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
-export -import -restore -backuploc

-showbackup

-upgrade -downgrade -help

Propsito Para exportar el contenido del OCR dentro del fichero destino. Para importar el contenido OCR desde un fichero exportado previamente. Para restaurar el OCR desde un fichero de respaldo OCR creado automticamente. 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. Para mostrar la localizacin, tiempo y nombre del nodo de origen para los tres ltimos ficheros de respaldo creados automticamente. Para actualizar el OCR a su ltima versin. Para des actualizar el OCR a su versin ms temprana. 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: 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: La 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: 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 frec uencia 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 ALTER USER Pedro IDENTIFIED BY otracontrasea; DROP USER usuario [CASCADE]; clusula CASCADE permite borrar CREATE USER Pedro IDENTIFIED BY profesor;

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: Tambin podemos bloquear manualmente una cuenta mediante la clusula ALTER USER.
ALTER USER Juana ACCOUNT LOCK; ALTER USER Juana ACCOUNT UNLOCK; ACCOUNT LOCK

del comando

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: 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. ALTER PROFILE PERFIL_LIMITADOR LIMIT PASSWORD_LIFE_TIME 30;

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; usuario Juana intenta ahora reutilizar una contrasea ALTER USER Juana IDENTIFIED BY contrasea1;

Si el ella cambia su contrasea, como en la siguiente lnea: Y ella la cambia otra vez:
ALTER USER Juana IDENTIFIED BY contrasea2; ALTER USER Juana IDENTIFIED BY contrasea1; ERROR en lnea 1: ORA-28007: la contrasea no puede ser reutilizada

reciente no podr. Por ejemplo, supongamos que

Durante su siguiente cambio de contrasea, ella intenta reutilizar una contrasea reciente, y su intento falla:

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
SESSIONES_PER_USER CPU_PER_SESSION CONNECT_TIME

Descripcin El nmero de sesiones concurrentes que un usuario puede tener en una instancia. El tiempo de CPU, en centenas de segundos, que una sesin puede utilizar. 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. El nmero de bloques de datos que se pueden leer en una operacin. LOGICAL_READS_PER_CALL La cantidad de espacio privado que una sesin puede reservar en la zona PRIVATE_SGA de SQL compartido de la SGA. El nmero de total de recursos por sesin, en unidades de servicio. Esto COMPOSITE_LIMIT 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: 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: 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; la forma de conectarse como OPS$ALU10 CONNECT ops$alu10/01ula CONNECT / SHOW PARAMETER OS_AUTHENT_PREFIX;

As,

desde una cuenta del SO diferente es:

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: 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' CREATE USER ops$alu10 IDENTIFIED EXTERNALLY;

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: La (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. 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 CREATE USER appschema INDENTIFIED GLOBALLY AS ''; CREATE USER scott CREATE USER scott IDENTIFIED GLOBALLY AS 'CN=scott,OU=division1,O=oracle,C=US'; cadena proporcionada en la clusula AS proporciona un identificador

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 abiert a 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: Anlogamente, para conectarnos con permisos SYOPER, podemos usar: 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 CONNECT SYS/contrasea AS SYSOPER CONNECT SYS/contrasea AS SYSDBA

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

tener ese privilegio en

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 DELETE_CATALOG_ROLE, EXECUTE_CATALOG_ROLE, SELECT_CATALOG_ROLE EXP_FULL_DATABASE, IMP_FULL_DATABASE AQ_USER_ROLE, AQ_ADMINISTRATOR_ROLE SNMPAGENT RECOVERY_CATALOG_OWNER SCHEDULER_ADMIN CONNECT, RESOURCE

Se proporcionan para compatibilidad con versiones previas de Oracle. Se proporcionan estos roles para acceder a las vistas y paquetes del diccionario de datos. Se proporcionan para usar las utilidades Import y Export. Estos roles son necesarios para Oracle Advanced Queuing. Este rol es usado por el Enterprise Manager Intelligent Agent. Se requiere este rol para la creacin de un catlogo de recuperacin propietario de esquema. Este rol permite la ejecucin de los procedimientos del paquete DBMS_SCHEDULER. Debera restringirse slo a los DBA's.

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: 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): Permiso para usuario de modificacin de datos (permiso sobre objeto): Permiso de solo lectura sobre una tabla para todos:
GRANT SELECT ON una_tabla TO PUBLIC; GRANT SELECT, INSERT, UPDATE, DELETE ON una_tabla TO un_usuario; GRANT CREATE SESSION TO un_usuario; GRANT [privilegios_de_sistema | roles] TO [usuarios | roles | PUBLIC] [WITH ADMIN OPTION];

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]; SELECT * FROM SYSTEM_PRIVILEGE_MAP;

Podemos obtener la lista de permisos del sistema con el comando siguiente:


GRANT CREATE ANY TABLE, DROP ANY TABLE TO Empleado;

Por ejemplo, si deseamos dar permisos de creacin y borrado de tablas al usuario

Empleado

podemos usar:

Los permisos de sistema son auditables. Permisos sobre objetos (object privileges): Los permisos sobre objetos ms importantes son: SELECT, UPDATE, INSERT, EXECUTE, INDEX, y REFERENCES. Se pueden usar las siguientes sintaxis para conceder permisos sobre objetos:

DELETE, ALTER, DEBUG,

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, se creen despus de ejecutar el comando GRANT.

incluso sobre los que

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: 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; REVOKE [privilegios_de_sistema | roles] FROM [usuarios | roles |PUBLIC];

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 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];

Bob

algunas

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: 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: Una vez conectado, Dora selecciona los datos de una tabla a la cual Bob tiene permisos de acceso. Se
SELECT * FROM Dora.Ventas; crea una vista llamada VENTAS, la cual simplemente selecciona CREATE VIEW VENTAS AS SELECT * FROM Dora.Ventas; CONNECT Bob/contrasea GRANT SELECT ON Ventas TO Bob;

los datos de la tabla 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 sobre la tabla Ventas: GRANT SELECT, UPDATE ON ALGUNAS_VENTAS TO Bob;

esta vista, y revoca todos los permisos de

Bob

Oracle /175

Y si

Se produce un error:

/ REVOKE ALL ON Ventas FROM Bob; ahora Dora se reconecta con la cuenta CONNECT Bob/contrasea / SELECT * FROM VENTAS;

de Bob para probar los cambios:

ERROR en lnea 1: ORA-04063: vista "BOB.VENTAS" tiene errores Intentar hacer una seleccin sobre la vista VENTAS falla porque para su defincin acceso a la tabla subyacente Dora.Ventas, para la cual el usuario Bob ya no tiene embargo, un intento de seleccionar la vista Dora.ALGUNAS_VENTAS: SELECT * FROM Dora.ALGUNAS_VENTAS;

se necesitan permisos de permisos de acceso. Sin

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: Y se actualiza un registro:
CREATE VIEW ALGUNAS_VENTAS_CORTO AS SELECT * FROM Dora.ALGUNAS_VENTAS; UPDATE ALGUNAS_VENTAS_CORTO SET Cantidad = 88 WHERE IdVenta = 3; Cuando la vista ALGUNAS_VENTAS_CORTO es consultada, se muestran los efectos de la consulta sobre Dora.ALGUNAS_VENTAS debera mostrar los mismos resultados, ya que

realiz sobre la tabla subyacente.

actualizacin. Una la actualizacin se

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 SELECT: GRANT SELECT ON Dora.ALGUNAS_VENTAS TO Judy;

intenta pasar un permiso que s tiene, como

Se produce un error:

l no puede ceder este permiso tampoco, porque la vista

ERROR en lnea 1: ORA-01031: permisos insuficientes

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: Pero el resultado es tambin un error:
GRANT SELECT ON ALGUNAS_VENTAS_CORTO TO Judy; 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:

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 }];

ERROR en lnea 1: ORA-00942: la tabla o vista no existe

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

Concediendo un rol a otro rol. Los roles pueden ser concedidos a otros roles. Podemos hacer esto a travs del comando muestra a continuacin:
GRANT Empleado TO Administrador;

GRANT CREATE SESSION TO Empleado; GRANT CREATE SESSION, CREATE VIEW TO Administrador;

GRANT,

tal como se

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

Administrador

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 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;

SESSION

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: 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: 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 ALTER ROLE Administrador IDENTIFIED EXTERNALLY; ALTER ROLE Administrador IDENTIFIED BY contrasea;

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: 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 como se muestra a continuacin:
ALTER ROLE Administrador NOT IDENTIFIED; ora_local_manager_d:NONE:1:dora,judy

ROL,

tal

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: Para habilitar un rol que no sea por defecto, se usa el comando continuacin:
SET ROLE Empleado; ALTER USER Bob DEFAULT ROLE Empleado; SET ROLE,

tal como se muestra a

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. Si un rol tiene asociada una contrasea, sta debe ser especificada mediante la clusula IDENTIFIED BY:
SET ROLE Administrador IDENTIFIED BY contrasea; SET ROLE ALL; SET ROLE ALL EXCEPT Empleado;

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: Con ya 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: 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
DROP ROLE Administrador; REVOKE SELECT ON Ventas FROM Empleado; este comando, los usuarios del rol Empleado

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: 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; propietario de la tabla Ventas puede crear esta SELECT NombreCliente, Producto, Precio FROM Ventas;

El vista 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: 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; GRANT SELECT ON Mis_Ventas TO PUBLIC;

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. 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.
ALTER USER Bob QUOTA 100M ON USERS;

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:

La 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: 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; DBMS_SESSION.SET_CONTEXT('Dora','USER_ID', v_id);

SELECT Cuenta INTO v_id FROM STOCK_CUENTA WHERE NombreCuenta = v_user; tabla STOCK_CUENTA contiene una registro por cada usuario ( Ana, Bob, y dems).

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; USUARIO -------------ANA NMERO CUENTA ----------------------1234

El resultado de esta consulta debera ser el siguiente:

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

Ya el permiso de ejecutarlo, y se crea un sinnimo pblico.

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; que este paquete ser ejecutado por todos los usuario que tengan acceso a la tabla STOCK_TRX, se GRANT EXECUTE ON Dora.SECURITY_PACKAGE TO PUBLIC; / CREATE PUBLIC SYNONYM SECURITY_PACKAGE FOR Dora.SECURITY_PACKAGE;

concede

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'); SYS.DBMS_RLS.DROP_POLICY('Dora', 'STOCK_TRX', 'STOCK_TRX_SELECT_POLICY');

De forma similar, podemos eliminar la poltica 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
ADD_POLICY DROP_POLICY REFRESH_POLICY ENABLE_POLICY CREATE_POLICY_GROUP ADD_GROUPED_POLICY ADD_POLICY_CONTEXT DELETE_POLICY_GROUP DROP_GROUPED_POLICY DROP_POLICY_CONTEXT ENABLE_GROUPED_POLICY DISABLE_GROUPED_POLICY

Propsito Aade una poltica a una tabla, vista o sinnimo. Elimina una poltica de una tabla, vista o sinnimo. Invalidad los cursores asociados con polticas no estticas. Habilita (o deshabilita) una poltica previamente aadida a una tabla, vista o sinnimo. Crea una poltica de grupo. Aade una poltica al grupo de polticas especificado. Aade el contexto para la aplicacin activa. Elimina un grupo de polticas. Elimina una poltica que es miembro del grupo especificado. Elimina el contexto de la aplicacin. Habilita una poltica dentro de un grupo. 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

podemos crear un STOCK_TRX_SELECT_POLICY al grupo:

ejemplo,

grupo

llamado

TRXAUDIT,

entonces aadir

la poltica

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.

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;

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: 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.
DBMS_SESSION.SET_CONTEXT('Dora','SETUP', policy_group);

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: 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; CREATE TABLESPACE Users_3 CREATE TABLESPACE nombre_tablespace DATAFILE nombre_datafile tamao_fichero ;

Podemos especificar tambin ms de un fichero de datos en la creacin del tablespace. Por ejemplo:

Oracle /191

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 -------------------------SYSTEM UNDOTBS1 SYSAUX TEMP USERS CONTENTS -----------------PERMANENT UNDO PERMANENT TEMPORARY PERMANENT

DATAFILE '/U01/ORADATA/Users_3_01.dbf' SIZE 100M, '/U01/ORADATA/Users_3_02.dbf' SIZE 250M;

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 ----------------------------USERS TEMPORARY_TABLESPACE --------------------------------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 -------------------------USERS BYTES ----------131072 MAX_BYTES ----------------1 BLOCKS ----------16 MAX_BLOCKS ------------------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 --------------------------SYSTEM UNDOTBS1 SYSAUX TEMP USERS EXTENT_MAN --------------------LOCAL LOCAL LOCAL LOCAL 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 pueden modificar para ser de solo lectura: O pueden ser modificados para ser de solo escritura:
ALTER TABLESPACE USERS READ ONLY; ALTER TABLESPACE USERS READ WRITE;

ALTER TABLESPACE.

Los tablespaces se

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: 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); ALTER TABLESPACE USER_1 FLASHBACK OFF;

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: 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 ALTER TABLESPACE AGG_DATA READ ONLY; ALTER TABLESPACE AGG_INDEXES READ ONLY;

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 lecturaescritura 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) Titulo POSITION(05:100)

INTEGER EXTERNAL, CHAR "LTRIM(RTRIM(:Titulo))",

Oracle /197

"LTRIM(RTRIM(:Autor))", "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

Autor POSITION(101:120) Categoria POSITION(121:140)

CHAR CHAR

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
Userid Control Log Bad Discard Discardmax Skip

Descripcin Nombre de usuario y contrasea para la carga, separados con una barra. Nombre del fichero de control. Nombre del fichero de log. Nombre del fichero "malo". Nombre del fichero de descartes. Nmero mximo de filas a descartar antes de parar de cargar. El valor por defecto es permitir todos los descartes. 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 Errors Rows

Nmero de filas lgicas a cargar. El valor por defecto es todas. Nmero de errores permitidos. El valor por defecto es 50. 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. Tamao de cadenas de rutas enlazadas, en bytes. El valor por defecto depende del Bindsize sistema operativo. Suprime mensajes durante la carga. Silent Direct Usa carga Direct Path. El valor por defecto es FALSE. Nombre del fichero de parmetros que contiene especificaciones de parmetros de Parfile carga adicionales. Parallel Activa la carga en paralelo. El valor por defecto es FALSE. Fichero para asignar extensiones desde (para carga paralela). File Permite cargas dentro de tablas que tienen ndices en estados no usables. El valor Skip_Unusable_Indexes 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. Tamao del bfer de lectura; el valor por defecto es de 1MB. Readsize 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. Nmero de filas para cadenas de columnas Direct Path; el valor por defecto es de Columnarrayrows 5.000. Tamao en bytes del bfer del canal Direct Path; por defecto es de 256000. Streamsize Un indicador de que debera usarse multiproceso durante Direct Path. Multithreading
Oracle /199

Resumable Resumable_name Resumable_timeout

Un indicador TRUE/FALSE para habilitar o deshabilitar operaciones recuperables en la sesin actual; el valor por defecto es FALSE. Identificador de texto para la operacin recuperable. 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: 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 sqlldr empleado/contrasea control=libros.ctl log=libros.log

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: 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 una columna llamada Fecha y los datos estn en el formato Mon-DD-YYYY WHEN Categoria='ADULTO'

fila, podemos especificar la carga de este campo de la siguiente manera:


Oracle /201

de formato. Por ejemplo, si tenemos en las primeras once posiciones de la

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: 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: 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. 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" Columna_secuencial SEQUENCE(100,2) Columna_secuencial SEQUENCE(MAX,1) FechaInsercion SYSDATE

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: 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
-- Limitar la carga a empleados de LA: WHEN Ubicacion='LA'

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 posibl e, 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 u sar 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 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
DIRECT=TRUE

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 Empleado:
DTPUMP

y concede accesos

READ

WRITE

al esquema

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
ATTACH

Descripcin 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. Especifica el directorio destino para el fichero de log y el fichero de volcado DIRECTORY asignado. Especifica el nombre y directorio para ficheros de volcado (dump). DUMPFILE Determina el mtodo usado para estimar el tamao del fichero de volcado ESTIMATE (BLOCKS o STATISTICS). ESTIMATE_ONLY Valor Y/N usado para instruir a Data Pump sobre si los datos deberan ser exportados o estimados. Especifica el criterio para excluir objetos y datos que sern exportados. EXCLUDE Especifica el tamao mximo de fichero para cada fichero de volcado FILESIZE exportado. SCN de la base de datos para flashback durante la exportacin. FLASHBACK_SCN Fecha de la base de datos para flashback durante la exportacin. FLASHBACK_TIME Le dice a Data Pump que exporte todos los datos y metadatos en un modo de FULL exportacin "Full". Muestra una lista de comandos y opciones disponibles. HELP Especifica el criterio por el cual los objetos y datos sern exportados. INCLUDE Especifica el nombre de la tarea; el valor por defecto es generado por el JOB_NAME sistema. Nombre y directorio opcional para el fichero de log de exportacin. LOGFILE Especifica el enlace de base de datos origen para la tarea de Data Pump NETWORK_LINK Export a una base de datos remota. NOLOGFILE Valor Y/N usado para suprimir la creacin del fichero de log. Asigna el nmero de trabajadores para la tarea de Data Pump Export. PARALLEL Nombres del fichero de parmetros que se usa, si hay alguno. PARFILE Filtras registros desde las tablas durante la exportacin. QUERY Nombres de los esquemas a ser exportados por el modo de exportacin SCHEMAS "Schema". Muestra detalles del estado de la tarea Data Pump. STATUS Lista las tablas y particiones que sern exportadas para el modo de exportacin TABLES "Table". Lista los tablespaces a ser exportados. TABLESPACES Especifica si el tablespace que es exportado debera primero ser verificado TRANSPORT_FULL_CHECK como un conjunto autnomo. TRANSPORT_TABLESPACES Especifica un modo de exportacin "Transportable Tablespace". Especifica la versin de los objetos de base de datos a ser creados, y as el VERSION 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 Aade un fichero de volcado. ADD_FILE CONTINUE_CLIENT Finaliza el modo interactivo y entra en el modo de logging. Finaliza la sesin cliente, pero conserva ejecutndose la tarea de servidor Data Pump EXIT_CLIENT Export. Muestra ayudas en lnea para la importacin. HELP Mata la tarea actual y desenlaza las sesiones cliente relacionadas. KILL_JOB Modifica el nmero de trabajadores para la tarea Data Pump Export. PARALLEL Reinicia la tarea asociada. START_JOB Muestra detalles de estado de la tarea Data Pump. STATUS Para la tarea para reiniciarla ms tarde. STOP_JOB

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: 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 EXPDP empleado/contrasea PARFILE=dp1.par

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: 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 DUMPFILE=directorio1:file1.dmp, directorio2:file2.dmp

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: Presionando CTRL-C salimos de la pantalla de registro, y Data Pump retornar al indicador Export: Se finaliza la operacin a travs del comando EXIT_CLIENT: Podemos entonces reiniciar el cliente y asociarnos a la tarea que se est ejecutando actualmente bajo nuestro esquema:
EXPDP empleado/contrasea ATTACH Export> EXIT_CLIENT Export> EXPDP empleado/contrasea PARFILE=dp1.par

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: Podemos parar una tarea mediante la opcin 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: 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
Export> START_JOB Export> STOP_JOB Export> CONTINUE_CLIENT

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 EXCLUDE debera ser como sigue.
EXCLUDE=SCHEMA:"='Empleado'" Empleado

de una exportacin completa, el formato para la opcin

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: 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%\'\" EXCLUDE=TABLE:"LIKE 'TEMP%'"

Nota. Podemos especificar ms de una opcin Export.

EXCLUDE

dentro de la misma tarea de Data Pump

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: 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: 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
QUERY = [ esquema . ] [ nombre_tabla : ] clusula INCLUDE=TABLE:"IN ('LIBROS','AUTORES')" INCLUDE=PROCEDURE

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: 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 Asocia el cliente a una sesin del servidor y sita el modo interactivo. ATTACH CONTENT Filtros que son importados: ALL, DATA_ONLY o METADATA_ONLY. Especifica la ubicacin del fichero de volcado asignado al directorio destino DIRECTORY para los ficheros de log y SQL. Especifica los nombres y, opcionalmente, los directorios para el fichero de DUMPFILE volcado asignado. Determina el mtodo usado para estimar el tamao del fichero de volcado ESTIMATE (BLOCKS o STATISTICS). Excluye objetos y datos que estn siendo importados. EXCLUDE SCN de la base de datos para "flash back" durante la importacin. FLASHBACK_SCN Timestamp de la base de datos para "flash back" durante la importacin. FLASHBACK_TIME FULL Valor Y/N usado para especificar si queremos importar el fichero de volcado completo. Muestra ayudas en lnea para la importacin. HELP Especifica el criterio para los objetos que sern importados. INCLUDE Especifica un nombre para la tarea; el valor por defecto es asignado por el JOB_NAME sistema. Nombre y nombre opcional del directorio para el fichero de log. LOGFILE Especifica el enlace de base de datos origen para una tarea Data Pump de NETWORK_LINK importacin a una base de datos remota. NOLOGFILE Valor Y/N usando para suprimir la creacin del fichero de log. Asigna el nmero de trabajadores para la tarea de Data Pump Import. PARALLEL Nombre del fichero de parmetros, si se usa. PARFILE Filtros de registros para tablas durante la importacin. QUERY Cambia el nombre del fichero de datos fuente para el fichero de datos REMAP_DATAFILE destino en los comandos CREATE LIBRARY, CREATE TABLESPACE y CREATE DIRECTORY durante la importacin. Importa datos exportados desde el esquema fuente dentro del esquema REMAP_SCHEMA destino. Importa datos exportados desde el tablespace fuente dentro del tablespace REMAP_TABLESPACE destino. Especifica si ficheros de datos existentes deberan reutilizarse por el REUSE_DATAFILES comando CREATE TABLESPACE durante el modo de importacin "Full". Nombre del esquema a ser importado en el modo de importacin "Schema". SCHEMAS 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". Nombre del fichero en el cual el DDL para la importacin ser escrito. Los SQLFILE datos y metadatos no sern cargados dentro de la base de datos destino. Muestra detalles del estado de la tarea Data Pump. STATUS STREAMS_CONFIGURATION Valor Y/N usado para especificar si se debe importar la informacin de
Oracle /210
QUERY=LIBROS:'"WHERE IdLibro > 2"'

TABLE_EXISTS_ACTION

TABLES TABLESPACES TRANSFORM TRANSPORT_DATAFILES TRANSPORT_FULL_CHECK TRANSPORT_TABLESPACES VERSION

configuracin de streams. 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. Lista de tablas para el modo de importacin "Table". Lista de tablespaces para el modo de importacin "Tablespace". Dirige cambios a los atributos de segmento o al almacenaje durante la importacin. Lista los ficheros de datos a ser importados durante el modo de importacin "Transportable Tablespace". Especifica si los tablespaces que son importados deben primero verificarse como autnomos. Lista los tablespaces que sern importados durante el modo de importacin "Transportable Tablespace". 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
CONTINUE_CLIENT EXIT_CLIENT HELP KILL_JOB PARALLEL START_JOB STATUS STOP_JOB

Descripcin Finaliza el modo interactivo y entra en modo de registro. La tarea ser reiniciada si est parada. Finaliza la sesin de cliente, pero contina ejecutndose la tarea de servidor Data Pump Import. Muestra ayuda en lnea para la importacin. Mata la tarea actual y desasocia las sesiones cliente relacionadas. Modifica el nmero de trabajadores para la tarea Data Pump Import. Reinicia la tarea asociada. Muestra detalles de estado para la tarea Data Pump. 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: 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; REMAP_SCHEMA= esquema_fuente : esquema_destino

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. Presionando las teclas CTRL-C regresamos a la pantalla de registro, y Data Pump regresar al indicador Import:
Import> IMPDP system/contrasea PARFILE=dp1.par

Podemos salir del sistema mediante el comando EXIT_CLIENT: Podemos entonces reiniciar el cliente y asociarnos a la tarea que se ejecute actualmente bajo nuestro esquema:
IMPDP system/contrasea ATTACH Import> EXIT_CLIENT

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: Podemos parar una tarea mediante la opcin STOP_JOB: Mientras la tarea est parada, podemos incrementar su paralelismo mediante la opcin podemos reiniciar la tarea:
Import> START_JOB Import> STOP_JOB PARALLEL. Import> CONTINUE_CLIENT

Y despus

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:

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: Para eliminar los tablespaces exportados y clusulas de almacenamiento de todas las tablas e ndices, se usa lo siguiente:
TRANSFORM=SEGMENT_ATTRIBUTES:n TRANSFORM=STORAGE:n:tabla

TRANSFORM = nombre_transformacin : valor [ : tipo_objeto ]

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 Ntese que la opcin CONTENT no est especificada. La salida ser escrita en el directorio dtpump.
DIRECTORY=dtpump DUMPFILE=metadataonly.dmp SQLFILE=sql.txt SQLFILE.

Podemos entonces ejecutar la importacin para poblar el fichero sql.txt: En 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 IMPDP Empleado/contrasea PARFILE=dp1.par el fichero sql.txt que crea la importacin, podemos

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 CP /

CHAR(20), 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 DATOS LOCAL

Enlace de base de datos

BASE DE DATOS REMOTA

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' ; no se especifica PUBLIC el enlace es por defecto privado.

Si

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

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

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) ) )';

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: Como ejemplo, para tablas remotas usaremos el nombre de enlace CONEXIN_REMOTA. En la clusula referenciaremos el nombre de la tabla seguido de @CONEXION_REMOTA:
SELECT * FROM Libro@CONEXION_REMOTA; SELECT * FROM Libro; FROM

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 Libro@CONEXION_REMOTA Enlace de base de datos

SELECT * FROM Libro

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. 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: 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: 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 CREATE VIEW Local_Libro_View AS SELECT * FROM Libro@CONEXION_REMOTA WHERE Titulo >'M'; CREATE SYNONYM Libro_Syn FOR Empleado.Libro@CONEXION_REMOTA; CREATE SYNONYM Libro_Syn FOR Libro@CONEXION_REMOTA;

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: 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; SELECT * FROM Empledo.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. 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 CREATE PUBLIC SYNONYM Libro FOR Libro@CONEXION_REMOTA;

para la tabla Libro remota. Segundo, podemos incluir el nombre del propietario remoto cuando creamos el sinnimo local, tal como se muestra a continuacin: 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 pseudocolumna 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. 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
CREATE VIEW Mis_Libros AS SELECT * FROM Libro WHERE SUBSTR(Nombre, 1, INSTR(Nombre,'') - 1) = USER; CREATE PUBLIC SYNONYM Libro FOR Empleado.Libro@CONEXION_REMOTA;

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';

ALTER TABLE Libro ADD (Region VARCHAR2(10));

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 SUR) debera slo ser capar de ver los registros cuya regin sea 'SUR'.

registra remotamente como el usuario

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: En 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; CREATE OR REPLACE VIEW Sur_Libros AS SELECT * FROM Libro@CONEXION_REMOTA WHERE Region = 'SUR'; este caso, la restriccin sobre Region est todava vigente, pero es administrada

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}

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

nombre_tabla USING subconsulta;

Nota. Excepto para la ltima lnea, cada lnea del comando porque es un comando de SQL*Plus. Hay varias opciones dentro del comando COPY:
Opcin

COPY

debe terminar con un guin

Explicacin Inserta los registros dentro de la tabla destino. Automticamente crea la tabla si no existe previamente. Crea la tabla y entonces inserta los registros. CREATE 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.
APPEND

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: 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: Este comando nos registrar directamente en la base de datos registro se muestra en la siguiente figura.
SQLPLUS usuario/contrasea@HQ HQ. SQLPLUS usuario/contrasea

La configuracin host para este tipo de

Oracle /221

Oracle Database + Oracle Net Base de datos HQ Herramientas Oracle + Oracle Net SQLPULS usuario/contrasea@HQ SQL>

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: En 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
CREATE TABLE Local_Libros AS SELECT * FROM Libros@REMOTE_CONNECT; este ejemplo, se crea una tabla llamada Local_Libros

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 } ] | ON PREBUILT TABLE [ {WITH | WITHOUT} REDUCED PRECISION ] ] [ USING INDEX [ { clusulas atributos fsicos | clusula tablespace } [ clusula atributos fsicos | clusula tablespace ] | USING NO INDEX ] [ clusula refresco ] [ FOR UPDATE ] [{DISABLE | ENABLE} QUERY REWRITE] AS subconsulta; comando CREATE MATERIALIZED VIEW tiene cuatro secciones

Parmetros de almacenamiento

Opciones de refresco consulta

El en la cual se indica el nombre de la vista materializada:

mayores. La primera seccin es la cabecera,

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: 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
[ FOR UPDATE ] [{DISABLE | ENABLE} QUERY REWRITE] AS subconsulta ; especificamos FOR UPDATE, la vista ser actualizable; si

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; Vista materializada creada.

Oracle responde con

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 generadas por QUICK_TUNE pueden verse a travs de la vista 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.
USER_ADVISOR_ACTIONS,

recomendaciones

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 mediante GET_TASK_SCRIPT, al cual se pasa el nombre de la tarea), el directorio de salida,

fichero que ser creado.

script (generado y el nombre del

El 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:

EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT('MV_TUNE'), 'SCRIPTS', 'MV_TUNE.sql'); fichero MV_TUNE.sql creado por el procedimiento CREATE_FILE contendr comandos similares

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 ----------------------------------------STATEMENT_ID MVOWNER MVNAME CAPABILITY_NAME POSSIBLE RELATED_TEXT RELATED_NUM MSGNO MSGTXT SEQ Null? -------Type ---------------VARCHAR2(30) VARCHAR2(30) VARCHAR2(30) VARCHAR2(30) CHAR(1) VARCHAR2(2000) NUMBER NUMBER(38) VARCHAR2(2000) 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), MVOWNER VARCHAR(30), MVNAME VARCHAR(30), CAPABILITY_NAME VARCHAR(30), -- Client-supplied unique statement identifier -- NULL for SELECT based EXPLAIN_MVIEW -- NULL for SELECT based EXPLAIN_MVIEW -- 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

Una determinar nuestras opciones.

-- 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. vez ejecutado el procedimiento EXPLAIN_MVIEW podemos consultar MV_CAPABILITIES_TABLE

para

Para

SELECT Capability_Name, Msgtxt FROM MV_CAPABILITIES_TABLE WHERE Msgtxt IS NOT NULL; la vista materializada LOCAL_LIBRO

la consulta retornar:
MSGTXT --------------------------------------------------------------------------relation is not a partitioned table the detail table does not have a materialized view log see the reason why REFRESH_FAST_AFTER_INSERT is disabled see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled PCT is not possible on any of the detail tables in the materialized view query rewrite is disabled on the materialized view query rewrite is disabled on the materialized view query rewrite is disabled on the materialized view general rewrite is not possible or PCT is not possible on any of the detail tables relation is not a partitioned table

CAPABILITY_NAME ---------------------------------------------PCT_TABLE REFRESH_FAST_AFTER_INSERT REFRESH_FAST_AFTER_ONETAB_DML REFRESH_FAST_AFTER_ANY_DML REFRESH_FAST_PCT REWRITE_FULL_TEXT_MATCH REWRITE_PARTIAL_TEXT_MATCH REWRITE_GENERAL REWRITE_PCT PCT_TABLE_REWRITE

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 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 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
NEXT NEXT_DAY(TRUNC(SysDate), 'DOMINGO')+12/24 NEXT SysDate+7

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: 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] ; comando CREATE MATERIALIZED VIEW LOG se ejecuta en la base de datos de la tabla origen, EXECUTE DBMS_MVIEW.REFRESH_ALL_MVIEWS;

El 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; clusula WITH SEQUENCE es necesaria para soportar

La 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; tipo de ndice CTXCAT soporta

El 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;

Dentro de las llamadas a la funcin, el operador precedente puede ser leda de la siguiente manera:

REM Mtodo CATSEARCH para ndices CTXCAT: SELECT Titulo FROM TROZO_LIBRO_CTXCAT WHERE CATSEARCH(Trozo, 'India', NULL) > 0;

>

es denominado un operador de umbral. La consulta

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 ;

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

TITULO -----------------------------La montaa de luz

SCORE(10) -------------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 fila slo si el texto revisado incluye ambas palabra "India" y "elefante".

que la funcin

CONTAINS

retornar un

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 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; operador ACCUM proporciona otro mtodo para combinar

Oracle Text es la barra

El 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;

La 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

SELECT Titulo FROM TROZO_LIBRO_CONTEXT WHERE CONTAINS(Trozo, 'India , elefante') > 0; sintaxis ACCUM es soportada por la funcin CATSEARCH

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;

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; 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;

SELECT Titulo FROM TROZO_LIBRO_CTXCAT WHERE CATSEARCH(Trozo, 'Indica NOT elefante', NULL) > 0;

La

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;

La

REM mtodo CATSEARCH para ndices CTXCAT: SELECT TITLE FROM TROZO_LIBRO_CTXCAT WHERE CATSEARCH(REVIEW_TEXT, '"muy calurosa tarde"', NULL) > 0; siguiente consulta busca la frase "transactions and finances". La palabra "and" 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;

es encerrada entre llaves.

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 (_ _ _).

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;

SELECT Titulo FROM TROZO_LIBRO_CONTEXT WHERE CONTAINS(Trozo, 'escalo___') > 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; embargo, s contiene la palabra "elefante", que

Sin es 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; opciones principales de bsqueda para CONTAINS

Las

se resumen en la siguiente tabla.

Operador Descripcin Devuelve un registro si uno u otro trmino de bsqueda exceden el umbral. OR | Equivalente a OR. Devuelve un registro si ambos trminos de bsqueda exceden el umbral. AND & Equivalente a AND. Devuelve un registro si la suma de las puntuaciones de los trminos de bsqueda exceden el ACCUM umbral Devuelve un registro si la puntuacin de la primera bsqueda menos la puntuacin de la segunda MINUS bsqueda exceden el umbral. Equivalente a MINUS. Asigna diferentes pesos a la puntuacin de bsqueda. * La puntuacin se basar en cmo de cerca los trminos de bsqueda estn uno junto al otro en el NEAR 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. | Devuelve un registro si cada trmino de bsqueda es encontrado. AND 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. Equivalente al guin. NOT 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 estas actividades de mantenimiento.

EXECUTE

sobre el paquete

CTX_DDL

al usuario para soportar

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: Aqu hay un ejemplo:
[[METADATA] SYNC (MANUAL | EVERY "intervalo" | ON COMMIT)] 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: 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 de ndices en la clusula PARAMETERS: CREATE INDEX Trozo_CtxCat_Indice ON TROZO_LIBRO_CTXCAT(Trozo) INDEXTYPE IS CTXSYS.CTXCAT PARAMETERS ('INDEX SET Trozos'); EXECUTE CTX_DDL.CREATE_INDEX_SET('Trozos');

como tipo de ndice, y el conjunto

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 Empleado:
LIBRO_DIR

y concede accesos

READ

WRITE

al esquema

El 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

CREATE DIRECTORY LIBRO_DIR AS 'e:\oracle\external'; GRANT READ ON DIRECTORY LIBRO_DIR TO Empleado; GRANT WRITE ON DIRECTORY LIBRO_DIR TO Empleado; usuario Empleado puede ahora leer ficheros del directorio e:\oracle\external

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: Tambin los ficheros mismos deber ser legibles por el usuario de Oracle al nivel del sistema operativo.
Oracle /244
GRANT READ ON DIRECTORY LIBRO_DIR TO otroUsuario;

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') ); Tabla creada.

Oracle responder con:

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: Podemos combinar la tabla "interna" AUTOR con su contrapartida externa, AUTOR_EXT, para verificar que no hay registros perdidos o aadidos:
SELECT * SELECT Titulo FROM LIBRO; SELECT Titulo FROM LIBRO_EXT;

Oracle /245

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 ----------------------------------------TABLE_NAME TYPE_OWNER TYPE_NAME DEFAULT_DIRECTORY_OWNER DEFAULT_DIRECTORY_NAME REJECT_LIMIT ACCESS_TYPE ACCESS_PARAMETERS PROPERTY Null? -------NOT NULL NOT NULL NOT NULL Type -------------------VARCHAR2(30) CHAR(3) VARCHAR2(30) CHAR(3) VARCHAR2(30) VARCHAR2(40) VARCHAR2(7) VARCHAR2(4000) VARCHAR2(10)

FROM AUTOR A WHERE NOT EXISTS (SELECT 'X' FROM AUTOR_EXT AE WHERE A.Nombre = AE.Nombre);

Por ejemplo, la tabla consulta:

AUTOR_EXT

usa

LIBRO_DIR

como directorio por defecto como mostrara la siguiente

SELECT DEFAULT_DIRECTORY_NAME, ACCESS_PARAMETERS FROM USER_EXTERNAL_TABLES WHERE TABLE_NAME = 'AUTOR_EXT'; DEFAULT_DIRECTORY_NAME -----------------------------------LIBRO_DIR ACCESS_PARAMETERS --------------------------------------------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 ------------------LIBRO_EXT AUTOR_EXT LOCATION --------------------------libro_dump.lst autor_dump.lst DIR -----SYS SYS DIRECTORY_NAME -----------------------LIBRO_DIR 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: 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 ( [TYPE tipo_dispositivo_acceso ] propiedades_datos_externos ) [REJECT LIMIT { entero | UNLIMITED }]

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

Podemos ahora verificar el nmero de filas de la tabla:

LOCATION ('libro_dump_2.lst') ) REJECT LIMIT 1 ;

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

) LOCATION ('libro_dump_2.lst') ) REJECT LIMIT 1 ; LIBRO_EXT_3 accede al mismo fichero 'ADULTO'.

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) )

que

LIBRO_EXT_2,

pero slo mostrar los registros de categora

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 ; orden de los ficheros es importante; SKIP 2 se aplica

El 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 externas con el comando ANALYZE.
DBMS_STATS.

No podemos analizar tablas

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 -------------------------Joe descalzo Evangelio Algo tan fuerte La hija de Galileo Longitud Una vez quitado EDITOR -------------------Mariner Picador Pandoras Penguin Penguin Sancturay Pub CATEGORIA ---------------Adulto-fic Adulto-fic Adulto-nf Adulto-nf Adulto-nf 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: 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 DELETE FROM PEDIDO_LIBRO; COMMIT;

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 sobre el paquete DBMS_FLASHBACK.

EXECUTE

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 asociado con cada registro:

ORA_ROWSCN

introducida en Oracle Database 10g para ver el SCN

SELECT Titulo, ORA_ROWSCN FROM PEDIDO_LIBRO; TITULO -------------------------Joe descalzo Evangelio Algo tan fuerte La hija de Galileo Longitud Una vez quitado ORA_ROWSCN -----------------553531 553531 553531 553531 553531 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 -------------------------Joe descalzo Evangelio Algo tan fuerte La hija de Galileo Longitud Una vez quitado Innumeracy ORA_ROWSCN -----------------553531 553531 553531 553531 553531 553531 553853 SCN_TO_TIMESTAMP

A qu hora se hace el mapeado SCN? Podemos usar la funcin de fecha en la cual se hizo el cambio:
SELECT SCN_TO_TIMESTAMP(555853) FROM DUAL;

para mostrar la

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: Ahora repoblaremos la tabla PEDIDO_LIBRO:
SELECT SYSTIMESTAMP FROM DUAL; INSERT INTO PEDIDO_LIBRO SELECT * FROM PEDIDO_LIBRO_OLD; SELECT SYSTIMESTAMP FROM DUAL; DELETE FROM PEDIDO_LIBRO;

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 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. El identificador de la transaccin que cre la versin de la fila. VERSIONS_XID VERSIONS_OPERATION La operacin que realiz la transaccin (I para INSERT, U para UPDATE, D para DELETE).
VERSIONS_STARTSCN

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 -------------------------Una vez quitado Longitud La hija de Galileo Algo tan fuerte Evangelio Joe descalzo Joe descalzo Evangelio Algo tan fuerte La hija de Galileo Longitud Una vez quitado ORA_ROWSCN -----------------568127 568127 568127 568127 568127 568127

V ---U U U U U U

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 -----------------NombreAutor Comentarios Null? -------NOT NULL Type ---------------------------VARCHAR2(50) 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; ORIGINAL_NAME ---------------------AUTOR OPERATION --------------DROP TYPE --------TABLE TS_NAME ------------USERS OBJECT_NAME --------------------------RB$$48448$TABLE$0 CREATETIME ------------------------2004-02-23:16:10:58

Oracle /258

RB$$48449$INDEX$0

SYS_C004828 DROPSCN -------------720519 720516

DROP

INDEX

USERS CAN ------YES NO CAN -----YES YES

2004-02-23:16:10:58 RELATED ------------48448 48448

SELECT DropTime, DropScn, Partition_Name, Can_Undrop, Can_Purge, Related FROM RECYCLEBIN; DROPTIME ------------------------2004-02-25:14:30:23 2004-02-25:14:30:23 PARTITION_NAME ------------------------

SELECT Base_Object, Purge_Object, Space FROM RECYCLEBIN; BASE_OBJECT -----------------48448 48448 RECYCLEBIN PURGE_OBJECT ---------------------48448 48449 SPACE ---------8 8

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: La tabla es restaurada, junto con sus filas, ndices y estadsticas. La sintaxis completa de este comando es la siguiente:
FLASHBACK TABLE AUTOR TO BEFORE DROP;

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 recupera.

RENAME

del comando

FLASHBACK TABLE

para renombrar la tabla cuando se

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 embargo, la clusula WHERE no es especificada; todos los registros sern actualizados.
UPDATE AUTOR SET COMMENTS = 'Ilustrador de libros para nios'; COMMIT; Clement Hurd.

Sin

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: Entonces podemos recuperar la tabla:
ALTER TABLE AUTOR ENABLE ROW MOVEMENT; 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 ARCHIVELOG antes de ejecutar el comando ALTER DATABASE FLASHBACK ON.

ALTER DATABASE

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 ----------------------------------------OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TIME RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE SELECT * FROM V$FLASHBACK_DATABASE_LOG; OLDEST_FL --------------722689 OLDEST_FL --------------25-FEB-04 RETENTION_TARGET --------------------------1440 FLASHBACK_SIZE ----------------------8192000 ESTIMATED_FL --------------------Null? -------Type -----------NUMBER DATE NUMBER NUMBER NUMBER

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 --------------------723649 FLASHBACK_ON ---------------------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: Para desactivar la opcin de flashback de la base de datos hay que ejecutar el comando FLASHBACK OFF cuando la base de datos est montada pero no abierta:
STARTUP MOUNT EXCLUSIVE; ALTER DATABASE FLASHBACK OFF; ALTER DATABASE OPEN; ALTER DATABASE OPEN RESETLOGS; ALTER DATABASE

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

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 con la siguiente sintaxis: Por ejemplo, supongamos el tipo Telefono_TA y el tipo Telefono_Lista_TA:
ALTER TYPE nombre_del_tipo ADD ATTRIBUTE (nombre_del_atributo tipo_de_dato) CASCADE;

/ -- 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 );

ALTER TYPE,

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) ); George no es propietario del tipo abstracto Persona, Warning: Tipo creado con errores de compilacin.

Si siguiente mensaje:

Oracle responder a este comando

CREATE TYPE

con el

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. SHOW ERRORS Errores para el tipo CLIENTE: LINE/COL ERROR

Para ver los errores asociados con la creacin del tipo de dato podemos usar el comando SHOW ERRORS:

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 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.

le conceda el permiso

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 ------------------CLIENTE_ID CLIENTE Null? -------Type ----------------NUMBER 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 ------------------CLIENTE_ID CLIENTE IDENTIDAD DIRECCION SET DESCRIBE DEPTH 3 DESC CLIENTES Name ------------------CLIENTE_ID CLIENTE IDENTIDAD NOMBRE TELEFONO DIRECCION

Null? --------

Type ----------------NUMBER CLIENTE_TA PERSONA VARCHAR(100)

Null? --------

Type ----------------NUMBER CLIENTE_TA PERSONA VARCHAR2(30) VARCHAR2(20) 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: 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.
ALTER TYPE Persona ADD MEMBER FUNCTION ObtenNombreTelefono RETURN VARCHAR2 CASCADE;

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

Tambin se pueden crear mtodos estticos que acten como constructores:

); / 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');

nombre VARCHAR2(20), telefono VARCHAR2(30), CONSTRUCTOR FUNCTION Cliente_t(id NUMBER, nombre VARCHAR2) RETURN SELF AS RESULT

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;

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');

Oracle /268

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

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.

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

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;

CREATE TABLE TRJefeEmpleado ( jefe Persona, empleado Persona);

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'; la primera instruccin, la tabla TRPersona

En 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 los objetos de la tabla TRCompra.

travs de

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'; SELECT VALUE(T) FROM TRCompra T WHERE T.comprador = Persona('Juan', '555');

O bien:

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: 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
UPDATE TRCompra SET comprador = NULL WHERE comprador IS DANGLING;

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: Para
INSERT INTO TRCompra (id, comprador, detalles) SELECT 1, REF(tr), NULL FROM TRPersona tr WHERE nombre='Jos Prez'; 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 LineaDetalle

de 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 media nte 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: Un resultado posible ser:
Id --1 2 SELECT T.id, T.detalles FROM TRCompra T; detalles ----------------------------------------------------------------------Tabla_detalles (LineaDetalle('P1',4,3.5), LineaDetalle('P2',12,0.4)) 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: El resultado ser:
SELECT * FROM TABLE( SELECT T.detalles FROM TRCompra T WHERE T.id=1); Producto Cantidad ---------- ---------P1 4 P2 12 PrecioUnitario -------3.5 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

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';

INSERT INTO THE (SELECT T.detalles FROM TRCompra T WHERE id = 45) VALUES (LineaDetalle('Nuevo producto', 3, 5.2));

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: La la primera lnea de detalle de la compra de cdigo 45:
SELECT T.id, T.comprador.nombre, CURSOR(SELECT * FROM TABLE(T.detalles) D WHERE D.cantidad>5) FROM TRCompra T; clusula THE tambin sirve para seleccionar las tuplas de una tabla anidada. Por ejemplo, para seleccionar 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 ); funcin CARDINALITY retorna el nmero de elementos dentro de una tabla anidada o array variable: SELECT CARDINALITY(Animales) FROM GRANJA; funcin MULTISET EXCEPT toma dos tablas anidadas como entrada y retorna el conjunto de registros 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; funcin MULTISET INTERSECT toma dos tablas anidadas como entrada 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; funcin MULTISET UNION toma dos tablas anidadas como entrada DECLARE A1 ANIMALES_TA := ANIMALES_TA ('PERRO', 'GATO'); A2 ANIMALES_TA := ANIMALES_TA('GALLINA', 'PERRO'); A3 ANIMALES_TA; BEGIN

La