DESARROLLO DE APLICACIONES EN LENGUAJES DE 4º GENERACIÓN INDICE DE LA ASIGNATURA • Introducción a los sistemas gráficos de bases de datos • Organización de sistema gestor de bases de datos • Lenguaje SQL: Definición, control y manipulación de datos • Utilización de plantillas y menús • Utilización de generadores de funciones de impresión • Programación en PL/SQL • Designer 2000. CRITERIOS DE EVALUACIÓN Las tres primeras unidades se hará un examen individual Las dos siguientes unidades (4−5) se irá preparando un proyecto y se irá evaluando Al final habrá que evaluar un proyecto conjunto. 26/10/99 SISTEMA GESTOR DE BASE DE DATOS DEFINICIÓN: Es un conjunto de procedimientos (lenguaje) que controlan una base de datos. HISTORIA: Antes se usaban ficheros tradicionales en la gestión de datos y en cada área se creaba una gestión de base de datos diferente. Pero esto creaba el problema de tener datos duplicados en diferentes gestores de bases de datos. En esta fase los datos estaban intrínsecamente unidos a los programas que los gestionaban, puesto que esos datos sólo podían ser leídos con los procesos que había creado el analista. Por eso se llamaban sistemas orientados a procesos. Se derrochaba la memoria y el proceso, ya que al repetirse los datos, a la hora de modificar alguno de ellos había que modificarlo en todos los ficheros en los que aparecía dicho dato. Este sistema tenía una gran falta de flexibilidad frente a los cambios. <dibujo en el cuaderno> Una base de datos tiene que permitir: • Evitar la duplicidad de los datos salvo en el caso de que se quiera tener una seguridad en caso de estropearse la unidad principal • Una descripción de los datos y las relaciones entre ellos se almacenen en la base de datos. • Ahorro de memoria y proceso. • Centralizar la información en un solo tipo de fichero, es decir, normalizar la información. • Relacionar los ficheros de datos. • Mejorar las disponibilidad y la seguridad de los datos. INCONVENIENTES DE UTILIZAR UN SISTEMA GESTOR DE BASE DE DATOS • Se incrementan los costes 1 Mas CPU Mas memoria Mas licencias • Se necesita personal especializado en el uso de las bases de datos. • La implantación del proyecto es larga y dura (como mi...) • Rentabilidad a medio plazo. • Ausencia real de normas. DEFINICION: • Es un conjunto, colección o depósito de datos • Las interrelaciones de los datos están almacenados con los datos. • No se permite la redundancia lógica. Si está permitida la redundancia física. • Han de atender a múltiples usuarios y aplicaciones • Independencia de los datos frente a las aplicaciones. • Definición, descripción e incluso documentación (metadatos) relativa a los datos están almacenadas con los datos. Colección o depósito de datos integrada, con redundancias controladas y con una estructura que refleja las interrelaciones existentes en el mundo real; los datos que han de estar compartidos por diferentes usuarios y aplicaciones deben mantenerse independientes de ésta y su definición, descripción, única para cada tipo de datos, han de estar almacenadas con los mismos. Los procedimientos de actualización, recuperación habrán de ser capaces de respetar la integridad, seguridad y confidencialidad del conjunto de datos Dentro de una base de datos podemos distinguir tres niveles diferentes de abstracción. • Estructura lógica (esquema externo) (Vistas) • Estructura lógica global (Esquema) • Estructura física (Esquema interno): como están almacenados todos los datos físicamente. ¿Qué es un sistema gestor de base de datos? Es un conjunto de programas, procedimientos y lenguajes que permiten o suministran a los usuarios los medios necesarios para escribir, recuperar y manipular los datos almacenados; manteniendo su integridad, confidencialidad y seguridad. Existen funciones de tres tipos diferentes: • Definición y Descripción de datos • Funciones de manipulación de datos • Funciones de utilización (Se engloban dentro de 2 grupos) • Rutinas y software de acceso: Nos permiten acceder a los datos de la base de datos desde el programa • Funciones que permiten al administrador de la base de datos administrarla, como por ejemplo: • Copias de seguridad • Carga masiva de datos • Reorganización de objetos • Obtener estadisticas de utilización 2 ARQUITECTURA DE UN SISTEMA GESTOR DE BASE DE DATOS La arquitectura de las bases de datos están regidas por las instituciones Ansi,X3 y Sparc. Tenemos que tener una arquitectura a 3 niveles: • Nivel interno • Nivel conceptual: Todos los datos de la base de datos • Nevel externo: lo que percive el usuario. También tendremos que tener unos lenguajes para el sistema gestor de base de datos. Habrá de diferentes tipos: • Huésped: Son lenguajes que precisan de otro, que se llama anfitrión, para comunicarse con la base de datos, como por ejemplo el SQL • Autocontenido: Funciona de manera autonoma para comunicarse con la base de datos. El SQL también es un ejemplo de este tipo de lenguaje. • Procedimentales / No procedimentales: Los procedimentales son aquellos en los que hay que bajar mucho el nivel de detelle de las instrucciones para lograr el objetivo que queremos y los no procedimentales son todo lo contrario. • Diferido (BACH)/conversacionales: (SQL interactivo) • Lenguajes navegacionales Todos estos lenguajes han de permitirnos las siguientes cosas: • Lenguajes de definición y descripción de datos: Permiten hacer definiciones de estructuras de registros y relaciones entre ellos. Tienen que cumplir las siguientes caracteristicas: 27/10/99 *Ejercicio: Buscar en access todos aquellos paralelismos con las especificaciones de lenguajes DML y DDL. DIFERENTES ESTRUCTURAS DE LAS BASES DE DATOS Tenemos varios tipos dependiendo del enfoque: • Enfoque relacional • Enfoque jerarquico • Enfoque en red En el enfoque relacional los datos aparecen con una visión uniforme en forma de tablas. Ejemplos de bases de datos relacionales son: informix, oracle, db2, adabas, sybase, ... En el enfoque jerárquico los datos tienen un esquema en forma de árbol. Sus características son: El enfoque red viene de un desarrollo de la idea del jerárquico, en el cual puede haber un hijo que tenga varios padres. Tienen peor rendimiento que los de enfoque jerárquico, pero tienen una mayor flexibilidad. TIPOS DE ALMACENES DE DATOS: 3 El nacimiento de las Bases de datos llevo a que los datos de definición de las bases de datas van a estar incluidos en las propias bases de datos. • Diccionario de datos: Reúne la información sobre los datos almacenados en la base de datos como descripción, significados, estructuras, consideraciones de seguridad,... todo lo que los usuarios necesitan para entender el significado de los datos (metadatos) • Directorio de datos: toda aquella información que permite al sistema gestor de bases de datos acceder físicamente a los datos. • Catalogo de datos: Es un directorio de datos más restringido, con bajo contenido semantico, pero sus datos estan dispuestos en modo de tablas, y que pueden consultarse con las mismas herramientas de los lenguajes de manipulación de datos. EJERCICIO: Hacer un diseño de un modelo relacional que permita la gestión de prestamos de los libros de una biblioteca. Partimos de un fichero: • Fichas donde se recogen las características del libro: Titulo, Autor, Editorial, Año, Nº de ejemplares. • Fichas relativas a los prestamos con los datos: Nombre del prestatario, fecha del préstamo, fecha de devolución El bibliotecario quería además: • Desearía tener en las fichas el idioma en el que está escrito el libro. • Quiere reflejar el tema y el subtema de los que trata el libro. • De los autores, además del nombre, se quiere saber, la nacionalidad y la institución en la que trabaja. • Quiere establecer tres tipos de prestatarios: alumnos, que solo se lo pueden prestar un fin de semana; alumnos en proyecto de fin de carrera, se les puede dejar hasta dos libros una semana; profesores y otras bibliotecas, hasta un año. <Resolución en el cuaderno> 1.SOPORTE FÍSICO DE UNA BASE DE DATOS ORACLE Una base de datos de oracle puede ocupara un numero variable de ficheros. Los ficheros serán soportados en el sistema bajo el que se ejecuta el oracle, pero el sistema gestor de base de datos, la estructura de almacenamiento dentro de los ficheros va a ser independiente del sistema operativo en el que se almacene. 2. ESPACIOS PARA TABLAS Es una agrupación de archivos físicos. Puede ser uno o varios. También se llama Tablespace. Vista de forma lógica, para el oracle, es una sola entidad, a pesar de que esté formado por varios ficheros. Un ejemplo de creación de tabla sería: CREATE TABLE empleado ( nom.empleado char(20), cod.empleado integer ... ) 4 in TABLESPACE users; 2.1 ESPACIO PARA TABLAS (SYSTEM) System contiene tablas que sirven para la gestión interna de la base de datos, como por ejemplo, información de seguridad, descripción de los datos, etc. 2.2 ESPACIO PARA TABLAS (TEMP) Se necesita para poder hacer gestiones temporales. Se podría tener uno o varios, pero por lo menos hay que tener uno 2.3 ESPACIO PARA TABLAS (TOOLS) Este no es imprescindible. Sirve para almacenar tablas de utilidades 2.4 ESPACIO PARA TABLAS (USERS) Sirve para meter datos que no son importantes o que no tienen mucho uso. 2.5 ESPACIO PARA TABLAS (ROLLBACK) Hay que exigir integridad a los datos. En el caso de que haya algún fallo durante la ejecución de los procesos, el oracle lo que hace es guardar la información de los datos que se van a usar antes de ejecutar el proceso, con lo cual cuando el sistema vuelve a funcionar bien el propio oracle se encarga de verificar si realmente se acabo el proceso bien y en caso negativo vuelve a ejecutarlo. Se verifica que el proceso terminó bien con la marca de finalización correcta llamada comit 2.6 ESPACIO PARA TABLAS (DATA E INDEX) El índice (index) contiene una serie de claves de una estructura de registros, y por cada una serie de claves tiene una dirección por la cual se busca en dicha estructura. Hay que tener cuidad de crear los índices necesarios, ya que a la hora de hacer modificaciones en una tabla conlleva el tener que modificar todos sus índices. RECOMENDACIONES • Es muy recomendable usar un espacio de tabla diferente para cada aplicación. • También es bueno usar un tablespace diferente para los datos y para los índices. FICHEROS REDO En el momento que algún programa modifica alguna fila de una tabla el oracle la guarda en memoria, y la modifica. Una vez que se le manda la marca de confirmación Comit, este lo que hace es guardar los cambios en el REDO (archivos de Rehacer). El oracle es totalmente asíncrona a la hora de guardar los datos en la tabla. Simplemente guarda las modificaciones en las tablas de rehacer. En el caso de que se vaya la luz o el sistema se estropea. Se tienen al memos dos porque se puede trabajar en oracle de dos formas. Archive log y no archive. Con el Archive log cuando se llena el Redo 1 se hace un Back Up y llena el redo 2. Si se llenan los dos redos se para el sistema hasta que alguno de los dos se vacía. Con el modo no archive no pide cintas de back up FICHEROS DE CONTROL (CONTROL FILE) 5 Guarda la información de los ficheros de la base de datos, y tendrá un registro por cada fichero que componga la base de datos. En el momento en el que falte algún fichero el oracle no arranca. También hay información de control acerca de ....... por razones de integridad. Hay una opción del oracle que hace que se cargue con dos control file, y los dos ficheros son iguales y guarda la información en ellos por duplicado. Estos estarían en discos diferentes. 29/10/99 PROCESOS DEL ORACLE Se pueden distinguir dos tipos de procesos en el oracle: • Procesos de usuarios (cliente) como por ejemplo SQL, SQLPLUS, SQLFORM... procesos que se arrancan cada vez que un usuario trabaja contra la base de datos. • Procesos de servidor: son procesos que están cargados constantemente en memoria y trabajan con los procesos usuarios para coger sus solicitudes y se comunican con la base de datos. Los diferentes procesos servidor que hay son: • DBWR: Escritor de la base de datos (database writer). Es el que se encarga de hacer las escrituras, las modificaciones y las lecturas en los ficheros de la base de datos. Es el único proceso que puede hacer esto directamente en la base de datos. • LGWR: Escritor de los registros de rehacer (log writer). Es el único proceso que puede leer y escribir en los ficheros redo. Y además, cada vez que se hace un checkpoint en el sistema para grabar la información de la memoria en las tablas graba también una marca de sincronismo. Estos dos procesos anteriores son obligatorios • CKPT: Puerto de comprobación/sincronismo (checkpoint): No es obligatorio. Solamente es útil en aquellas estaciones de trabajo en las que se hacen muchos checkpoint. Se encargaría esta función, opcionalmente, de grabar la información de los puntos de sincronismo, descargando de esta tarea al log writer en sistemas con alta frecuencia de puntos de sincronismo. • SMON: Supervisor del sistema. (System monitor): Este proceso de varias cosas. Por un lado se encarga de hacer todas las recuperaciones que hay que hacer cuando se paró el sistema. Si cuando se arranca el sistema se da cuenta de que el oracle terminó mal la última vez, recupera toda la información y la prepara correctamente. También se encarga de liberar espacio temporal disponible, es decir, que no está siendo utilizado, periódicamente. También se encarga, periódicamente, de compactar los huecos libres en los espacios de datos. Se trata de un proceso obligatorio, y su forma de funcionamiento es estar dormido y de vez en cuando actuar, comprobando todos sus objetivos descritos antes. • PMON: Supervisor de procesos (Program monitor): Es obligatorio y tiene la misma forma de actuar que el Smon. Este se encarga de recuperar un programa de usuario fallido. • ARCM: Archivador (Archiver): Es el que se encarga de hacer las copias de los redo log cuando se llenan y estamos funcionando en el modo archive log. Por lo tanto este fichero será opcional para cuando estemos en modo archive log. • RECO: Recuperador(Recoverer): Se encarga de tener los datos sincronizados cuando estos no están centralizados en una sola base de datos. SGA: AREA GLOBAL DEL SISTEMA (SYSTEM GLOBAL AREA) • CACHE DEL BUFFER DE DATOS: Es una zona de la memoria en la que se van guardando cosas que se van a grabar en el disco. No se graban inmediatamente, sino que se van metiendo en la cache y se grabarán 6 en un momento no definido, es decir, que es una grabación asíncrona. En caso de hacer una cache conviene que no sea pequeña, puesto que si lo es el rendimiento es peor. • BUFFER DE LOS REGISTROS DE REHACER: Igual que los de antes, solo que en vez de con los ficheros de datos, con los ficheros redo. • ZONA COMPARTIDA: Dentro de esta tenemos dos partes: • Cache del diccionario: información de las tablas de datos, como las descripciones, etc. Es un cache específico para almacenar y leer estos diccionarios. Siempre que se pida información sobre los diccionarios de datos primero mirará si esta el esta cache y si no es así lo leerá del disco. • Zona SQL compartida: Para ejecutar una sentencia SQL se necesita: un plan de ejecución, un texto de la sentencia y una lista de objetos referenciados. Para ejecutarla hace varios pasos: • Comprobar si es exactamente igual a otra en el área compartida. • Si los objetos referenciados son los mismos. • Si el usuario que lo está ejecutando tiene permiso para acceder a los datos. PGA: AREA GLOBAL DEL PROGRAMA (PROGRAM GLOBAL AREA) Es la zona donde se guardan los datos relativos a un proceso. Por lo tanto hay siempre una PGA por cada usuario que se conecta a oracle. Se que se arranca una instancia Oracle cuando se esta creando una zona de me memoria que comprende una SGA y unos procesos de servidor. Cada base de datos está asociada a una instancia. ASIGNACIÓN DE ESPACIO ORACLE (Data blocks, Extents y Segmentos) • Data block: Para oracle, un data block es la unidad más pequeña de memoria. Cualquier objeto que ocupe espacio, por lo menos usará un data block. El oracle administra sus archivos de datos (Data files) en Data Blocks, que es la unidad de asignación. Cuando se crea una base de datos en oracle se define que tamaño va a tener el data block y este será siempre el mismo en esa base de datos. Puede ser de 2 kb o de 4 kb. Cuando se quiere recuperar la información de una fila de una tabla va toda la información que hay en el data block con ella. Si una fila está en varios data blocks se recuperarán todos. Contenido de un Data block: Tiene una cabecera al principio con información de control para el oracle. Mantiene una información del directorio de datos que tiene el nombre de las tablas que tienen fila. Guarda también un directorio con las filas que tienen almacenadas. A continuación se guardan los datos propiamente dichos en filas de tablas y a continuación va el espacio libre. Este espacio libre sirve para que en el momento de actualizar un dato y este ocupe más que antes el espacio sirva de colchón para que entre. En el caso de que no entre tendría que meter el dato en otro Data Block. El espacio libre del data block se le asigna con la instrucción pctfree • Extent: Es una espacio contiguo de almacenamiento, es decir, un grupo consecutivo de data blocks. Se reserva con la instrucción extent en el cual se le indica un numero de kb. con los cuales se redondeará hacia arriba con múltiplo del tamaño del data block para que este coincida. • Segmento: Es la agrupación de una o varias extents. No tienen por que estar consecutivas y ni siquiera tienen que estar en el mismo fichero. Con el parámetro next se le indica al oracle de que tamaño es el extent siguiente. Estos extents formarían un segmento de datos. Estos extents se van creando a medida que se van llenando, de forma que se puede definir el tamaño de cada uno que se puede crear. Hay varios tipos de segmentos en una base de datos: • Segmentos de datos • Segmentos de índice • Segmentos de RollBack (agrupan extens del tablespace RollBack) 7 • Segmentos temporales (agrupan extens del tablespace Temp) OBJETOS DE UNA BASE DE DATOS DE ORACLE Una agrupación lógica de objetos que pertenecen a un usuario se denomina esquema de usuario. Por ejemplo, una tabla viene identificada por un nombre de tabla y por un propietario. Con lo cual puede haber dos tablas con el mismo nombre pero de diferente propietario. No todos los objetos ocupan espacio físico, como puede ser una tabla. Un esquema de usuario no esta sujeto a un solo tablespace, sino que se puede tener un esquema repartido en varios tablespace. En un mismo tablespace puede haber objetos de diferentes esquemas de usuario. Con lo cual se deduce que no hay una relación directa entre esquemas de usuario y tablespaces. · TABLAS: Es el objeto de oracle que contiene datos. Se organiza en filas y columnas. Los tipos de datos que van a parar a una columna se corresponden con el tipo de dato que se definió para esa columna. Cuando se crea una tabla se especifican características sobre la ubicación física. Tipos de datos de las columnas: • CHAR: Sirven para almacenar cadenas de caracteres alfanuméricas, de longitud fija, es decir, que hay que especificar una longitud cuando se crea, hasta un máximo de 255 caracteres. Dos cadenas de este tipo, oracle las compara, en el caso de que sean de la misma longitud, carácter a carácter hasta que hay una diferencia y con ella decreta cual es la mayor y la menor. Si son de diferente longitud rellena con blancos la más pequeña. • VARCHAR2: Almacena cadenas de caracteres de longitud variable. Cuando se define una columna de este tipo se declara el nombre de la columna, el tipo y la longitud máxima que puede tener. La longitud máxima que se le puede especificar es de 2000 caracteres. Solo almacena la información representativa, es decir, que al contrario que en el caso anterior, en este no pone blancos hasta que se llena la longitud de caracteres. Por lo tanto su longitud depende del contenido del campo. Este aprovecha mucho mejor el espacio puesto que no guarda espacios en blanco no significativos. • VARCHAR: Es exactamente igual que el tipo anterior. Está reservado para futuros usos, con lo cual puede ocurrir que en futuras versiones de oracle este comando haga otra cosa. Con lo cual no se debe usar. • NUMBER: Sirve para almacenar datos numéricos con una precisión de hasta 38 dígitos significativos. Con esa precisión el numero más grande que se puede archivar es desde 10−130 hasta 9.99999... · 10125. Los negativos son igual pero en negativo. Se puede especificar la precisión y la escala. La precisión es el numero total de dígitos y la escala es el numero de dígitos de la cifra. Ejemplo: para poder archivar numeros del estilo ##.###.###,## sería una precisión de 10 y una escala de 2. Se definiriá de la forma: SALARIO NUMBER(10,2) • LONG: Son campos que permiten guardar datos de hasta 2 gigas de datos. Oracle interpreta, es decir, que si mueve esa información entre dos bases de datos, el es capaz de convertir esa cadena con un juego de caracteres a otro con un juego de caracteres diferentes. Tiene restricciones: solo se puede definir una columna de tipo long por tabla; una columna de tipo long no es indexable; las columnas de tipo long no pueden aparecer en una relación de tipo referencial. 8 • RAW, LONG RAW: Sirve para almacenar tipos de datos binarios, como imágenes o sonidos. El oracle no interpreta dichos datos, sino que tendrá que interpretar los datos un programa externo. La diferencia entre los dos radica en el tamaño: RAW admite un tamaño de 2000 caracteres y LONG RAW admite hasta 2 gigas de longitud • DATE: Sirve para almacenar datos de tipo fecha/hora, como por ejemplo DD/MM/YYYY HH.MM:SS El rango de este tipo de dato es de 1/01/4712 BC hasta 31/12/4712 AC. El formato por defecto es DD−MM−YY. Para cambiarlo habrá que usar funciones de oracle para crear máscaras. Si se introduce la fecha y no la hora, por defecto pone las 12:00:00 AM, y en el caso contrario la fecha por defecto que pone es el primer día del año en curso. El valor nulo En una columna de una tabla de oracle se puede archivar el valor nulo. Esto indica ausencia de valor. No es lo mismo definir una columna numérica que admita nulos con el valor nulo que introducir el valor cero. Por defecto, una columna puede admitir el valor nulo. Cuando en una fila se encuentra en una columna el valor nulo, se archiva la marca del valor nulo, y no se queda vacía. Se recomienda no utilizar nulos el columnas numéricas, porque se puede operar con el valor nulo. Un numero sumado a nulo da de resultado nulo. Hay otra forma de poner valores por defecto si no se sabe el valor. Se puede decir que esa columna tenga un valor por defecto, que entrará en juego cuando no se introduzca ningún valor en esa columna. · VISTAS: Es una versión particularizada de una tabla. En una vista aparecerá la información de una tabla, pero no necesariamente con todas las columnas. Solamente aparecerán las columnas que interesen. Se puede incluir en una sola vista columnas de varias tablas. En esas vistas se podrá eliminar, añadir o modificar filas. En el caso de añadir una fila, al no aparecer todas las columnas, se añadirían valores nulos o por defecto a los campos de las columnas que no aparecen. Este no es un objeto físico. Es un objeto lógico. No ocupa espacio en el disco. Lo que hace es, físicamente, referirse a otros objetos (tablas) para mostrar información. Este concepto de vista apareció para tener más seguridad y confidencialidad en los datos de la base de datos. Confidencialidad por no mostrar todos los datos. También se puede simplificar con él la visión del modelo de datos, para que no parezca demasiado complejo. Otra utilidad de las vistas es la de poner un nombre a las columnas para saber que datos se han de introducir en ellas. · PRIVILEGIOS: En oracle, por defecto, cuando se crea una tabla, nadie tiene acceso a dicha tabla a no ser que el que la crea le de privilegios a otros usuarios. Los privilegios se otorgan con la sentencia grant. Un privilegio es el permiso que se le da a los demás usuarios para que puedan leer los datos de mis tablas, o para modificarlas o insertar datos. Los cuatro privilegios básicos son: Select, Insert, Delete, Update. Se pueden dar de forma separada o todos juntos. Una vez que un usuario tiene privilegios sobre una tabla que no es suya, este usuario puede transferir dicho privilegio a otros usuarios. También se pueden revocar, con la instrucción revoke los derechos a un usuario para que lea los datos de las tablas propias, y si este usuario había dado derechos sobre la tabla a algún otro usuario, este también pierde dichos privilegios. · ROLES: Es un objeto que nos permite administrar los privilegios de una forma ordenada. Es un objeto orientado a la seguridad de los datos. Para no tener que dar privilegios uno a uno a todos los usuarios se crean los objetos 9 rol. Se crea un objeto rol al que se le dan todos los derechos que se quieran dar a un grupo de usuarios y después se van dando privilegios a los usuarios para poder usar dicho rol. Con lo cual, todos los usuarios que tengan privilegios sobre el rol, a su vez tendrán los mismos privilegios que tiene el rol. Si mas tarde se quiere modificar alguno de los privilegios que tiene ese grupo, solo hay que ir a modificar los privilegios del rol. · SINÓNIMOS: Un sinónimo es asignar un alias a una tabla. Esto sirve para que cada vez que te quieras referir a dicha tabla, no tengas que poner el nombre y el propietario de la tabla. Con poner el sinónimo ya se hace referencia a dicha tabla. · ÍNDICES: Sirven para permitir un acceso más rápido a los datos. Es una tabla más reducida, que hace referencia a una columna de una tabla de datos, y que los guarda en un orden ascendente o descendente. Este objeto ocupa espacio físico en la base de datos. Un índice puede estar formado por varias columnas concatenadas, siempre en orden. Una vez que se crea un índice hay que especificar el nombre de la tabla del que va a ser índice. También hay que especificarle las columnas por las que se va a hacer el índice y el orden tanto de los campos como de la indexación. El elemento de un índice no puede ser único, pero solo hace una única referencia a la tabla. RESTRICCIONES DE INTEGRIDAD El oracle nos ofrece varias de estas restricciones: • NOT NULL (relacionado con una columna de la tabla): Esa columna, para cualquier fila que se introduzca en dicha tabla, ha de tener un valor, es decir, que no permite introducir una fila en la tabla sin haber dado un valor a dicha columna. • RESTRICCIÓN DE CLAVE ÚNICA (Unique Key): Esta es una restricción para una columna o para un conjunto de ellas. No puede haber dos filas en una tabla que tengan el mismo valor en dicha o dichas columnas. • RESTRICCIÓN DE CLAVE PRIMARIA (Primary Key): Se asocia a una o varias columnas. Identifica de forma única y unívoca a cada una de las filas de una tabla, con lo cual no puede tener duplicados y no pueden admitir valores nulos. • RESTRICCIÓNES DE INTEGRIDAD REFERENCIAL: Intervienen varios objetos: • Foreign Key (clave ajena): Columna o conjunto de columnas que van a ser referenciadas en otra tabla • Clave referenciada: Es aquella clave única o clave referenciada de la tabla referenciada. • Tabla ajena: Tabla en la que se encuentra la clave ajena • Tabla referenciada: Es la tabla en la que se encuentra la clave referenciada. <tabla en el cuaderno> UPDATA O DELETE RESTRICT: No deja actualizar o borrar una fila de una tabla si de ella dependen otros datos o si se rompe la integridad referencial de la base de datos. DELETE CASCADA: Cuando se borra una fila de una tabla se eliminan también las filas de las tablas que dependen de dicha fila. • RESTRICCIÓN DE TIPO CHECK: Son las restricciones de condición que tienen que cumplir las columnas para poder introducir los datos. 10 SQL Y SQL PLUS Es un lenguaje no procedural, en el cual hay que dar muy pocas instrucciones para manejar la base de datos. El SQL plus es una herramienta que nos permite manejar el SQL. Es útil para manejar informes básicos. El lenguaje SQL maneja funciones de los lenguas de programación DDL y DML, es decir, que puede definir las tablas y tipos de datos y también puede insertar, modificar y borrar datos de las tablas definidas. Dentro de la parte de definición de datos tenemos las siguientes instrucciones: CREATE TABLE CREATE TABLESPACE CREATE INDEX CREATE VIEW DROP TABLE DROP TABLESPACE DROP INDEX DROP VIEW CLAUSULA DE ALMACENAMIENTO Esto habrá que aplicarlo a todos aquellos objetos que ocupan espacio físico a la hora de crearlos. STORAGE (INITIAL NK/NM {en Kb o en Mb}) El parámetro Initial indica el tamaño de la primera extensión en Kb o en Mb El parámetro next indica el tamaño de la siguiente extent también en Kb o en Mb El parámetro pctincrease indica el incremento de las extensiones cada vez que se crea una nueva. El parámetro miniextents indica el numero mínimo de extensiones que queremos que tenga nuestro objeto, con lo cual nos reservará n extens al principio El parámetro maxextents indica el número máximo de extens que queremos en nuestro objeto. CREACIÓN DE UN TABLESPACE Se crea con la orden: CREATE TABLESPACE nombre DATAFILE nombre de fichero SIZE nM REUSE Con el reuse le indicamos que si existe un fichero con ese nombre y del tamaño que le hemos indicado, que lo reuse, es decir, que lo limpie y lo adapte a nuestro uso. Se le puede indicar también AUTOEXTEND ON con el cual irá cogiendo nuevos extents para ese fichero. Si se le indica on después se le puede indicar NEXT nM con 11 lo cual le indicamos el tamaño del siguiente segmento, y después se le puede indicar un MAXSIZE en el cual se le puede indicar UNLIMITED para indicarle que sea ilimitado o un numero de megas determinado. También se le puede indicar en la misma línea DEFAULT STORAGE(cláusulas de almacenamiento) con lo cual, cada objeto que se cree dentro de este tablespace tendrán por defecto las cláusulas de almacenamiento que se indiquen a no ser que se le indiquen otras específicamente. CREACIÓN DE UNA TABLA La sentencia para crear una tabla es como sigue: CREATE TABLE tablename ( columna 1 tipo de dato longitud NOT NULL DEFAULT valor expresion restricciones de integridad) ( columna 2 ( columna 3 8/11/1999 CREACIÓN DE UN ÍNDICE Cuando se quiere crear un único índice, sin que tenga duplicados se especifica escribiendo CREATE UNIQUE INDEX . Para crear el índice se pondrá lo siguiente: CREATE INDEX indice.nombre ON nombre.tabla (columna 1,columna 2,...,columna x) TABLESPACE nombre PCTFREE n STORAGE {clausulas de almacenamiento} INITIAL nK NEXT nK PCTINCREASE n Como en casi todas las definiciones, las últimas definiciones (desde pctfree) tienen ya valores por defecto, que si nos sirven no tenemos porque definirlos. EJEMPLO: Ejemplo de creación de una tabla en SQL de Oracle CREATE TABLE empleados (cod.empleado NUMBER(4), 12 nombre.empleado VARCHAR(2), dir.empleado VARCHAR(2), cod.dep NUMBER(4), salario.empleado NUMBER(8,2) ); • Ejemplo de creación de clave única para la tabla de empleados CONSTRAIN dir.única UNIQUE (nombre.empleado,dir.empleado) Si lo que se quiere es crear una clave única de un solo campo de la tabla se puede especificar a continuación de la definición del dato dir.empleado VARCHAR(40) CONSTRAIN dir.unique UNIQUE USING INDEX ... Al crear la clave única oracle crea inmediatamente un índice al cual le podemos definir sus características a continuación. USING INDEX PCTFREE 20 TABLESPACE empleados ... Todo esto va incluido dentro de los paréntesis de creación de la tabla, como parámetros de esta, y a continuación se pueden seguir definiendo más parámetros de la tabla como los tamaños de extents, etc. • Ejemplo de creación de una clave primaria en la tabla de empleados CONSTRAIN cod.empleado.PK PRIMARY KEY (cod.empleado) • Ejemplo de creación de restricciones NOT NULL Se usará en el ejemplo la tabla de empleados y la siguiente tabla. CREATE TABLE dept ( id.dep NUMBER(4), descrip.dep VARCHAR(20)) La tabla dep será padre de la tabla empleados, con lo cual si se quiere definir la clave ajena será de la forma siguiente, dentro de la definición de la tabla hija: CONSTRAIN dep.dep.fk FOREING KEY (cod.dep) REFERENCES dep(id.dep) Si se quiere que se tenga en cuenta la forma de borrar los registros en cascada habrá que añadir al final de la definición del constrain las palabras: ON DELETE CASCADE. EJERCICIO: Tenemos dos tablespaces, una para datos (DATE) y otro para índices (INDEX). Vamos a crear una tabla de 13 artículos que va a tener las siguientes columnas: • cod_art (numérico), habrá unos 50.000 articulos aprox. • desc_art (alfanumérico) • existencias_art (numérico), el articulo más numeroso tendrá 2.000.000 de unidades. Después tendremos otra tabla llamada pedidos que tendrá los siguientes campos: • cod_ped (numérico), tendremos 10.000.000 de pedidos hasta ahora y crecerá el número de pedidos un 20% cada año. Después del primer año solo podrá tener dos extents. • cod_art • fecha_ped (fecha) • fecha_cierre_ped (fecha) • num_art (numérico) La tabla de de pedidos tendrá una clave única por código de pedidos y codigo de articulos. Habrá una integridad referencial entre articulos y pedidos por el codigo de articulo. CREATE TABLESPACE data CREATE TABLE artículos (cod_art NUMBER(5) CONSTRAIN unq_art UNIQUE USING INDEX PCTFREE 10 TABLESPACE index STORAGE (INITIAL 260K NEXT 100K PCINCREASE 10 MAXEXTENTS 10 ), desc_art VARCHAR2(20), exist_art NUMBER(7) TABLESPACE data PCTFREE 10 PCTUSED 15 14 STORAGE (INITIAL 2M NEXT 1M PCTINCREASE 20 MINEXTENTS 2 MAXEXTENTS 5) ); CREATE TABLE pedidos (cod_ped NUMBER(9), cod_art NUMBER(5), fecha_ped DATE, fecha_cierre_ped DATE, num_art NUMBER(5) CONSTRAIN clv UNIQUE (cod_ped,cod_art) USING INDEX PCTFREE 10 TABLESPACE index STORAGE (INITIAL 120M NEXT 20M PCTINCREASE 20 MAXEXTENTS 20 ) CONSTRAIN integridad FOREING KEY (cod_art) REFERENCES artículos(cod_art) ON DELETE CASCADE TABLESPACE data 15 STORAGE INITIAL 350M NEXT 70M PCTINCREASE 20); EJERCICIO: Banco: tiene unos 10 millones de clientes. Los datos por cliente serán: • Codigo de cliente(numerico) • Nombre del cliente (carácter) • Dirección (carácter) • Tlfn (numerico) • Fecha de alta del cliente • Fecha de baja del cliente Habra otra tabla de cuentas con 15 millones con los datos: • codigo de cuenta (numerico) • fecha de apertura • fecha de cierre • saldo (numerico) • codigo de cliente • tipo de cuenta Existirá otra tabla de tipos con los datos: • tipo de cuenta (numerico) • descripcion (carácter) Entre clientes un cuentas habrá una relación con integridad referencial por codigo de cliente y entre cuentas y tipos habrá otra relación con integridad referencial por tipo de cuenta. Las dos relaciónes tendrán la propiedad de borrar en cascada. Habrá menos de 100 elementos en la tabla de tipos. Habrá un crecimiento anual del 5% en el de clientes, con lo cual en la tabla de cuentas el crecimiento será al menos del 5%, aunque habrá que tener en cuenta que cada cliente puede tener más de una cuenta. CREACIÓN DE SINÓNIMOS La estructura para crear sinónimos es la siguiente: CREATE SYNONYM nombre FOR nombre de tabla o de vista ; Con esto nos evitamos tener que escribir cada vez que nos queremos referir a una tabla o a una vista, su nombre y su dueño. Cuando se crea un sinomino es para uso propio, pero si queremos que lo pueda usar cualquiera se pondrá: CREATE PUBLIC SYNONYM ... CREACIÓN DE ROLES 16 Estos sirven para no tener que estar usuario por usuario dando los mismos privilegios para un grupo. Se crea un rol y se le da privilegios, y después a una serie de usuarios se les da el privilegio de poder usar el rol con lo cual tiene los mismos privilegios que le dimos al rol. CREATE ROLE nombre.rol IDENTIFIED BY password; Estos roles pueden estar protegidos por contraseña con la palabra IDENTIFIED BY, y si no se quiere proteger por password se tiene que poner NOT IDENTIFIED. Solamente lo puede borrar el usuario que lo ha creado. Para usar el role hay que usar el comando SET. Este se activa poniendo: SET ROLE nombre_role IDENTIFIED BY password ; En el caso de que la password no estuviera bien, daría un error y no daría los privilegios del role. ELIMINACIÓN DE OBJETOS La sentencia para borrar objetos es DROP. ELIMINACIÓN DE TABLAS Para borrar una tabla se utiliza la instrucción: DROP TABLE nombre_tabla Si esa tabla tiene alguna relación de integridad referencial no dejaría borrarla, al haber datos que están relacionados con los datos de esta tabla. Para poder borrarlo se puede usar la instrucción de la forma siguiente: DROP TABLE nombre_tabla CASCADE CONSTRAIN De esta forma inhabilita las relaciones de integridad referencial que tenga esa tabla y la da de baja. Con las tablas hijas no hay ningún problema a la hora de borrarlas, sino que el CASCADE CONSTRIAN es para tablas padre que tienen tablas hijas. No borra las tablas hija, sino que quita las relaciones y borra las padres, quedándose las tablas hijas huérfanas. Cuando se borra una tabla se producen los siguientes efectos: • Se borran todas las filas • Se borran todos los índices relacionados. • Libera y devuelve todo el espacio (data blocks) de la tabla al tablespace • Las vistas relacionadas con esa tabla quedan marcadas como invalidas. No se borran, sino que se marcan. ELIMINACIÓN DE ÍNDICES Para eliminar un índice se usa la instrucción: DROP INDEX nombre_índice ELIMINACIÓN DE SINÓNIMOS Para eliminar un sinomio se usa la instrucción: 17 DROP SYNONYM nombre_sinónimo Y si era público se especifica PUBLIC ELIMINACIÓN DE ROLES Para eliminar un role se usa la instrucción: DROP ROLE nombre_role BORRAR FILAS DE UNA TABLA Si queremos borrar todas las filas de una tabla podemos usar la instrucción: TRUNCATE TABLE nombre_tabla {DROP STORAGE | REUSE STORAGE} Si usamos la instrucción DELETE podremos despues recuperar los datos por medio del ROLL BACK pero con el truncate se borra directamente de forma muy rápida y sin la posibilidad de recuperar los datos. Con la opción DROP STORAGE elimina todos los datos y libera todas las extens para el tablespace menos la primaria. Si ponemos REUSE STORAGE simplemente borrara las filas y conservará los extents vacíos. MODIFICACIÓN DE LAS CARACT. DE UN OBJETO Se usa el comando ALTER. Se pueden modificar los siguientes objetos: ALTER TABLE Podemos modificar las siguientes características de la tabla: • Añadir columnas • Añadir restricciones de integridad • Redefinir una columna • Modificar características de almacenamiento • Habilitar, deshabilitar o borrar restricciones de integridad • Alocar explícitamente una expresión. EJEMPLO: ALTER TABLE tabla_name ADD (nombre_columna tipo_dato DEFAULT expresión Restricción de integridad ADD (Restricción de integridad a la tabla) MODIFY(nombre_columna tipo_de_dato longitud DEFAULT expresión Restricciones_de_integridad) DROP constraint PCTFREE n PCTUSE n 18 STORAGE (INITIAL Nk NEXT Nk PCTINCREASE n MAXEXTENT MINEXTENT) No dejara hacer modificaciones de tipos datos en columnas a no ser que la tabla esté vacia. Si que se puede modificar en algunos casos la longitud de las columnas. También podremos modificar el default y también las restricciones de integridad, pero siempre y cuando las filas que están introducidas ya en la tabla permitan hacer esas restricciones de integridad. También se puede permitir alterar algunos de los parámetros de almacenamiento de la tabla. Se podrá hacer una modificación del parámetro INITIAL, pero solo tendrá efecto a la hora de que el administrador haga la función de recuperación de datos, cuando se crea otra vez la extent y se vuelven a meter los datos. Se puede cambiar el tipo de dato de una columna si y solo si la tabla está vacía. Si se puede cambiar el tipo de dato de una columna en una tabla con datos si es para pasar una columna de tipo char a varchar, siempre y cuando no sea menor el numero de bytes del varchar2 que del char. Si en esa columna hay todo nulos también se puede cambiar el tipo de dato. También se puede cambiar la precisión en los tipos de datos numéricos. Si se aumenta la precisión del numérico no da ningún problema. Si se disminuye la precisión habrá problemas. Si lo que se quiere es cambiar una clave única, es decir, añadir una, puede que no te deje en el caso de que se haya repetido un código. Lo mismo pasa a la hora de crear claves primarias y relaciones de integridad referencial. Cuando se quiere añadir columnas a una tabla que tiene filas ya metidas, obligatoriamente esa columna tiene que admitir nulos, puesto que para los elementos que ya existen en la tabla el valor que va a tomar esa columna es el nulo. ALTER INDEX Sirve para modificar los parámetros de un índice. Se pueden cambiar los parametros: PCTFREE Y STORAGE (INITIAL, NEXT, PCTINCREASE,MIN..,MAX) ALTER ROLE Sirve para modificar los parametros de un rol. Se puede cambiar la password del role con: ALTER ROLE nombre_rol NOT IDENTIFIED (para quitarselo) ALTER ROLE nombre_rol IDENTIFIED BY password. (para poner password nueva) GESTION DE PRIVILEGIOS 19 Para dar privilegios a un role o a un usuario se usa la orden grant. La estructura de este comando es la siguiente: GRANT privilegio, privilegio, ...[ ALL ] ON nombre_objeto TO {usuario, role, public} WITH GRAN OPTION Con la opción public después del TO se le da dicho privilegio a todo el mundo. Los objetos posibles son tabla o vista. WITH GRAN OPTION sirve para dar la opción a quien le das el privilegio de poder dar ese privilegio a otra persona. Es decir, que el que recibe el privilegio puede dárselo a otro. PRIVILEGIOS Sobre tablas se pueden dar los siguientes privilegios SELECT: permite ver la tabla UPDATE: permite actualizar datos de la tabla DELETE: permite borrar datos de la tabla INSERT: permite insertar filas en la tabla ALTER: permite alterar las propiedades de la tabla INDEX: permite definir indices sobre la tabla REFERENCES: permite crear relaciones de integridad referencial sobre la tabla Sobre vistas se pueden dar los siguientes privilegios: SELECT, UPDATE, DELETE, INSERT Para quitar los derechos se usa la instrucción REVOKE. Las estructura de esta sentencia es la siguiente: REVOKE privilegio,.. [ALL] ON nombre.objeto FROM {usuario,role,public} CASCADE CONSTRAIN COMANDOS DML Ahora viene una descripción del manejo de las bases de datos. COMANDO SELECT Sirve para seleccionar la tabla que vamos a manejar. Su estructura es la siguiente: SELECT * FROM tabla; Para recuperar algunas de las columnas de la tabla se usa la siguiente instrucción: SELECT columna1, columna2, columan3, ... FROM tabla 20 También se puede recuperar datos de una tabla según una condición que le planteemos: SELECT * FROM tabla WHERE cond; Esa condición puede ser que en un campo hubiera un dato determinado. Los operadores que nos podemos encontrar son: <,>,<=,>=,=,<>,in, not in, between, not between Tambien se pueden crear máscaras con el comando like SELECT * FROM tabla WHERE dirección_empleado LIKE `ruiz%' Enseña a todos los empleados que vivan en una calle que empieze por ruiz. Se puede decir que saque las filas ordenadas con la instrucción ORDER BY columna1, columna2,... detrás de la instrucción select. Funciones numéricas: ABS nos devuelve el valor absoluto CEIL devuelve el mayor entero siguiente COS devuelve el coseno EXP devuelve el exponencial FLOOR es la inversa del CEIL SQRT devuelve la raiz cuadrada de n TAN devuelve la tangente ROUND (N,M) Redondea el primero a el segundo cifras decimales POWER Eleva el primero al seguno MOD devuelve el resto de la division del primero por el segundo SIN devuelve el seno de n SIGN nos devuelve el signo del numero introducido TRUNC (n,m) Este corta las cifras decimales Operaciones con caracteres: Para concatenar caracteres se usa la instrucción || SELECT `ABC'||'DEF' FROM DUAL También se puede usar el comando CONCAT(`JUAN','DIEGO') FROM DUAL La instrucción INITCAP devuelve el string que se le pasa con el primer carácter en mayuscula. 21 La instrucción LOWER(`CaSa') FROM DUAL pasa todos los caracteres en mayuscula de la cadena a minusculas La instrucción LTRIM(CHAR[,SET]) suprime todos los caracteres por la izquierda hasta que se encuentra un carácter distinto al especificado en el segundo parametro LTRIM(`xyzXjhg','z') el resultado será Xjhg La instrucción RTRIM es igual que la anteriór pero en vez de por la izq es por la derecha. Estas instrucciónes son muy buenas para quitar espacios en blanco a cadenas de caracteres. La instrucción REPLACE (CHAR, CAD1, CAD2) reemplaza las ocurrencias que haya en char de la cadena 1 por las de la cadena 2 REPLACE(`TORERO','RO','RA') devolverá TORERA La instrucción SUBSTR(CHAR,M,N) EJERCICIO: Cuenta Cod_cliente Nombre_cliente Dirección_cli Codigo_postal Tipo_cuenta Saldo_medio_a Saldo_actual Preguntas: 1.− Filas que tengan por apellido Lopez 2.− Clientes que vivan en la C/Alta 3.− Vivan en la calle del pez y tengan un saldo mayor de 1.500.000 4.− Vivan en la calle Castilla o aledaños y tengan una cuenta corriente de mas de 250.000 5.1.− Tengan depósitos anuales de menos de 2.000.000 o cuentas corrientes de más de 500.000 5.2.− Tengan depósitos anuales de menos de 2.000.000 y cuentas corrientes de más de 500.000 6.− Tengan cuentas corrientes o depósitos con un saldo inferior a 300.000 7.− Calcular el interes neto que debo pagar a los clientes con depósitos anuales de saldo entre 1.000.000 y 2.000.000 (I=3%) Respuestas: 1.− SELECT * FROM cuentas WHERE nom_clientes LIKE %López% 2.− SELECT * FROM cuentas WHERE dirección_cliente =C/Alta 3.− SELECT * FROM cuentas WHERE dirección_cliente=C/Pez and saldo_actual>1.500.000 4.− SELECT * FROM cuentas WHERE codigo_postal='39003' and saldo_actual>250.000 22 5.1.− SELECT * FROM cuentas WHERE (tipo_cuenta=3 and saldo_actual<2.000.000) or (tipo_cuenta=2 and saldo_actual>500.000) 5.2.− (SELECT cod_cli FROM cuentas WHERE tipo_cuenta=3 and saldo_actual<2.000.000) INTERSECT (SELECT cod_cli FROM cuentas WHERE tipo_cuenta=2 and saldo_actual>500.000 6.− SELECT * FROM cuentas WHERE saldo_actual < 300.000 7.− SELECT nombre_cliente,(saldo_actual*3/100) FROM cuentas WHERE (saldo_actual >1.000.000 and saldo_actual<2.000.000) Funciones de grupo: GROUP BY obligatorio • AVG(n): Calcula la media de los datos de una columna. Un ejemplo de su uso sería: SELECT AVG(saldo_actual) FROM cuentas WHERE tipo_cuenta=1; • MAX(n): Calcula el máximo elemento de una columna • MIN(n): Calcula el mínimo elemento de una columna • SUM(n): Calcula la suma de una columna • COUNT(n): Calcula el numero de filas de una columna. Funciones con fechas: • SYSDATE: nos devuelve la fecha y la hora del día. • LAST_DAY (date): devuelve la fecha del último día del mes que se le introduce. Por ejemplo: LAST_DAY (5/12/1999) devolverá 31/12/1999. • ADD_MONTH(date, n) añade n meses a la fecha especificada. • MONTHS_BETWEEN(date1, date2) devuelve el numero de meses que hay entre las dos fechas Sumar un entero a una fecha te devuelve n días más de la fecha. EJERCICIO: Cod_emplea Cod_dept Fecha_alta Nom_emple Dir_emp Cod_cat Sal_base Compl1 Compl2 Coef_irpf Cod_departamento Cod_categoria descripcion Descripción 1.− Calcular la masa salarial anual teniendo en cuenta que tenemos 2 pagas extraordinarias al año y estas comprometen al salario base 2.− Haremos una subida salarial del 2% lineal tanto al salario base como a los complementos 3.− A los del departamento de atención del cliente se les hará además una subida del 3% lineal del complemto 1. 4.− Para aquellos trabajadores que tengan un sueldo inferior a 150.000 se les baja un punto del coeficiente de IRPF. Para los que ganan entre 150.000 y 300.000 se les baja 0'25 y a los que ganan más de 300.000 se les sube 0'5 puntos 23 Borrardo de filas de una tabla DELETE Para borrar filas de una tabla se usa el comando DELETE. Por ejemplo: DELETE FROM nombre_tabla WHERE condición; Actualización de datos UPDATE El comando UPDATE sirve para actualizar los datos de uno o más campos de una o más filas. Su estructura es: UPDATE nombre_tabla SET columna1=valor, columna2=valor, ... WHERE condición; Si no ponemos una condición cambiará el valor de esa columna a todas la filas de una tabla. Insertar filas en una tabla INSERT El comando INSERT sirve para insertar nuevas filas en una tabla. Su estructura es la siguiente: INSERT INTO nombre_tabla columna1,columna2,columna3,... VALUES(valor1, ...) El nombre de las columnas tiene que estar en el orden en el que se creo la tabla. Si omitimos alguna de las columnas en la lista, y en consecuencia no le damos ningún valor, se le asignará el valor por defecto que tenga definido dicha columna. En caso de que no tenga definido ningún valor por defecto dará un error por no incluir esa columna. SOLUCIÓN AL EJERCICIO ANTERIOR 1.− SELECT (SUM(sal_base)*14)+(SUM(compl1)+SUM(compl2))*12 FROM empleados 2.− UPDATE empleados SET sal_base=(sal_base * 2/100)+sal_base, compl1=(compl1*2/100)+compl1, compl2=(compl2*2/100)+compl2 3.− UPDATE empleados SET compl1=(compl1*3/100)+compl1 WHERE cod_dep in (SELECT cod_dep FROM departamentos WHERE descripcion LIKE atención al cliente) 4.− • UPDATE empleados SET coef_irpf=coef_irpf−1 WHERE sal_base<=150.000 • UPDATE empleados SET coef_irpf=coef_irpf−0.25 WHERE sal_base between(150.000, 300.000) • UPDATE empleados SET coef_irpf=coef_irpf+0.5 WHERE sal_base>=300.000 Funciones de conversión Tenemos básicamente 3 funciones de conversión: TO_CHAR • TO_CHAR(x,formato) Transforma datos de columnas a formato carácter. Puede transformar tanto datos numéricos como de fecha. Se le especificará un formato, que será como una máscara. • TO_NUMBER(char,formato): Sirve para transformar caracteres numéricos a una variable numérica. • TO_DATE(char, formato): Sirve para transformar una fecha que está en formato de carácter a una variable fecha. 24 Formatos máscara para números Indicando nueves en la máscara se indicará la precisión que queremos que tenga el número. Por ejemplo: TO_CHAR(124,'99999') = __124 Indicando una S le decimos que nos muestre el signo: TO_CHAR(124,'S9999')=_+124 Con la D, el `.' o `,' le indicamos donde irá el punto. Se pondrá `.' o `,' según que es lo que esté definido en el sistema como separador decimal. TO_CHAR(1234.678,'9999.9')=1234.7 Con la G, la `,' o `.', según lo que esté especificado por el administrador en el sistema, pondremos los separadores de los miles: TO_CHAR(12345.678,'9G999D99') = 12.345,68 (En el caso de que esté configurado el punto como separador de miles y que la coma sea el separador de decimales. Si ponemos E's pondrá formato de potencias de 10 Si ponemos L nos pondrá el símbolo de la moneda. Formato de máscara para fecha A la hora de convertir variables de tipo carácter con números a tipos de variable numérico tendremos que poner la máscara dependiendo de cómo ofrezca el char la información numérica, es decir, que habría que decir que máscara tiene la variable de tipo carácter con los números. En el caso de que el formato que le incluimos no sea el correcto nos dará un error. Formato de mascara para fecha Poniendo Y te pone el año. Se puede poner de 1 a 4, dependiendo de las cifras con las que queramos el año. Si ponemos YEAR nos pondrá el año en letras. Con MM nos mondrá el número del mes. Con MONTH nos pondrá el mes en letras. <no los he copiado todos porque no me da la .... gana > CONTINUACIÓN DEL EJERCICIO ANTERIOR 5.− Dar de alta a un nuevo empleado 6.− La lista de empleados que se incorporan a la empresa después del 1 de Marzo de 1981 7.− Crear una nueva categoría `Directivos estrategicos', con cod_catg 90. Cambiar a esta categoría los empleados que pertenecían a la categoría de directivos y que tienen un salario_base de más de 1.000.000 SOLUCIONES: 5.− INSERT INTO empleados cod_emp, cod_dep, fecha_alta, nom_empleado, dir_empleado, cod_categoría, 25 sal_base,compl1,compl2,coef_irpf VALUES (...) 6.− SELECT * FROM empleados WHERE fecha_alta > TO_DATE(01/03/1981,DD/MM/YYYY) 7.− A) INSERT INTO categorías cod_categoria, desc_categoría VALUES (90,Directivos estratégicos) B) UPDATE empleados SET cod_cat=90 WHERE cod_cat in (SELECT cod_cat FROM categorías WHERE descripcion LIKE `Directivos') and sal_base < 500.000 16/11/1999 MANEJO DEL ENTORNO DE SQL PLUS Para ver todas las tablas que tenemos cada usuario tenemos que ver las filas que tiene la tabla cat, que es el tabla del esquema de usuario de cada uno. SELECT * FROM CAT; 17/11/1999 EJERCICIO: Pasar los ejercicios anteriores al SQL PLUS CREACIÓN DE VISTAS EN EL SQL PLUS CREATE VIEW empl_view AS (SELECT cod_emp,nombre,dirección,fecha_alta from EMPL); Este comando creará un objeto vista con únicamente las columnas que se le especifican en el select que está entre paréntesis. Una vez creada la vista podemos manejarla como si fuera una tabla, con la salvedad de que si queremos meter datos, en el caso de que no se vean todas las columnas de la tabla a la que se referencia (o de las tablas), estos datos que no se ven tendrán que poder tener el valor nulo o un valor por defecto, porque ese será el valor que se le asigne. 18/11/1999 Se puede hacer que en una vista solo aparezcan ciertas filas de la tabla, simplemente poniendo las condiciones del where en la sentencia select que se especifica entre los paréntesis. También se puede especificar los nombres que aparecerán en la cabecera de la tabla INSTRUCCIÓNES PARA INTERACTUAR CON VARIOS SELECT Estas instrucciones son: UNION, UNION ALL, INTERSEC, MINUS. Con estas instrucciones se puede hacer salidas conbinadas entre varias instrucciones select con diferentes tablas. Lo lógico es que la salida de los dos select tengan las mismas columnas o el mismo tipo de columnas. Con el UNION saldrian las columnas de los dos select como si hubiera sido uno solo. Con el UNION ALL sería la misma salida que con el anterir, pero con la salvedad de que no daldrían columnas repetidas. Con INTERSEC solo saldrían aquellas filas que fuesen iguales en los dos select. Con el MINUS saldrían todas las filas que están en el primer select menos las filas que aparezcan en el segundo select. 26 Un ejemplo sería: (SELECT * FROM empleados WHERE cod_emp<3) UNION (SELECT * FROM empleados WHERE cod_emp >5) 19/11/99 AGRUPACIONES DE FILAS DENTRO DE TABLAS Este comando sirve para hacer agrupaciones de filas por el valor de columnas o para utilizar set funciones de grupo. Por ejemplo, para sacar la masa salarial por cada categoria se podría usar la siguiente instrucción: SELECT cod_categoria, SUM(sal_base) FROM empleados GROUP BY (cod_categoría) Esto lo que hace es sacar las sumas de los salarios base de todos los empleados, pero agrupadas por la categoría de los empleados. También se pueden hacer varias agrupaciones diferentes dentro de una misma sentencia select: SELECT cod_dep,cod_cat,SUM(sal_base) FROM empleados GROUP BY cod_dep,cod_cat REDIRECCIONAR SALIDAS A FICHEROS Para redireccionar la salida de datos a un fichero se usa el comando SPOOL seguido de un nombre de fichero con ruta. Todas aquellas salidas que hagamos con el SQL plus nos irá al fichero especificado. A parte de salir por pantalla también se guardará en un fichero. Para que no nos siga guardando las salidas por pantalla a fichero se usa SPOOL OFF. USO DE VARIABLES EN FICHEROS DE COMANDOS DE SQL A la hora de crear ficheros de texto con instrucciones, se pueden poner variables de la forma &1, &2,... de tal forma, que cuando se ejecuta dicho archivo de texto con la instrucción @ se le especifican a continuación los valores de las variables en orden respectivamente. Para definir variables se usa el comando DEFINE. Una vez definida una variable se puede usar en el entorno SQL. Sería como tener un sinónimo almacenado en la memoria que se puede usar en cualquier sentencia SQL. Estas variables van siempre precedidas del símbolo &. Para referirse a una variable dentro de una sentencia aparecerá entre comillas en el caso de que tenga que estar entre ellas. Si cuando se ejecuta una sentencia en SQL con una variable esta no existe, te pedirá seguidamente cual es el valor que se le asocia. En este último caso la variable que no existía no se crea, pero en el caso de que queramos que se cree dicha variable podremos hacerlo con dos símbolos & precediendo al nombre en vez de con uno. COMANDOS PARA EL FORMATEO DE FORMULARIOS Comando SET: Este comando sirve para modificar algunos de los parametros del SQL plus. Estos parametros son: • SET PAUSE on/off: Hace un pause cada vez que los datos visualizados con un select llenan la página. • SET HEADING on/off : Activa o desactiva las cabeceras de los comandos select. • SET ECHO on/off • SET FEEDBACK on/off: Enseña el numero de filas resultantes de una sentencia select. • SET PAGESIZE n: Especifica el numero de líneas que hay por cada página. Por defecto son 14 27 páginas. • SET LINESIZE n: Especifica el numero de caracteres que va a tener cada línea. Por defecto son 80 caracteres. Comandos para el formateos de salidas: Estos son los comandos que nos van a permitir formatear la salida de los select, como poner títulos, encabezados, etc. TTITLE Este comando sirve para poner un titulo a la salida de datos de un comando select. Por ejemplo: TTITLE `Informe de pruebas | DAI' Con este comando saldrá un titulo de dos líneas (separadas por el símbolo | ) antes de cada sentencia select. En caso de que no le especifiquemos nada nos pondrá el título con una justificación centrada. Podremos nosotros especificarle otra justificación con las expresiones: COL n, LEFT, RIGHT o CENTER. Podemos usar la expresión SKIP para que salte un numero determinado de líneas antes de escribir el título. Ejemplo TTITLE COL 4 Informe de prueba SKIP CENTER DAI Con este ejemplo nos escribiría el primer titulo con la justificación en la cuarta columna, y el segundo dos líneas más abajo con la justificación centrada. También se le puede decir que el texto salga en negrita con la expresión BOLD, con lo cual el texto sale tres veces en tres líneas diferentes resaltándolo. BREAK Con esta sentencia hace rupturas en el select de una tabla según los valores de una columna de dicha tabla. Es muy util en el caso de querer dividir en pequeñas tablas una tabla según el valor que tenga una columna. Break on cod_dep Con este ejemplo nos haría diferenciaciones entre los empleados de diferentes departamentos. Si le añadimos la expresión SKIP a continuación nos dejará un espacio en blanco después de cada apartado. COMPUTE Nos permite hacer cálculos sobre los datos de la tabla. Este comando está siempre ligado a un comando BREAK anterior. Con lo cual, si ponemos: COMPUTE SUM of sal_base on cod_dep; Nos sacará las sumas de los salarios base dentro de un departamento. EJERCICIO: Calcular los sueldos mínimos y medios por departamento en la tabla de empleados. SOLUCIÓN: 28 BREAK ON cod_dep SKIP 1; COMPUTE MIN OF sal_base+compl1+compl2 ON cod_dep; SELECT cod_emp,cod_dep,nombre,apellidos,sal_base+compl1+compl2 from empleados order by cod_emp; Con esto se calcula el salario mínimo, y para calcular la media de salarios dentro de un mismo departamento seguiríamos limpiando la sentencia compute y modificandola para que calcule la media de cada apartado: CLEAR BREAK; COMPUTE AVG OF sal_base+colmpl1+compl2 ON cod_dep; SELECT cod_emp,cod_dep,nombre,apellidos,sal_base+compl1+compl2 from empleados order by TRANSACCIONES ORACLE Es un conjunto de sentencias de SQL que comienzan cuando empieza el programa, cuando hacemos un commit, cuando se ejecuta una sentencia feedback o cuando se encuentra una sentencia DDL. Termina la transacción cuando se acaba el programa, después de ejecutar un commit, después de un rollback o después de una sentencia DDL. Los cambios se hacen efectivos en el sistema gestor de base de datos cuando ocurren una de estas cuatro cosas. Todos esos cambios que estamos realizando no son realmente buenos, es decir, que no se modifica el fichero, hasta que se realiza una de esas cuatro operaciones. En el caso de que se vaya la luz, se perderían todos los cambios que se han efectuado desde la ultima vez que ocurrió una de esas cuatro cosas. JOIN Podemos hacer en un mismo select una consulta de datos de diferentes tablas, siempre y cuando exista alguna relación entre dichas tablas. Así, podemos sacar el listado de empleados de nuestra base de datos y podemos poner la descripción del departamento de cada empleado haciendo referencia con el cod_dep al fichero de departamentos. SELECT empleados.cod_emp,empleados.nombre,departamentos.desc_dep,empleados.sal_base FROM empleados,departamentos WHERE empleados.cod_dep=departamentos.cod_dep; Los campos irán precedidos por el nombre de la tabla, y después del FROM tendremos que especificar el nombre de las tablas referenciadas. Después habrá que decirle cuales son las relaciones entre campos de los diferentes tablas después del WHERE INSTRUCCIÓN BTITTLE Esta instrucción formatea los pies de página de la misma forma que el TTITLE para las cabeceras de página. REPORT En los break podemos especificar un report de la forma BREAK ON REPORT para que haga una sentencia COMPUTE al final de la ejecución de una sentencia SELECT COLUMN 29 Podemos definir el nombre que queremos que salga en una columna en vez de la salida normal que es el nombre de la columna en la tabla. Para ello usaremos el comando COLUMN de la siguiente forma: COLUMN cod_emp HEADING `codigo de empleado'; También con este comando podemos definir una longitud de campo máxima, para que no nos muestre toda su información en caso de que sea muy larga. Para ello haremos lo siguiente COLUMN desc_dep FORMAT A20; Puede ocurrir que si una palabra no entre en el campo después de formatearlo la corte o que escriba justamente debajo lo que queda de texto. Esto se puede controlar desde la propia instrucción con: Wrap: Los caracteres que no entran nos los pone justamente debajo. Wordwrap: Lo mismo que el anterior pero con palabras enteras. Truncate: Nos cortaría las palabras y no mostraría la información que no entra. También podemos alinear los titulos de las columnas con el comando JUSTIFY y especificandole que tipo de justificación queremos: CENTER, RIGHT o LEFT CAMBIO DE PASSWORD Para cambiar la password tendremos que ejecutar la siguiente instrucción: ALTER USER nombre.usuario IDENTIFIED BY nuevo_password; 24/11/99 OTROS COMANDOS COMANDOS ANY E IN Con el ANY se le puede especificar una serie de valores entre paréntesis y separados por comas. Se usa en condiciones y la condición se cumpliría cuando se cumpliera con alguno de los valores que se le especifican. Con el in tendrá que cumplirse la condición de que el valor tiene que estar en la lista que se le especifica entre paréntesis y separado por comas. Select * from emp where cod_emp in (1,2,3,4,5) Select * from emp where sal_base >(sal1,sal2,sal3) COMANDO ALL El comando ALL es muy parecido al comando ANY. En el anterior la condición se tenía que cumplir con alguno de los valores que se le especificaban entre paréntesis. Con el ALL se tiene que cumplir la condición con todos los valores que se le especifican entre paréntesis. COMANDO DECODE Select apellidos,DECODE (cod_banco,'111222','santander','222333','Bankinter', '333444',Asturias','ninguno') 30 from emp; Este comando nos mostrará un dato dependiendo del valor que tenga el campo que se le especifica al principio. Se le van dando valores en pareja, el primero es el valor que tiene que tener el campo y el segundo el nombre que aparecerá, y al final se le especifica un string que aparecerá si el valor que tiene dicho campo no está especificado en el decode. EJERCICIO: La empresa para la que ya tenemos una base de datos con los empleados también quiere tener la opción de poder dar prestamos a sus empleado, para lo cual tendremos que crear una tabla de prestamos: cod_prest numérico not null cod_emp numérico not null tipo_prest numérico not null fecha_con date not null fecha_can date null importe numérico not null interes numérico default = 0 n_años numérico not null También necesitamos una tabla de tipos de prestamos que tendrá dos columnas: cod_prest numerico y not null; y desc_prest de tipo carácter que admita hasta 50 caracteres. Habrá restricciones de integridad referencial entre prestamos y empleados por el cod_emp y entre prestamos y tipos de prestamos por el campo tipo_prestamo. También tendremos otra tabla de pagos_prestamo que tendrá los campos: Cod_prest numerico not null Fecha_pago date not null Importe_pago numerico Esta última tabla va a tener una clave externa por cod_prest a la tabla de prestamos. • Crear una vista con las mismas columnas que tenga la tabla prestamos pero que solo muestre los prestamos activos. • Crear una vista con los prestamos cerrados. • Hacer un informe con los empleados a los que se les ha prestado durante el año en curso. Tendrá que estar agrupado por el tipo de préstamo. Para cada tipo de préstamo obtener el importe total prestado y al final del informe que aparezca el total prestado. En el informe debe aparecer el nombre del empleado, el importe del préstamo, la fecha de concesión y el tipo de préstamo. • Utilizar el informe anterior para obtener otro con los prestamos abiertos el primer trimestre. • Obtener un informe con todos los prestamos abiertos agrupados por departamentos y tipo de préstamo. 31 • Informe: • Crear una vista a partir de la tabla pagos_préstamo en la que aparezca el código de préstamo, la suma de importes para cada préstamo y el nº de pagos. • Obtener para cada empleado con un préstamo activo, el código del préstamo, el importe total de pagos efectuados y el nº de pagos efectuado. • Obtener un informe en el que aparezcan reflejados los importes medios de los prestamos de cada tipo concedidos en los últimos 3 años. • Obtener un informe con el nombre de los empleados que tengan activo mas de un prestamo. • Obtener la lista de los empleados que no han tenido nunca ningún préstamo agrupado por departamentos y ordenados por categorias. • Obtener la lista de los empleados que han pagado durante este año mas de 100.000 pts en concepto de amortozación de prestamos. Agrupados por: • Codigo de empleado y amortización • Nombre de cliente y amortización. • Añadir a la tabla de prestamos una nueva columna `saldo' que representa el saldo de cada préstamo y actualizarlos con los valores reales de los saldos. • Consultas al catalogo: • Espacio libre disponible para cada uno de nosotros. • Obtener un informe con información de las tablas: nombre columna, tipo de dato. Agrupado por nombre de tabla y ordenado por columnas. • Obtener información nueva de lo que ocupan realmente, vuestras tablas. • Obtener las constraint que teneis definidas. FALTA ALGO DE APUNTES (1 HORA) USER INDEXES Información para cada índice del que soy propietario. Nos dara : index.name, table_name, uniqueness, tablespace_name, initial_extent, min_extent, nax extent, pct_free, pct_increase. User_ind_columns Nos dara informacion como: index_name, table_name, ncolumn_position, column_length. USER_RESOURCE_LIMITS Una fila con los recursos sobre los objetos en los que tienes un limite. USER_ROLE_PRIVS Roles a los que tenemos acceso: username, granted role. Granter: el que otorga el privilegio. Grantee: recibe el privilegio. USER_SEGMENTS: 32 Información relativa sobre los segmentos en los que yo soy propietario. Segment_name, segment_type,tablespace, bytes, blocks etc es lo que nos dara de info. USER_SYNONYM: Info relativa a los sinónimos que yo he definido. Nos da información sobre: Synonym_name, table_owner, table_name. USER_TABLE Información sobre mis tablas. Table_name, table−space_name, pct_free, pct_used, max_extent etc. USER_TAB_COLUMNS Guarda una fila por cada una de las columnas que hay en cada una de las tablas de nuestra propiedad. Table_name, column_name, data_type, data_legth, data_precision, data_scale, default, column id etc. USER_TABS_COMMENTS Lo mismo que el anterior pero en vez de filas guarda comentarios. USER_TAB_PRIVS Informacion de la tablas sobre las que hemos dado un privilegio. USER_TS_QUOTAS Información relativa a la quota definida en un tablespace. PL/SQL CURSORES ========= Declaración, apertura, acceso a filas y cerrado (fases de un cursor) El cursor se define en la declare (parrafo de declaracion de variables): Declare Cursor nombre_cursor is select ....... Ejemplo cursor c1 is select cod_cliente, nombre from clientes where cuota > 20000; En este momento todavia on ha ido a la base de datos a hacer la consulta. Dentro del parrafo BEGIN del programa se abre el cursor 33 BEGIN Open cursor en nuestro caso c1. FETCH nombre_cursor INTO var1, var2 etc (en el ejemplo seria fetch c1 into v_cod_cliente, v_nombre; (por cada fetch el apuntador salta de fila y lee la siguiente es un tratamiento secuencial). Y se termina con un CLOSE nombre_cursor; (las filas dejan de estar disponibles para mi programa). Si la sentencia select de la definicion del cursor llevase una variable por ejemplo where cuota > v_cuota la sentencia open verificara los valores y los sustituira para obtener resultados concretos. Al abrir el cursor se pueden definir las variables que utilizara el propio cursor. Cursor nombre_cursor ([variable tipo [=valor]) is select ....... Ejemplo : cursor c1 (cuota_minima unmber) is select descripcion from actividades where cuota_socio > cuota_mínima; Open c1 (5000 cuota mínima que pedimos y resto de variables si las hubiese). % notfound sera true si el ultimo fetch ejecutado contra un cursor no encuentra ninguna fila en el cursor el atributo notfound estará a true y viceversa a falso. Not found valdrá null cuando se haya echo un open sin un primer fetch. %Found devolvera true cuando el ultimo fetch haya encontrado fila y estara a false si el ultimo fetgh sino encuentra filas. %rowcount: n º de fials recuperadas por fecht ejemplo open loop sentencias; fetch c1 into.........; if % c1 rowcount > 100 then exit; end if; end loop; %isopen esta a true si el cursor esta habierto y viceversa. 34 Para codificar un programa en pl/sql se puede hacer en un ficheero de taxto o irlo codificando directamente en SQL plus. Según vea un declare ya sabe que es un pl/sql y no una sentencia de sql plus. Ejercicios 1.− Actualizar el nombre del cliente `a1111' a `Antonio Jose' 2.− Actualizar la cuota del cliente a1111 incrementándosela en un 10% si la antigüedad es mayor de 2 años o un 8% si es mayor de tres años o un 5% en otro caso. ROWID: es un número con tres campos con una extructura XXXXXXXX.YYYY.ZZZZ. Las x es el numero de bloque o data block al que pertenece la fila (identificativo unico que se asigna al dar de alta una fila en una tabla y que permanece inalterable mientras exista la tabla) y puede ser consultada. Las YYYY es el numero de data block ZZZZ es el numero de fichero o data file donde se aloja el data block. FALTA MUCHO Y MUCHO Y MUCHO EJERCICIOS 1.− Hacer PL/SQL que actualice las cuotas de los clientes activos con el criterio: • Antigüedad menor de 2 años = 10% • Antigüedad menor de 3 años = 8% • Antigüedad mayor de 3 años = 5% 2.− Crear una tabla como la de clientes. Construir un PL/SQL que cargue en la nueva tabla las filas de la tabla clientes. 3.− Para mantener los saldos de la tabla de prestamo.empleado. 4.− Para mantener la tabla de los pagos para los prestamos activos. Desarrollo de aplicaciones en lenguajes de 4º Generación 31 35