I.E.S LA ARBOLEDA (ALCORCÓN) CASE DESARROLLO DE APLICACIONES INFORMÁTICAS EN ENTORNOS DE CUARTA GENERACIÓN CON HERRAMIENTAS CASE De M o N Case CASE Apuntes tomados de la clase de CASE del I.E.S. La Arboleda de Alcorcón durante el curso 2002/2003. Pasados por David “DeMoN” Rodríguez. Queda totalmente prohibida la NO distribución de estos apuntes, así que “COMPARTE” ;-). 2 Case COMPOSICIÓN DEL CURSO 1. OBJETIVO GENERAL Capacitación en el uso de herramientas de desarrollo de 4ª Generación para el desarrollo rápido de aplicaciones basadas en Bases de Datos (desde ahora BD) a partir de un correcto diseño de una BD. CAPACITACIÓN PROFESIONAL: Desarrollador en “Sistemas Integrados de gestión de BD Relacionales” y particularmente en el entorno ORACLE. 2. OBJETIVOS ESPECÍFICOS - Realizar diseños correctos de BD Relacionales. Conocer los principios de los sistemas de BD relacionales. Definir y manipular en modo interactivo una BD relacional mediante SQL (ORACLE SQL*PLUS). Desarrollar módulos de programación con SQL embebido (ORACLE PL/SQL) Utilizar generadores de pantallas y menús (ORACLE DEVELOPER FORMS BUILDER) Utilizar generadores de informes (ORACLE DEVELOPER REPORTS BUILDER) Conocer el uso de herramientas CASE para modelización de datos (ORACLE DESIGNER) 3. T E M A R I O 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Concepto de Base de Datos El modelo relacional de datos. Introducción a SQL Definición de estructuras de datos y otros objetos relacionales mediante SQL Uso de SQL en modo interactivo. Principios operativos de la herramienta ORACLE SQL*PLUS Uso de SQL en modo programación ORACLE PL/SQL Generación de pantallas y menús DEVELOPER 2000, ORACLE FORMS BUILDER Generación de informes DEVELOPER 2000, ORACLE REPORTS BUILDER Proyecto integrador. Desarrollo de una aplicación de gestión. Uso de herramientas CASE para la modelización de datos. ORACLE DESIGNER 4. TEMPORALIZACIÓN 1ª Evaluación ! Temas 1- 6/7 2ª Evaluación ! Temas 7- 11 5. CONTENIDOS MÍNIMOS Son los temas del 1-8 y el tema 10. Son los temas fundamentales de la asignatura. 3 Case 6. EVALUACIONES 40% de la nota final 1ª evaluación 30% de la nota final 2ª evaluación 30% de la nota final proyecto integrador 7. RECUPERACIONES Las recuperaciones se realizarán por bloques en Marzo. El proyecto integrador NO tiene recuperación. Si se suspende la recuperación se hará una convocatoria extraordinaria en Junio, y si se aprueba se realizarán las FCT en cuanto sea posible. 8. BIBLIOGRAFÍA - ORACLE GUÍA DE APRENDIZAJE. Michael Abbeg/ Michael J. Coreg. Ed. Oracle-Press/ McGraw Hill - MANUAL DE ORACLE DEVELOPER 2000 Robert J. Miller Ed. Oracle-Press/ McGraw Hill - ORACLE 8. PROGRAMACIÓN PL/SQL Scott Urman. Ed. Osborne/ McGraw Hill - DISEÑO Y USO DE BASES DE DATOS RELACIONALES Irene Luque/ M. Ángel Gómez Nieto Ed. Ramos 4 Case I bloque 5 Case 6 Case TEMA 1. CONCEPTO DE BASE DE DATOS. 1. Que es una BD 1.1. Definición 1.2. Ventajas de los sistemas de BD sobre los sistemas de ficheros tradicionales. 2. Elementos de un sistema de BD. 3. Características de los sistemas gestores de BD. 4. Arquitectura CLIENTE-SERVIDOR 5. Modelo de datos. 1. QUE ES UNA BD 1.1. DEFINICIÓN. Una BD es una colección de datos que están lógicamente relacionados entre sí. Los datos están estructurados según un modelo de BD que refleja las relaciones y restricciones que tienen estos datos en el mundo real. La descripción y la definición de los datos están almacenados en la misma BD. Los tratamientos que se realizan con los datos han de conservar la integridad y la seguridad de la BD. 1.2. VENTAJAS DE LOS SISTEMAS DE BD SOBRE LOS SISTEMAS DE FICHEROS • Independencia de los datos respecto de los tratamientos y viceversa. A los sistemas de ficheros tradicionales se les llama “Sistemas Orientados al Proceso”, ya que los datos se almacenan en ficheros diseñados específicamente para cada aplicación, de tal manera que si un dato es utilizado por más de una aplicación aparecerá repetido en dos o más ficheros. Además, si se modifica el tratamiento que realiza un proceso sobre los datos es necesario reestructurar los ficheros. Por tanto, en estos sistemas de ficheros los datos son dependientes de los tratamientos que se realizan sobre ellos. A los sistemas de BD se les llama “Sistemas Orientados al Dato”, ya que los datos se estructuran según un modelo que refleja las características que tienen en el mundo real, y ese modelo permite que cualquier proceso pueda tratar los datos. En estos sistemas los datos son independientes de los tratamientos que se realizan sobre ellos. • Descripción centralizada de los datos. La definición de los datos se almacena en la misma BD, de manera que los tratamientos no tienen que especificar de nuevo la definición de los datos. Además, esto ofrece una mejor y más normalizada documentación de la información. 7 Case • Eficiencia en la estructuración de los datos. Al estar los datos estructurados según un modelo, no se producen redundancias de datos, es decir, que el mismo dato no aparece en dos o más ficheros. Esto evita 3 problemas: - • Por un lado no se desperdicia espacio de memoria almacenando la misma información varias veces. Se ahorra tiempo de proceso al no tener que modificar el dato en varios ficheros. Se evita la corrupción de la BD, ya que al modificar un dato habría que hacerlo en todos los ficheros en que aparece, y si no se modifica en alguno de los ficheros, la BD sería inconsistente. Mayor nivel informático Los sistemas de BD ofrecen herramientas más potentes y más sencillas para la modificación de los datos. Los sistemas de BD están integrados en los sistemas de desarrollo de 4ª Generación. En contra, los sistemas por ficheros pertenecen a los sistemas de 3ª Generación. 2. ELEMENTOS DE UNA BD. • Los datos: es el conjunto de datos que estructurados y almacenados en un soporte magnético u óptico de acceso directo. A este conjunto de datos es lo que suele denominarse Base de Datos. • La metabase: es la información sobre los datos de la BD. Es imprescindible para que el sistema autodocumentado pueda suministrar a los usuarios, al administrador de la BD y al sistema gestor de BD (SGBD) la información que necesita sobre los datos almacenados y su funcionamiento. Los elementos fundamentales de la metabase son: Catalogo o diccionario de datos, que contiene la descripción lógica de cada uno de los datos, es decir, contiene la descripción desde el punto de vista del usuario. Esta información es: tipo de dato, fichero en que se encuentra, relación entre ficheros, etc. - Directorio de datos, que contiene la descripción física de los datos, que permite pasar de la representación externa a la interna. - Sistema de seguridad, que es a dos niveles, la seguridad lógica que contiene y controla los permisos de acceso de los usuarios a los datos, o seguridad física, que consiste en registrar en unos ficheros llamados log o dietario las operaciones realizadas en la BD, con el objeto de poder deshacerlas en caso de error. • El software de gestión de sistema: también llamado logical. Es el conjunto de programas, procedimientos, lenguajes, etc. capaces de realizar todos los tratamientos exigidos para el funcionamiento del sistema. Estos elementos son: - - Sistema gestor de BD, núcleo de un sistema de BD. Permite que el usuario pueda crear, actualizar y recuperar los datos contenidos en la BD, es decir, interpreta las órdenes del usuario y la ejecuta físicamente. Lenguaje de definición de datos (DDL) y lenguaje de manipulación de datos (DML). Utilidades de administración de la BD, que facilitan las tareas de mantenimiento y seguridad de la BD. Estos programas realizan tareas como por ejemplo: modificación del 8 Case tamaño del fichero, realizar copias de seguridad, herramientas para la exportación e importación de datos, estadísticas de utilización de los datos. - Herramientas de desarrollo que es el conjunto de lenguajes para el desarrollo de aplicaciones. • El administrador de la BD (BDA): es la persona cuya misión es asegurar la calidad y permitir el uso de los datos, diseñando la BD de manera que el diseño de su estructura lógica y la implementación de su estructura física responda lo mejor posible a las necesidades de los distintos usuarios. ORACLE INFORMIX DB II INTGRES SQL SERVER MOTOR JET 4GL C clientes servidor JAVA SQL Base de Datos SGBD FORMS REPORTS Diccionario Privilegios Directorio LOG de datos SYSADM DBA 3. CARACTERÍSTICAS DE LOS SISTEMAS GESTORES DE BD Los sistemas de BD proporcionan mecanismos para proteger los datos contra fallos que los alteren y corrompan. Los fallos que pueden alterar los datos son físicos, por ejemplo, fallos en la memoria RAM o de disco, caídas del sistema, interrupción de la energía, etc., o lógicos, como fallos del programa o del SO o del SGBD. El tercer tipo de fallo es el fallo humano, que puede ser intencionado o no intencionado. Para proteger los datos, el SGBD debe tener 3 características: seguridad, integridad y confidencialidad. • Seguridad: Se trata de recuperar un estado consistente de los datos ante fallos que los destruyen total o parcialmente. Un caso muy común que provoca la inconsistencia de la BD es cuando una operación lógica se traduce en varias acciones en la BD, de tal manera que la operación sólo tiene sentido cuando se realizan todas las acciones. Este problema lo soluciona el SGBD con las transacciones, a saber, secuencias de operaciones que han de ejecutarse de forma atómica, es decir, o se realizan todas las operaciones que componen la transacción o ninguna de ellas. Cuando hay que deshacer las acciones de una transacción inconclusa el sistema se apoya en el fichero log, que es un fichero en el que el sistema va grabando todas las operaciones que se realizan sobre la BD. A este tipo de recuperación se le denomina recuperación en caliente. Otro tipo de fallo que se puede sufrir es el que afecta a la memoria del disco. En este caso la información se recuperaría desde una copia de respaldo o Backup, que 9 Case conserva el estado de los datos en una fecha determinada. A esta operación se la denomina recuperación en frío. • Integridad: El objetivo de la integridad es lograr que los datos contenidos sean correctos. Para ello el SGBD debe detectar y corregir las operaciones incorrectas que introduzcan inconsistencias en la BD. Hay dos tipos de operaciones que pueden afectar a la integridad de los datos: - Operaciones que atentan contra las reglas de integridad: Existencial o Referencial. Interferencias por accesos concurrentes. En el primer caso las restricciones de integridad son definidas en el momento del diseño de la BD, de modo que el SGBD vela por que se cumplan, no permitiendo operaciones que la violen. En el caso del control concurrente a los datos, el sistema lo soluciona con el mecanismo de bloqueos. • Confidencialidad: La confidencialidad se refiere a la protección de los datos contra accesos de usuarios no autorizados. Las decisiones sobre a que usuarios se les debe permitir realizar operaciones sobre qué objetos son decisiones de política de empresa, no decisiones técnicas. Para que el control de accesos se pueda ejecutar, es necesario que los usuarios del sistema se identifiquen mediante un login y un password, y los privilegios, permisos y autorizaciones han de estar registrados en la BD. Los sistemas que requieren una gran seguridad utilizan sistemas de criptografía, de tal manera que los datos están grabados en la BD cifrados, siendo necesario conocer la clave para descifrarlos. Por último, otro mecanismo para mantener la seguridad en la confidencialidad es facilitar la auditoría, registrando en unos ficheros auditores todos los accesos de los usuarios a los datos, pudiendo detectar a posteriori accesos no permitidos y por tanto mejorar el sistema de seguridad. 4. ARQUITECTURA CLIENTE-SERVIDOR Un sistema de BD posee una estructura compuesta por 2 partes: Un servidor (backend) y un conjunto de clientes (frontend). El servidor ofrece servicios para realizar operaciones físicas sobre los datos, es decir, el servidor el propio SGBD. Los clientes son aplicaciones ejecutadas en torno al SGBD, en los que se realizan varias operaciones, sobre todo de interfaz de usuario y tratamientos procedimentales, pero cuando requieren acceder a los datos se comunican con el servidor, que atiende los requerimientos y devuelve los resultados. Existen varias tipologías para implementar la estructura cliente-servidor: 10 Case • El cliente y el servidor se ejecutan en la misma máquina. Aplicac iones SGBD datos • El servidor y el cliente están en distintas máquinas (proceso distribuido). Requiere de un sistema de comunicaciones. Aplicaciones SGBD datos Aplicaciones • Existen varios servidores, y cada uno de ellos contiene parte de la BD. (BD’s distribuidas). SGBD Aplicaciones datos Red de Comunicaciones Aplicaciones Aplicaciones SGBD datos 11 Case • Arquitectura a 3 niveles (World Wide Web). Se usa en aplicaciones de la web, tanto en intranet como en internet. Aquí el servidor se instala en una máquina, pero la parte de cliente se reparte en 2 niveles: 1 máquina servidor de aplicaciones y 1 máquina cliente. Servidor de aplicaciones Servidor de aplicaciones Servidor de la BD datos 5. MODELO DE DATOS. El objetivo de cualquier sistema de información es representar, mediante una abstracción del mundo real, toda la información necesaria para el cumplimiento de sus fines. Estos fines pueden ser obtener facturas, controlar stocks de almacén, gestionar las matrículas de un centro educativo. Esta abstracción se realiza mediante un modelo de datos que es un conjunto de métodos y reglas que indican cómo se ha de almacenar la información y cómo se ha de manipular los datos. Existen 2 tipos de modelos: • • Modelo conceptual, que es una representación de la realidad no comprometida con ningún entorno informático. El modelo conceptual más popular es el modelo entidadrelación de Chen. Modelo lógico, que determina unos criterios de almacenamiento y de operaciones de manipulación de datos dentro de un tipo de entorno informático. Los SGBD comerciales se basan en un modelo lógico concreto y determinan en parte el modelo físico. Históricamente, los modelos lógicos de datos son: - Modelo jerárquico (IMS [IBM]). Modelo en red (CODASYL). Modelo relacional (ORACLE, DB II [IBM], INFORMIX, INGRES, SQL SERVER). Modelo orientado a objetos (Eiffel). 12 Case T.2. EL MODELO RELACIONAL DE DATOS 0. 1. 2. 3. INTRODUCCIÓN ESTRUCTURA DEL MODELO RESTRICCIONES DEL MODELO MANIPULACIÓN DE DATOS. 0. INTRODUCCIÓN El modelo relacional constituye el fundamento teórico de los SGBD comerciales más utilizados en la actualidad. El modelo relacional es propuesto por CODD en la década de 1970. Es un modelo de datos basado en la teoría matemática de las relaciones, en la que los datos se estructuran en el ámbito lógico en forma de relaciones. Uno de los objetivos fundamentales del modelo relacional es que la estructura lógica de los datos es independiente de su almacenamiento interno. Así, el modelo no contempla en absoluto los aspectos físicos de la BD, que queda en manos de los constructores de SGBD comerciales, que tienen como directrices el mejor rendimiento posible de sus sistemas. El modelo relacional se puede considerar como una combinación de 3 componentes, que son estructurales, de integridad y de manipulación. 1. ESTRUCTURA DEL MODELO Las estructuras de datos están formadas por tablas o relaciones, filas o tuplas, columnas o atributos y claves primarias y claves ajenas. Sistema de Ficheros Teoría relacional Fichero Registro Campo Relación Tupla Atributo SGBD relacionales Tabla Fila Columna Una tabla es una matriz rectangular dispuesta en filas y columnas y se puede representar de dos formas: • Representación tabular: Alumno DNI NUMEXP NOMBRE FECHA DIRECCIÓN CODCICLO 13 Case • Representación en forma de Tupla, que consiste en representar la tabla mediante el nombre de la tabla seguido por los atributos separados por comas, subrayando los atributos que son clave principal. Alumno (DNI, NUMEXP, NOMBRE, FECHA, DIRECCIÓN, CODCICLO) Las características de las tablas son: - En una tabla no hay filas repetidas. Las filas no están ordenadas dentro de la tabla por ningún criterio. En una tabla no hay dos columnas con el mismo nombre. En una celda de la tabla puede haber como máximo 1 valor. En cuanto a las claves se definen los siguientes conceptos: - Clave candidata. Es un subconjunto de columnas de la tabla que identifican cada fila de forma unívoca. Una clave candidata ha de ser irreductible, es decir, que ningún subconjunto de las columnas que forman la clave candidata sea a su vez clave candidata. En toda tabla hay al menos 1 clave candidata, ya que según el modelo no puede haber dos filas iguales. - Clave primaria. (Primary Key, PK). De entre todas las claves candidatas, el diseñador ha de elegir una de ellas como clave primaria, por criterios ajenos al modelo relacional, siguiendo criterios propios del sistema de información. El resto de las claves candidatas pasarán a llamarse claves alternativas (AK). La clave primaria es de gran importancia en el modelo, pues es la que permite la relación entre las tablas. - Clave ajena. (Foreing Key, FK). Es un conjunto de columnas de una tabla T2 cuyos valores han de coincidir con los valores de la PK de otra tabla T1. Las tablas T1 y T2 pueden ser la misma. La estructura del modelo relacional en los SGBD relacionales se amplía con tablas virtuales llamadas Vistas o Views. Una vista es una tabla derivada de otras tablas, que se representa dentro del sistema por su definición, pero que no posee datos almacenados propios separados de las tablas reales. Son una visión distinta de los datos almacenados en las tablas. Algunas vistas pueden ser actualizables y otras no. Otro elemento estructural de los SGBD relacionales son los índices. Un índice es una estructura opcional asociada a columnas de una tabla, que permite acelerar el acceso a los datos de la tabla. El que existan índices es totalmente transparente a los programadores y usuarios, pero el SGBD utiliza siempre los índices existentes. Así, el hecho de definir índices es una decisión que atañe al BDA para mejorar el rendimiento del sistema. Los índices son lógica y físicamente independientes de las tablas a las que se asocia, así que se pueden crear y eliminar índices sin que por ello se vean afectados los datos de la tabla. El SGBD ORACLE crea automáticamente un índice asociado a cada columna definida como clave primaria o alternativa. 14 Case 2. RESTRICCIONES DEL MODELO (INTEGRIDAD) El modelo relacional tiene una serie de restricciones, es decir, estructura u ocurrencias no permitidas. Las restricciones pueden ser inherentes al modelo (restricciones de integridad) y restricciones de usuario, que son unos predicados definidos sobre columnas o filas que deben ser verificados por el sistema para determinan si son válidos en el sistema de información. • Restricciones inherentes al modelo: Son: - Regla de integridad, de identidad o existencial, que dice que ninguna columna de las que forman parte de la PK puede tener un valor nulo. Un nulo no es ningún valor, sino que es una marca que se aplica a una columna para indicar que no tiene asignado ningún valor. Regla de integridad referencial, que dice que una FK debe tener un valor de la clave primaria de la tabla con la que se relaciona, o bien tener valor nulo. - " Reglas para FK: Cualquier estado de la BD que no satisfaga la integridad referencial es incorrecto por definición. Hay una serie de reglas para evitar estos estados incorrectos, que se indican en el momento de la definición de la BD, especificando qué debe hacer el sistema en caso de borrado o modificación que atente contra la integridad referencial. Hay las siguientes posibilidades: א א א א • Operación restringida: (Restrict) No se permite borrar filas ni modificar el valor de su clave primaria si existen FK’s que contengan su valor. Operación con propagación en cascada: (Cascade) El borrado o la modificación de la PK lleva consigo el borrado o modificación de las filas con los mismos valores en la FK. Operación con puesta a nulos: (Set Null) El borrado o modificación de las filas de la tabla que contiene la PK provoca la asignación de un valor nulo en las FK’s con el mismo valor. Operación con puesta a valor por defecto: (Set Default) El borrado o modificación de las filas de la tabla que contiene la PK provoca la asignación de un valor por defecto en las FK’s con el mismo valor. Restricciones de usuario: es un predicado definido sobre columnas o filas que han de ser verificadas por el sistema para determinar si la información es válida. Éstas restricciones de usuario pueden estar relacionadas en el diccionario de la BD o bien estar soportadas como procedimientos o disparadores. Una restricción de usuario ha de tener un nombre, el predicado que ha de ser satisfecho y una respuesta a la operación que intenta violar la restricción. 3. MANIPULACIÓN DE LOS DATOS. Codd definió 3 sistemas matemáticos pertenecientes al álgebra de conjuntos, para manipular los datos estructurados según el modelo relacional. Estos lenguajes son equivalentes entre sí, y tienen en común que no son lenguajes navegacionales, es decir, que no actúan sobre filas individuales, sino que son lenguajes de especificación que actúan sobre conjuntos de filas. Estos lenguajes son: Álgebra relacional orientada a tuplas, Cálculo relacional orientado a Tuplas y Cálculo relacional orientado a dominios. 15 Case Los lenguajes DML de los SGBD comerciales se basan en uno o varios de estos lenguajes matemáticos. Por ejemplo, el SQL está basado en el álgebra relacional y en el cálculo relacional orientado a tuplas. 16 Case T.3. INTRODUCCIÓN A SQL. 1. 2. 3. 4. 5. 6. QUE ES SQL. CÓMO SE USA SQL. PARA QUE SIRVE SQL. ELEMENTOS DE UNA SENTENCIA SQL. TIPOS DE DATOS. FUNCIONES. 1. QUE ES SQL El SQL es un lenguaje que permite expresar operaciones de definición de estructura de datos, de autorizaciones de acceso a los datos y de consulta y actualización de datos almacenados en la BD relacionales. La palabra SQL está formada por las iniciales inglesas Structured Query Languaje. La 1ª versión SQL la desarrolló IBM en la década de los 70. Ante el éxito de esta primera versión, otras empresas como ORACLE, DIGITAL o UNISYS desarrollaron sus propios lenguajes SQL, tanto para microoordenadores, miniordenadores y mainframes, lo que ha llevado a que sea una herramienta ampliamente utilizada en el mundo de las BD’s relacionales. Esta tendencia se vio consolidada debido a que ANSI (American National Standard Institute) desarrolló sus propias especificaciones para el lenguaje SQL, que posteriormente fueron aceptadas por la organización ISO (International Standard Organization). Las características principales del SQL frente a los sistemas tradicionales son: • • • Permite manejar conjunto de registros en lugar de registro a registro. Tiene una fuerte base teórica matemática, lo que le da una gran capacidad expresiva con una estructura muy simple. Ello permite mediante una sola sentencia expresar consultas complejas que tradicionalmente requerían de uno o varios programas. Se puede utilizar de forma interactiva, lo que permite realizar consultas no planificadas, es decir, que no están incluidas en programas, por lo que los mismos usuarios finales pueden acceder directamente a los datos. 2. CÓMO SE USA SQL. Las sentencias se pueden dirigir al sistema de 2 formas: • • Modo interactivo: la sentencia se escribe directamente en la pantalla del ordenador, se ejecuta y sobre la misma pantalla aparecen los resultados de la consulta. SQL embebido en un lenguaje de programación: en un lenguaje de 3ª o 4ª generación se insertan sentencias SQL para acceder a los datos de una BD relacional, y los resultados del acceso son recogidos por el programa que los tratará, por ejemplo, para listarlos. Al lenguaje donde se insertan sentencias SQL se le llama lenguaje anfitrión y puede ser C, JAVA, PL/SQL... Hay dos técnicas para utilizar SQL embebido en programas: 17 Case - SQL estático, donde las sentencias SQL incluidas en el programa no pueden cambiar durante la ejecución. SQL dinámico, donde una sentencia SQL puede ser modificada total o parcialmente por el propio programa durante su ejecución. 3. PARA QUE SIRVE SQL. El SQL se compone de 3 sublenguajes: • Lenguaje de definición de datos (DDL), que permite crear, alterar y eliminar objetos de la BD, como tablas, vistas, índices, restricciones, usuarios, disparadores, etc. Estas tareas son propias del DBA. Las sentencias son: - Create: para crear objetos. Alter: para alterar objetos ya creados de la BD. Drop: para eliminar objetos de la BD. • Lenguajes de manipulación de datos (DML), que permite añadir, modificar, borrar y consultar datos de la BD. Las sentencias son: Select: para consultar datos de una o varias tablas. Insert: para añadir una o varias filas en una tabla. Update: para modificar el valor de columnas de una o varias filas de una tabla. Delete: para borrar filas de una tabla. • Lenguaje de control de datos (DCL), que permite asignar y retirar autorizaciones de acceso a los datos y controlar transacciones. Estas sentencias son: - Grant: para otorgar autorizaciones de acceso. Revoke: para retirar autorizaciones de acceso. Commit: para confirmar transacciones. Rollback: para anular transacciones. 4. ELEMENTOS DE UNA SENTENCIA SQL Las sentencias SQL tienen los siguientes componentes: • • • • • Palabras reservadas, que tienen un significado predefinido en el lenguaje. Puede ser una sentencia, una cláusula o una función. Nombres de tablas, vistas o columnas, inventadas por los creadores de la BD que se asignan en el momento de la creación. Nombres de variables huéspedes, que son nombres de variables de programa que se insertan dentro de una sentencia. Constantes, que pueden ser numéricos o alfanuméricos entre comillas simples. Signos delimitadores, como paréntesis, operadores relacionales, operaciones aritméticas, espacios en blanco. 18 Case 5. TIPOS DE DATOS Los tipos de datos de los que se puede declarar una columna de una tabla en ORACLE son: • • • • • • • NUMBER (p,s): para declarar valores numéricos. Los parámetros p y s son opcionales. El parámetro p indica la cantidad máxima de dígitos totales que podrá tener el número. El parámetro s indica la cantidad de dígitos que tendrá la parte digital. Si no se especifican ni p ni s el valor se almacena tal y como se signe a la columna. Los operadores son +, -, * y /. CHAR (n): para declarar cadenas de caracteres de longitud fija de ‘n’ caracteres. El máximo de ‘n’ es 255 bytes. Si se omite el parámetro ‘n’ asume el valor 1. VARCHAR2 (n): para declarar cadenas de caracteres de longitud variable entre 0 y n caracteres. El tamaño máximo es de 4.000 bytes. El operador para cadenas, tanto para char como para varchar2 es el operador de concatenación de cadenas ||. LONG: que contiene cualquier dato imprimible, como ‘A’, ‘3’, ‘&’... Su longitud máxima es de 2 GB y se utiliza para guardar textos. RAW (n): que contiene información binaria. Su longitud máxima es de 255 bytes. LONG RAW: que contiene información binaria hasta 2 GB. Se utiliza para almacenar información gráfica, sonidos... DATE: que almacena datos del tipo fecha y hora. Los valores permitidos van desde el 1 de junio de 4.712 A.C. hasta el 30 de diciembre de 4712 D.C. En las consultas se presenta el dato con el formato por defecto DD-MM-YY. El dato almacenado en la BD es en realidad un número al que se le aplica un algoritmo de conversión y se presenta en el formato que se especifique. Si no se especifica ningún formato lo presenta en el formato por defecto. El formato por defecto se especifica en la variable de entorno NLS_DATE_FORMAT. Esta variable de entorno se encuentra en la clave de registro del sistema HKEY_LOCAL_MACHINE\Software\Oracle\Home0. En un dato de tipo fecha viene almacenado: año, mes, día, hora, minuto y segundo. a) Funciones para tratamientos de fechas: - SYSDATE: que devuelve la fecha del sistema. TO_CHAR (dato.fecha[,máscara[,’nlsparams’]]): Esta función convierte el dato de tipo DATE al tipo de VARCHAR2, según el formato especificado en la máscara. El parámetro NLS_PARAMS especifica el lenguaje en que aparecerán escritos los nombres y las abreviaturas de los nombres y las abreviaturas de los meses y días de la semana. Para indicarle la lengua especificamos ‘NLS_DATE_LANGUAGE = idioma’. Los elementos de la máscara para datos de tipo fecha son: א א א א א א א א א א א mm: número del mes (1-12). mon: abreviatura del mes (Ene.). month: nombre del mes (Enero). rm: mes en números romanos ( I ). ddd: número del día del año (1-366) dd: día del mes (1-31). d: día de la semana (1-7). dy: abreviatura del día de la semana (Mar.). day: nombre del día de la semana (Martes). yyyy: año con 4 dígitos (2002). yy: año con 2 dígitos (02). 19 Case א א א א א א א א א א year: año en letra (dos mil dos). q: número del cuatrimestre (1..4). ww: semana del año (1..53). w: semana del mes (1..5). hh: hora del día (1..12). hh12: hora del día (1..12). hh24: hora del día (1..24). mi: minuto de la hora (1..60). ss: segundo del minuto (1..60). am: muestra AM o PM según sea antes o después del mediodía. - TO_DATE: Convierte el dato de tipo char o varchar2 a tipo DATE. La máscara es un formato de fecha en el que está representado el dato alfanumérico. Si se omite la máscara el dato ha de estar en el formato de fecha por defecto. b) Asignación de valor a una columna de tipo DATE: Se puede asignar directamente valor a una columna de tipo DATE si la cadena de caracteres utiliza el formato por defecto, pues el sistema hace automáticamente la conversión. Si se ha de asignar un valor a una columna de tipo DATE con un formato distinto al formato por defecto se ha de utilizar la instrucción TO_DATE, que convierte una cadena de caracteres a un dato de tipo DATE. Si se asigna un valor a una columna de tipo fecha sin indicar hora:minutos:segundos se almacena por defecto 12:00:00 am. c) Operadores de fechas: Con las fechas se pueden utilizar los operadores + y -. Si a una fecha se le suma un entero ‘n’ devuelve la fecha pasado n días. Si a una fecha se le resta un entero n nos da la fecha de n días antes. Si se restan dos fechas devuelve el número de días que hay entre ellas. Si se suma o resta fracciones de enteros devuelve la fecha pasadas las horas, los minutos o los segundos teniendo en cuenta que 1/24= 1h. 1/1440= 1min. y 1/86400= 1sg. 6. FUNCIONES. • Para datos numéricos: א א א א א א א א א ABS(n): Devuelve el valor absoluto de n. CEIL(n): Devuelve el entero más grande menor o igual que n. FLOOR(n): Devuelve el entero más grande menor o igual que n. MOD(m,n): Devuelve el resto de dividir m entre n. POWER(m,n): Eleva m a n. ROUND(n,[m]): Redondea n. Si m no es 0 redondea a m decimales. SIGN(n): Devuelve –1 si n<0, 0 si n=0 y 1 si n>0. SQRT(n): Devuelve la raíz cuadrada de n. TRUNC(n,[m]): Trunca n. Si m no es 0 no trunca los m primeros decimales. 20 Case • Para las cadenas de caracteres: א א א א א א א א א א א א א א CHR(n): Devuelve el carácter asociado al código ASCII de n. ASCII(A): Devuelve el código ASCII de un carácter. CONCATA (A,B): Concatena las cadenas o variables A y B. Equivale a ||. INITCAP(A): Convierte a mayúsculas la letra inicial de cada palabra contenida en el argumento. LOWER(A): Convierte en minúsculas el argumento. UPPER(A): Convierte a mayúsculas el argumento. LPAD(A,n,[B]): Devuelve A ajustada a la derecha rellenada por la izquierda con el parámetro B hasta completar n. RPAD(A,n,[B]): Lo mismo que LPAD pero por la derecha. LTRIM(A,B): Elimina empezando por la izquierda del argumento A los caracteres que coinciden con el argumento B, hasta que encuentre uno diferente. RTRIM(A,B): Lo mismo que LTRIM pero por la derecha. REPLACE(A,B,[C]): Reemplaza en la cadena A, la subcadena B por la subcadena C. Si no aparece C, reemplaza con nada. SUBSTR(A,m,[n]): Devuelve una subcadena de A de longitud n, comenzando en la posición m. Sin m es negativo comienza por la derecha. INSTR(A,B[n,[m]]): Busca el argumento A, la cadena B, devolviendo la posición de comienzo. m y n por defecto son 1, de lo contrario comienza a buscar a partir del carácter que ocupa la posición n, o la ocurrencia que ocupe el emésimo lugar. (select instr(‘gabcdefghigg’,’g’,2,1) from dual;) LENGTH(A): Devuelve la longitud de la cadena. (select length(‘DeMoN’) from dual;) • Para fechas y conversión de datos: - SYSDATE: que devuelve la fecha del sistema. TO_CHAR (dato.fecha[,máscara[,’nlsparams’]]): Esta función convierte el dato de tipo DATE al tipo de VARCHAR2, según el formato especificado en la máscara. El parámetro NLS_PARAMS especifica el lenguaje en que aparecerán escritos los nombres y las abreviaturas de los nombres y las abreviaturas de los meses y días de la semana. Para indicarle la lengua especificamos ‘NLS_DATE_LANGUAGE = idioma’. Los elementos de la máscara para datos de tipo fecha son: א א א א א א א א א א א א א mm: número del mes (1-12). mon: abreviatura del mes (Ene.). month: nombre del mes (Enero). rm: mes en números romanos ( I ). ddd: número del día del año (1-366) dd: día del mes (1-31). d: día de la semana (1-7). dy: abreviatura del día de la semana (Mar.). day: nombre del día de la semana (Martes). yyyy: año con 4 dígitos (2002). yy: año con 2 dígitos (02). year: año en letra (dos mil dos). q: número del cuatrimestre (1..4). 21 Case א א א א א א א א ww: semana del año (1..53). w: semana del mes (1..5). hh: hora del día (1..12). hh12: hora del día (1..12). hh24: hora del día (1..24). mi: minuto de la hora (1..60). ss: segundo del minuto (1..60). am: muestra AM o PM según sea antes o después del mediodía. - TO_CHAR(dato,[máscara]): Convierte el dato de tipo NUMBER al tipo de VARCHAR2 según el formato especificado en la máscara. Los elementos de esta máscara pueden ser: א א א א א א 9: Devuelve el valor numérico eliminando los ceros a la izquierda. 0: Visualiza los ceros a la izquierda no significativos. MI: Devuelve el signo menos por la derecha si el valor es negativo. S: Devuelve + si es positivo o – si es negativo. ,: Puntuación de millar cuando proceda. .: Puntuación de decimal cuando proceda. - TO_DATE (dato,[máscara.[‘nlsparams’]]): Convierte el dato de tipo char o varchar2 a tipo DATE. La máscara es un formato de fecha en el que está representado el dato alfanumérico. Si se omite la máscara el dato ha de estar en el formato de fecha por defecto. TO_NUMBER (dato, [máscara.[‘nlsparams’]]): Convierte un dato de tipo CHAR o VARCHAR2 en un valor de tipo NUMBER, según el formato de la máscara. ADD_MONTHS(fecha, cantidad de meses): Suma meses a una fecha. MONTHS_BETWEEN(fecha1,fecha2): Devuelve el número de meses entre dos fechas. LAST_DAY(fecha): Devuelve la fecha correspondiente al último día del mes de la fecha indicada. • De propósito general: - NVL(expresión1, expresión2): Se utiliza para sustituir nulos por un valor real. Si expresión1 es nula devuelve expresión2, si no es nula devuelve expresión1. LEAST(valor1,valor2,...): Devuelve el menor valor de los especificados en la lista. GREATEST(valor1, valor2,...): Devuelve el mayor de todos los valores especificados. USER: Devuelve el nombre del usuario con el que se está conectado. - ORACLE proporciona una pequeña tabla con una fila y una columna llamada dual, para realizar pruebas y cálculos rápidos. Se utiliza cuando se quiere hacer trabajar con constantes en lugar de con columnas, especificando la tablas dual en la cláusula FROM de la sentencia SELECT, que es como no especificar ninguna tabla. 22 Case T.4. DEFINICIÓN DE ESTRUCTURAS DE DATOS Y OTROS OBJETOS DEL SISTEMA DE BD MEDIANTE SQL 1. CREACIÓN DE USUARIOS Y PERMISOS DEL SISTEMA. 2. EL DICCIONARIO DE DATOS. 3. LENGUAJE DE DEFINICIÓN DE DATOS (DDL). 4. CREACIÓN DE UNA TABLA. 5. ALTERACIÓN DE UNA TABLA. 6. ELIMINACIÓN DE UNA TABLA. 7. CONFIDENCIALIDAD DE LOS DATOS. 8. CREACIÓN DE ROLES. 9. CREACIÓN DE ÍNDICES. 10. CREACIÓN DE SINÓNIMOS. 11. CREACIÓN DE VISTAS. 1. CREACIÓN DE USUARIOS Y PERMISOS DEL SISTEMA. Para conseguir la confidencialidad en la BD es necesario definir usuarios que accedan a la BD y otorgarles permisos de acceso según su grado de responsabilidad en el sistema de información. El SGBD ORACLE viene con varios usuarios ya creados, entre ellos están: SYSTEM/manager: usuario administrador del sistema. SYS/change_on_install: que es el propietario del diccionario de datos. SCOTT/tiger: Para crear un nuevo usuario se usa el comando ‘create user nombre_usuario IDENTIFIED BY password [definiciones de almacenamiento físico]’ Las definiciones de almacenamiento físico son diferentes en cada SGBD. Son utilizadas por el DBA para optimizar el almacenamiento y el rendimiento del sistema. En el caso de ORACLE se definen unas áreas de memoria en disco que son espacios para ubicar las tablas, llamadas tablespace. Para conectarse al sistema con un nuevo usuario se utiliza el comando de SQL/PLUS ‘connect nombre_usuario/password’. Una vez creado un usuario, éste no puede hacer nada porque todavía no se le han asignado permisos sobre el sistema. Para facilitar la asignación de privilegios ORACLE utiliza el concepto de ROL, que es un grupo de privilegios con un nombre que pueden ser concedidos o denegados a un usuario. ORACLE ofrece 3 roles, que permiten al usuario conectarse a ORACLE: CONNECT: permite al usuario conectarse, pero no le permite crear objetos en la BD. RESOURCE: que permite al usuario crear sus propias tablas. DBA: que es el privilegio del DBA, así que se le asigna al usuario todos los privilegios. 23 Case Para otorgar un privilegio se utiliza la sentencia GRANT, con el siguiente formato: SQL> GRANT rol1[,rol2]... TO nombre_usuario; Para retirar un privilegio se utiliza la sentencia REVOKE, con el siguiente formato: SQL> REVOKE rol1[,rol2]... FROM nombre_usuario; 2. EL DICCIONARIO DE DATOS Un SGBD está constituido en torno a un Diccionario de Datos, que es utilizado por el sistema y por los usuarios para controlar los objetos existentes en la BD. En ORACLE el diccionario de datos está implementado mediante un conjunto de tablas y vistas que almacenan la información sobre la BD, y en ellas sólo puede escribir el SGBD. Los usuarios pueden acceder a las vistas del diccionario de datos mediante SQL para consultar. La mayoría de las vistas del diccionario aparecen en conjuntos de 3, que contienen información similar y que se diferencian con el prefijo. El prefijo USER_ visualizará sólo los objetos creados por el propio usuario. El prefijo ALL_ visualizará los objetos sobre los que el usuario tiene algún tipo de permiso. El Prefijo DBA_ visualizará todos los objetos que hay en el SGBD. Este tipo de vistas sólo pueden ser consultadas por un usuario que sea DBA, es decir, que tenga concedido el rol DBA. Algunas de las vistas del diccionario de datos son: • DICTIONARY o DICT: contiene la descripción de las tablas y vistas que componen el diccionario. SQL> select * from dict; Select table_name, substr(comments,1,40) from dict; • • • • DBA, ALL, USER_TABLES: contienen la descripción de las tablas creadas en el diccionario de datos. DBA, ALL, USER_CONSTRAINTS: contienen la descripción de las restricciones definidas sobre las tablas. DBA, ALL, USER_USERS: contienen la descripción de los usuarios definidos en la BD. DBA, ALL_TABLESPACES: contienen el nombre de los TABLESPACES definidos en la BD. El SGBD ORACLE ofrece un comando que permite ver la descripción de una tabla concreta. Este comando es DESC. SQL> DESC nombre_tabla; 3. LENGUAJE DE DEFINICIÓN DE DATOS (DDL). El conjunto de sentencias SQL que permiten crear, alterar y eliminar las estructuras de datos y otros objetos de la BD relacional reciben el nombre de DDL. El lenguaje DDL está basado en 3 verbos de SQL: 24 Case • • • CREATE: que define y crea objetos en la BD. DROP: que elimina un objeto existente en la BD. ALTER: que modifica la definición de un objeto de la BD. Los objetos de la BD a los que afectan estas instrucciones son: tablas, vistas, índices, restricciones, usuarios, roles, etc. 4. CREACIÓN DE UNA TABLA. El formato general para la creación de una tabla es: SQL> CREATE TABLE nombre_tabla (nombre_columna1 tipo_dato [restricción1], nombre_columna2 tipo_dato [restricción2], ······························································ nombre_columnaN tipo_dato [restricciónN]); Los nombres de las tablas y de las columnas debe empezar por una letra y puede incluir letras, dígitos y el guión bajo (_), hasta un máximo de 30 caracteres, no pudiendo utilizarse palabras reservadas del lenguaje. El lenguaje no distingue entre mayúsculas y minúsculas, pero en el diccionario de datos se graban en mayúsculas. El tipo de dato de las columnas ha de ser alguno de los permitidos en ORACLE. El formato para especificar las restricciones o CONSTRAINTS es: SQL> [CONSTRAINT nombre_restriccion] tipo_restriccion; Los tipos de restricciones pueden ser: • • • • • • PRIMARY KEY: determina que columna(s) forma(n) la clave primaria de la tabla. UNIQUE: determina que en la columna no puede haber valores repetidos, es decir, cada valor debe ser único en toda la tabla. Se suele declarar para claves alternativas. DEFAULT: determina el valor por defecto que se asignará a una columna cuando se inserte una fila en la tabla en la que no se da valor a la columna. Si la columna no tiene asignada esta restricción se le asigna el valor nulo. CHECK: permite controlar el valor que se le asigna a una columna, comprobando el valor signado con una lista de valores que se especifican entre paréntesis y separados por comas. En caso de insertar una fila donde el valor no coincida con alguno de los permitidos no permite la inserción. NOT NULL: impide que se inserten en la tabla filas a las que no se ha asignado valor en la columna que tiene asignada la restricción not null. FOREIGN KEY / REFERENCES: define claves ajenas indicando el nombre de la tabla y las columnas que forman la PK a la que hacen referencia. Las restricciones pueden ser definidas a nivel de columna o de tabla dependiendo de si se especifican al lado de la columna a la que afectan o después de haber declarado todas las columnas. Las restricciones que afectan a varias columnas han de ser definidas a nivel de tabla. 25 Case En el caso de definirse así el formato para crear la tabla sería: SQL> CREATE TABLE nombre_tabla ( nombre_col1 tipo_dato [restricción_col1], nombre_col2 tipo_dato [restricción1_col2], nombre_colN tipo_dato [restricción1_colN], [restricción1_tabla], [restricción2_tabla], [restricciónN_tabla]); En una misma sentencia de creación de una tabla se pueden especificar restricciones a nivel de columna y a nivel de tabla. Los formatos de las restricciones a nivel de columna o a nivel de tabla son los siguientes: • PRIMARY KEY: - a nivel de columna: >nombre_columna tipo_dato [CONSTRAINT nombre_restricción] PRIMARY KEY; - a nivel de tabla: >[CONSTRAINT nombre_restricción] PRIMARY KEY (nombre_columna.pk); • UNIQUE: - a nivel de columna: >nombre_columna tipo_dato [CONSTRAINT nombre_restricción] UNIQUE; - a nivel de tabla: >[CONSTRAINT nombre_restricción] UNIQUE (nombre_columna); • DEFAULT: sólo puede ser especificado a nivel de columna. >nombre_columna tipo_dato DEFAULT valor_por_defecto; • CHECK: - a nivel de columna: >nombre_columna tipo_dato [CONSTRAINT nombre_restricción] CHECK (nombre_columna IN (valor1, valor2,...valorN)); - a nivel de tabla: >[CONSTRAINT nombre_restricción] CHECK (nombre_columna IN (valor1, valor2,...valorN)); 26 Case • NOT NULL: sólo puede ser definido a nivel de tabla. >nombre_columna tipo_dato [CONSTRAINT nombre_restricción] NOT NULL; • FOREIGN KEY: - a nivel de columna: >nombre_columna tipo_dato [CONSTRAINT nombre_restricción] nombre_tabla_pk (nombre_columna_pk) [ON DELETE CASCADE]; - REFERENCES a nivel de tabla: >[CONSTRAINT nombre_restricción] FOREIGN KEY (nombre_columna_fk) REFERENCES nombre_tabla_pk (nombre_columna_pk) [ON DELETE CASCADE]; Con la opción ON DELETE CASCADE al eliminar una fila de la tabla maestra, es decir, la tabla que contiene la PK a la que se hace referencia, se borran todas las filas de la tabla relacionada cuyo valor de FK coincida con el valor de la PK borrada. ℘ PROPUESTA PARA LOS NOMBRES DE LAS RESTRICCIONES ℘ • • • • • PRIMARY KEY: UNIQUE: NOT NULL: CHECK: FOREIGN KEY: PK_tabla. UN_tabla_columna NN_tabla_columna CHK_tabla_columna FK_tabladetalle_tablamaestra 5. ALTERACIÓN DE UNA TABLA. La sentencia ALTER se utiliza para alterar la estructura de una tabla, pudiendo añadir nuevas columnas, redefinir los tipos de datos y sus tamaños, añadir y eliminar restricciones y activar y desactivar restricciones. La sentencia ALTER tiene dos formatos: • > FORMATO PARA ALTERAR COLUMNAS DE UNA TABLA ALTER TABLE nombre_tabla {ADD|MODIFY} nombre_columna tipo_dato; Con la opción ADD se añaden nuevas columnas, y con la opción MODIFY se modifica la definición de las columnas, pudiendo cambiar su tamaño y tipo de dato. Esta sentencia tiene las siguientes limitaciones: - No se puede borrar una columna de una tabla. No se puede cambiar el tipo de datos de una columna si contiene datos. No se puede disminuir el tamaño de una columna si contiene datos. 27 Case • > > FORMATO PARA ALTERAR LAS CONSTRAINTS ALTER TABLE nombre_tabla {DROP|DISABLE|ENABLE} constraint nombre_restricción; ALTER TABLE nombre_tabla add constraint nombre_restricción definición de restricción a nivel de nivel de tabla; Con DISABLE se deshabilita una constraint, es decir, sigue presente en el diccionario de datos pero no está activa. Con ENABLE se habilita una restricción que estaba previamente deshabilitada. Con DROP se elimina una restricción del diccionario de datos sin posibilidad de recuperación. Con ADD se añade una nueva restricción a una tabla. 6. ELIMINACIÓN DE UNA TABLA. El formato es: > DROP table nombre_table. Elimina los datos y la estructura de la tabla , eliminando toda referencia dentro del diccionario de datos y sin posibilidad de recuperarlos. 7. CONFIDENCIALIDAD DE LOS DATOS. Cuando se crea un usuario ORACLE crea una estructura lógica ‘ESQUEMA’, CON EL MISMO NOMBRE DEL USUARIO. Cuando un usuario crea una tabla en la BD es el propietario del objeto y el nombre del objeto está calificado por el nombre del esquema, con el siguiente formato: [nombre_esquema].nombre_objeto. Cuando se hagan referencias al objeto, si se omite el nombre del esquema el sistema asume el esquema del usuario con el que se está conectado a la BD. El usuario creador de un objeto es propietario de ese objeto, y un propietario tiene todos los privilegios sobre su objeto. Un usuario puede acceder a los objetos propiedad de otros usuarios si se le conceden los privilegios correspondientes. Hay dos tipos de privilegios: privilegios del sistema y privilegios de objeto. • • - PRIVILEGIOS DEL SISTEMA: son permisos para realizar aciones sobre los tipos de objetos de la BD, por ejemplo, crear una sesión, crear tablas, índices... hay hasta 60 privilegios del sistema. La vista DBA_SYS_PRIVS contiene los privilegios del sistema otorgados a usuarios y roles. La vista ROLE_SYS_PRIVS contiene los privilegios del sistema otorgados a roles. PRIVILEGIOS DE OBJETOS: son permisos para realizar acciones sobre objetos concretos de la BD. Los privilegios que un usuario puede otorgar a otros usuarios sobre objetos de su propiedad son: select: selecciona tablas. insert: inserta datos en tablas. update: actualiza tablas. delete: borrar. alter: permite alterar la estructura del objeto. index: permite incluir un índice. references: permite crear FK. 28 Case - execute: da permiso para ejecutar subprogramas. La sintaxis para conceder privilegios es: > GRANT {lista_privilegios|ALL[privileges]} [(columna1, {lista_usuarios|lista_roles|public} [with grant option]; columna2...)] on objeto to Donde lista_priviegios consiste en uno o más nombres de privilegios separados por comas. All privileges concede todos los privilegios sobre el objeto. columna1, columna2 especifican las columnas de la tabla sobre las que se concede los privilegios, sólo se pueden especificar para los privilegios insert, update y references. Objeto es el nombre de la tabla, vista u otro objeto sobre el que se otorga el privilegio. Lista_usuarios y lista_roles son los nombres de uno o mas usuarios o roles a los que se otorgan los privilegios. Si se especifica PUBLIC se otorgan los privilegios a todos los usuarios del sistema. La cláusula with grant option hace que los usuarios a los que se les conceden los privilegios puedan a su vez otorgarlos a otros usuarios. Para retirar privilegios se utiliza la sentencia REVOKE con el siguiente formato: > REVOKE {lista_privilegios|ALL[privileges]} on objeto from {lista_usuarios o roles |public} [cascade constraint]; La cláusula cascade constraint hace que si un usuario A concedió privilegios sobre un objeto a un usuario B y éste concedió privilegios sobre ese objeto a un usuario C, entonces al retirar los privilegios al usuario B se le retira también al usuario C. Las vistas del diccionario de datos asociadas a los privilegios son: USER, ALL_TAB_PRIVS, que contienen los privilegios sobre tablas en las que el usuario es otorgador, otorgado o propietario. La otra es USER, ALL_COL_PRIVS, que contiene los privilegios sobre columnas en las que el usuario es otorgador, otorgado o propietario. 8. CREACIÓN DE ROLES. Se puede crear un rol mediante la sentencia >CREATE ROLE nombre_rol; El rol se crea vacío y posteriormente se le concederán los privilegios mediante la sentencia >GRANT. Con la sentencia REVOKE se puede retirar privilegios que previamente se han concedido a un rol. Es posible conceder un rol a otro rol. ℘ VISTAS DEL DICCIONARIO DE DATOS ORIENTADA A ROLES℘ - USER_ROLE_PRIVS, que contiene los roles otorgados al usuario actual. DBA_ROLES, que contiene todos los roles que existen en la BD. DBA_SYS_PRIVS, que contiene los privilegios del sistema otorgado a los roles. ROLE_TAB_PRIVS, que contiene los privilegios sobre tablas otorgados a los roles. 9. CREACIÓN DE ÍNDICES. Se puede indexar una tabla en aquellas columnas que necesitan un acceso rápido. El SGBD ORACLE crea automáticamente índices cuando se establecen constraints de PK o UNIQUE. 29 Case El formato es: >CREATE INDEX [,columna[ASC|DESC]]...); nombre_indice ON nombre_tabla (columna[ASC|DESC] ℘VISTAS DEL DICCIONARIO DE DATOS ASOCIADAS A LOS ÍNDICES℘ - USER_INDEXES, que contiene los índices propiedad del usuario que consulta la vista. 10. CREACIÓN DE SINÓNIMOS. Los sinónimos son nombres alternativos que se pueden emplear para gestionar tablas y otros objetos como vistas, procedimientos, funciones, paquetes y otros sinónimos. La instrucción para crear un sinónimo es la siguiente: >CREATE [PUBLIC] SYNONYM nombre_sinonimo FOR nombre_objeto; Si se especifica la cláusula PUBLIC el sinónimo es accesible para todos los usuarios, si no se especifica sólo podrá ser reconocido por el usuario que lo creó. Los sinónimos pueden ser utilizados por las sentencias INSERT, UPDATE, SELECT, DELETE, GRANT y REVOKE. Los sinónimos proporcionan independencia para tratar los objetos ya que se puede acceder a objetos de otros propietarios o situados en BD’s remotas, sin necesidad de especificar el propietario al ir implícito en el nombre del sinónimo. Para borrar un sinónimo se utiliza: >DROP SYNONYM nombre_sinonimo; >DROP PUBLIC SYNONYM nombre_sinonimo; ℘VISTAS DEL DICCIONARIO DE DATOS ASOCIADAS A LOS SINÓNIMOS℘ - ALL_SYNONYMS, contiene todos los sinónimos accesibles por el usuario. Aquellos que tienen en la columna OWNER el valor PUBLIC son sinónimos públicos. USER_SYNONYMS, contiene los sinónimos privados accesibles por el usuario. 11. CREACIÓN DE VISTAS. Una vista define una tabla virtual basada en una o más tablas o vistas. Las vistas permiten organizar los datos de diferentes formas, de modo que los usuarios los ven desde diferentes perspectivas. Las vistas permiten restringir el acceso a los datos, haciendo que determinados usuarios accedan a las vistas que sólo contienen determinadas columnas y filas de las tablas reales. Desde el punto de vista del usuario no se encuentra diferencia entre tabla y vista. La diferencia entre tabla y vista es que en una vista no se almacenan los datos físicamente y en una vista a los usuarios se les presentan unos datos que son el resultados de una consulta sobre las tablas reales. 30 Case El formato simple para crear un vista es: >CREATE VIEW nombre_vista [(columna1 [,columna2]...)] AS consulta; Si se omiten los nombres de las columnas de la vista, especificadas entre paréntesis, las columnas de la vista tendrán los mismos nombres que las columnas de las tablas sobre las que se realiza la consulta. Las vistas también se pueden crear a través de una consulta con agrupamiento, y en este caso si hay que darle nombre a las columnas de la vista. También se pueden crear vistas de las columnas de varias tablas. La sentencia CREATE VIEW tiene dos cláusulas más, que son: - WITH CHECK OPTION: que obliga a que los datos modificados a través de la vista cumplan las condiciones de selección de la definición de la vista. WITH READ ONLY: no permite borrados, ni inserciones, ni actualizaciones sobre la vista. El formato completo sería: >CREATE VIEW nombre_vista [(columna1[,columna2]...)] AS consulta [WITH READ ONLY] [WITH CHECK OPTION]; 31 Case 32 Case T.5. USO DE SQL EN MODO INTERACTIVO. 1. 2. 3. 4. 5. 6. 7. 8. 9. CONSULTAS SENCILLAS. EXPRESIONES. PREDICADOS FUNCIONES DEL LENGUAJE SQL. CONSULTAS CON AGRUPAMIENTOS. CONSULTAS SOBRE VARIAS TABLAS. SENTENCIAS PARA MODIFICAR DATOS. OTRAS CARACTERÍSTICAS DE LA SENTENCIA SELECT. CONSULTAS COMPLEJAS EN SISTEMAS DE INFORMACIÓN COMPLEJOS. 1. CONSULTAS SENCILLAS. 1.1. Sentencia SELECT simplificada: es: El formato de la sentencia SELECT para realizar consultas sencillas sobre una sola tabla >SELECT {columna[,columna]...|*} FROM columna[ASC|DESC] [,columna[ASC|DESC]...; tabla [WHERE predicado] [ODER BY donde la lista de columnas de la cláusula SELECT son columnas de la tabla que se especifique en la cláusula FROM, y es la información resultante de la consulta. Si se especifica * es equivalente a sí se especifican todas las columnas de la tabla en el mismo orden que estuvieron en su proceso de creación. El predicado de la cláusula WHERE es una condición. En la cláusula ORDER BY se especifican las columnas por las que se presenta ordenado el resultado de la consulta. El resultado de ejecutar una sentencia SELECT es otra tabla. Los pasos que sigue el SGBD para ejecutar una sentencia SELECT son: DEPTO. [paso1=DEPTO.WORK] [paso 3,√] [paso 3,√] [paso 3,X] [paso 3,√] [paso 3,X] [paso 3,X] [paso 3,X] CODDE NOMDE [paso 2,√] 100 [paso 2,√] 110 [paso 2,X] 111 [paso 2,X] 112 [paso 2,√] 120 Dirección General Dirección Comercial Sección Técnica Sección Servicios Organi. CODCE CODJEFE TIDIR PRESU DEPDE 10 260 P 77344 - 20 180 P 94760 100 30 270 F 276364 100 20 180 F 56550 100 10 150 P 20733 112 33 Case >SELECT codde, nomde, codjefe, FROM depto WHERE tidir=’P’ ORDER BY nomde; 1. Ejecución de la cláusula FROM, que consiste en seleccionar de entre todas las tablas de la BD las tablas especificadas en la cláusula FROM, y ésta será la tabla resultante de la sentencia SELECT hasta este momento. 2. Ejecución de la cláusula WHERE, que aplica el predicado especificado en la cláusula WHERE a la tabla resultante del paso anterior, dejando las filas que cumplan la condición y suprimiendo las que no la cumplan. 3. Ejecución de la cláusula SELECT, que consiste en evaluar las condiciones contenidas en la cláusula SELECT y la opción DISTICT si existen. Además se retiran las columnas de la tabla no especificadas en la cláusula SELECT. 4. Ejecución de la cláusula ORDER BY, que consiste en presentar la tabla resultante del paso anterior ordenada por las columnas especificadas en la cláusula ORDER BY. ℘CARACTERÍSTICAS DE FUNCIONAMIENTO℘ Si no se especifica la cláusula ORDER BY, el SGBD presenta las filas en cualquier orden, que incluso puede variar de una ejecución a otra. En el caso concreto de ORACLE las presenta ordenadas por la PK. Cuando se especifica la cláusula ORDER BY los datos aparecen por defecto en orden ascendente, y si hay valores nulos se presentan al final de la lista. En la cláusula ORDER BY se puede especificar un número en lugar de un nombre de columna. Este número se refiere a la columna que aparece en la cláusula SELECT en el lugar indicado por el número. Si se desea una ordenación por orden decreciente se especifica la palabra DESC detrás de nombre de columna o del número en el que se desea la ordenación. La tabla resultante se puede ordenar por más de una columna. Para ello se especifican en la cláusula ORDER BY las columnas separadas por comas. Si en la cláusula SELECT se especifica en el lugar de una columna un literal entre comillas simples, éste literal aparecerá en todas las filas resultantes de la consulta. Se puede cambiar el encabezado de una columna en el resultado de la consulta poniendo el nuevo encabezado entre comillas dobles a continuación de la columna. Si el encabezado es una sola palabra no necesita comillas. 1.2. Eliminación de filas repetidas: En la cláusula SELECT se puede incluir la palabra reservada DISTINCT antes de todos los nombres de las columnas: >SELECT DISTINCT columna1, columna2...; Esto implica que en el resultado de la consulta no pueden aparecer filas repetidas, que serán eliminadas por el SGBD antes de enviarlas a la tabla resultante. 34 Case 2. EXPRESIONES. En la formulación de una consulta se pueden realizar operaciones con los datos. Estas operaciones se especifican mediante expresiones. Una expresión es una combinación de operadores operandos y paréntesis, que el SGBD cuando las ejecuta devuelve como resultado un único valor resultante de evaluar la expresión. Los operadores pueden ser nombres de columnas, constantes u otras expresiones. Los operadores actúan sobre datos del mismo tipo; los operandos pueden ser numéricos o alfanuméricos. Las operaciones pueden aparecer en dos sitios: • • En la cláusula SELECT, donde las expresiones aparecen en el lugar donde se especifican los nombres de columna. En la cláusula WHERE, donde uno o ambos de los valores a comparar pueden ser una expresión. 3. PREDICADOS. Un predicado expresa una condición entre valores y el resultado de la condición puede ser verdadero, falso o desconocido. Los predicados se expresan en las cláusulas WHERE y HAVING. Un predicado en la cláusula WHERE da lugar a que se seleccionen todas aquellas filas que se evalúen con el valor verdadero, y no serán seleccionadas las que se evalúen con el valor falso o desconocido. Un predicado tiene resultado desconocido cuando en alguno de los elementos de la comparación tiene nulos. Los predicados se clasifican en 2 grupos: 3.1. Simples: Se subdividen en predicados básicas, null, cuantificados (all, any, some), between, like, in, exist. 3.1.1. Básicos: Son predicados que expresan condición de comparación entre dos valores. Se especifican con los operadores relacionales < > = != <> <= >=. Los elementos comparados son expresiones. El segundo elemento comparado puede ser el resultado de otra sentencia SELECT, la cual ha de ir entre paréntesis. A esta SELECT subordinada se la denomina SUBSELECT o SUBCONSULTA. El resultado de la subconsulta ha de ser un valor único, es decir, la tabla resultante ha de tener una sola columna y una o ninguna fila. 3.1.2. Nulos: Su formato es: nombre_columna IS [NOT] NULL. Sirve para preguntar si el valor contenido en una columna de una fila determinada es o no nulo y el predicado se evaluará a los valores verdadero o falso. Este predicado NO puede tener valor desconocido. 3.1.3. Cuantificados: En un predicado básico se utiliza una subconsulta como segundo elemento del predicado. La tabla debe tener una sola columna y una sola fila o ninguna. Si se utilizan los predicados cuantificados (all, some, any) la tabla resultante de la columna podrá tener una columna y ninguna, una o varias filas. 35 Case • ALL: el predicado cuantificado se evalúa verdadero si la comparación es verdadera para todos y cada uno de los valores resultantes de la subconsulta. • SOME: se evaluará a verdadero si la comparación es verdadera para al menos uno de los valores resultantes de la subconsulta. • ANY: es igual que some. ℘CASOS ESPECIALES DE LOS PREDICADOS ALL Y SOME℘ Por convenio se evalúan de la siguiente manera: - Si se especifica ALL y la subconsulta devuelve una tabla vacía el predicado toma el valor verdadero. Si se especifica SOME y la subconsulta devuelve una tabla vacía, el predicado toma valor falso. 3.1.4. Predicado BETWEEN: Sirve para determinar si un valor está comprendido entre otros dos valores, ambos inclusive. Su formato es: >Expresión1 [NOT] BETWEEN expresión2 AND expresión3. El predicado se evalúa verdadero si el valor de expresión1 es mayor o igual que el valor de expresión2 menor o igual que el valor de expresión3. El predicado se evalúa falso en caso contrario. Si la evaluación de la expresión1, expresión2 o expresión3 es nula entonces el predicado se evalúa desconocido. Este predicado se puede expresar también mediante operadores lógicos: >expresión1 BETWEEN expresión2 AND expresión3 ! >exp1>=exp2 AND exp1<=exp3 >expresión1 NOT BETWEEN expresión2 AND expresión3! >exp1<exp2 OR exp1>exp3 3.1.5. Predicado LIKE: Sirve para seleccionar valores que se ajusten a un patrón. Su formato es: >nombre_columna [NOT] LIKE ‘patrón’. La columna ha de ser de tipo alfanumérico. El patrón es una constante que puede contener cualquier cadena de caracteres, pero hay dos caracteres que funcionan como comodín: ‘%’ y ‘_’. El ‘_’ equivale a una cadena de caracteres de longitud 1, mientras que el ‘%’ equivale a una cadena de caracteres de cualquier tamaño, incluido 0 caracteres. Si el patrón no contiene caracteres comodines, entonces el valor de la columna para que la fila sea seleccionada ha de ser igual que el patrón. 36 Case 3.1.6. Predicado IN: Sirven para preguntar si el resultado de una expresión está incluido en una lista de valores. Tiene dos formatos: - Formato 1: >expresión [NOT] IN (constante1[,constante2]...) Si el valor de la expresión es igual a alguno de los valores de la lista, el predicado se evalúa como verdadero. Si el valor de la expresión no es igual a ninguno de los valores de la lista se evalúa como falso. Si el valor de la expresión es nulo, el predicado se evalúa como desconocido. Existe otro formato en el que en lugar de una lista de constantes se puede especificar una subconsulta que devuelva una tabla con una sola columna. - Formato 2: >expresión [NOT] IN (subconsulta) Este segundo formato tiene sus equivalentes con los predicados cuantificados. Así ‘expresión IN (subconsulta)’ ! ‘expresión = some(subconsulta)’ 3.1.7. Predicado EXISTS: Sirve para determinar si existen filas o no existe ninguna fila que cumplan con un determinado requerimiento. Su formato es: >[NOT] EXISTS (subconsulta) La tabla resultante de la subconsulta puede contener cualquier número de filas y columnas. Este predicado se evalúa verdadero si el resultado de la subconsulta es una tabla que contiene una o más filas, es decir, si no es una tabla vacía. El predicado se evalúa a falso si la tabla resultante de la subconsulta es una tabla vacía. Este predicado no puede tomar el valor desconocido. 3.2. Compuestos: Son los predicados simples vistos hasta ahora combinados con los operadores lógicos AND, OR y NOT. Un predicado compuesto se evalúa a verdadero, falso o desconocido según la siguiente tabla de verdad. 37 Case PREDICADO X PREDICADO Y X AND Y X OR Y V V V V V F F V V D D V F V F V F F F F F D F D D V D V D F F D D D D D PREDICADO X NOT X V F F V D D 4. FUNCIONES DEL LENGUAJE SQL. 4.1. Definición de función: Una función representa un valor único que se obtiene aplicando unas determinadas operaciones a unos valores llamados argumentos. Una función se especifica mediante una palabra reservada, que es el nombre de la función, seguida de los argumentos entre paréntesis y separados por comas. El argumento de una función puede ser una expresión. Las funciones a su vez pueden ser operandos de una función. [(max(salar)+min(salar))/2]. En SQL hay dos tipos de funciones: escalares y colectivas o de columna. En una función escalar el argumento es un único valor. En las funciones colectivas el argumento es una columna. Por lo tanto la función se aplica a un conjunto de valores. 4.2. Funciones escalares: 4.2.1. Función LENGTH: Obtiene la longitud de una cadena de caracteres. Su formato es: >LENGTH (expresión). El argumento es una expresión cuyo resultado ha de ser de tipo alfanumérico. El resultado de la función es un entero que indica el número de caracteres que tiene la cadena pasada como argumento. Si el argumento es nulo, el resultado de la función es nulo. 38 Case 4.2.2. Función SUBSTR: Obtiene una subcadena de caracteres de una cadena de caracteres. Su formato es: >SUBSTR(expresion1,expresion2[,expresion3]); El primer argumento es la cadena de caracteres de la que se va a extraer la subcadena. El segundo argumento es un valor entero que indica la posición inicial de la subcadena dentro de la cadena. El tercer argumento es un valor entero que indica la longitud de la subcadena. Si este argumento no se especifica la subcadena será desde la posición inicial indicada en el segundo argumento hasta el final de la cadena. Si alguno de los argumentos de la función es nulo, el resultado de la función es nulo. 4.3. Funciones de columnas o colectivas: Estas funciones devuelven un único valor como resultado de aplicar una determinada operación a los valores contenidos en una columna, por ejemplo, la suma de todos los valores de una columna o la media aritmética. El argumento de estas funciones es un conjunto de valores tomados de una o más columnas: ‘sum(salar)’ o ‘sum(salar+comis)’, por ejemplo. Las funciones colectivas son: AVG, MAX, MIN, SUM, COUNT. - AVG: calcula la media aritmética de un conjunto de valores. MAX: obtiene el valor máximo de un conjunto de valores. MIN: obtiene el valor mínimo de un conjunto de valores. SUM: obtiene la suma de un conjunto de valores. COUNT: obtiene cuantos valores hay en una colección. El argumento de la función puede ser una expresión: ‘sum(salar)’ o ‘sum(salar+comis)’ por ejemplo. Las funciones pueden actuar como operandos de una expresión: ‘(max(salar)+min(salar))/2’ por ejemplo. Estas funciones sólo aparecen en las cláusulas SELECT y HAVING. Los valores a los que se aplica son a las columnas de las filas seleccionadas en la cláusula WHERE. Si se hacen grupos mediante la cláusula GROUP BY se aplica la función a cada grupo. Si no hay cláusula GROUP BY, todas las filas se consideran como un único grupo, y el resultado de la sentencia SELECT es una tabla con una única fila.ℑ ℘REGLAS Y FORMATOS DE LAS FUNCIONES COLECTIVAS℘ 1. Antes de aplicar una función colectiva al conjunto de valores de su argumento se eliminan los valores nulos. 2. Si el conjunto de valores es vacío la función COUNT da como resultado 0 y las otras funciones dan como resultado NULL. Que el conjunto de valores sea vacío puede ser, por ejemplo, si el resultado de la cláusula WHERE no lo satisface ninguna fila. 3. Para las funciones AVG, MAX, MIN, SUM el resultado tiene el mismo tipo de datos que el argumento. El tipo de argumento debe ser numérico para las funciones AVG y SUM y pueden ser de cualquier tipo para las funciones MAX, MIN y COUNT. ℑ Cuando se especifican funciones colectivas en la cláusula SELECT no se puede incluir en el resultado valores no colectivos, pues carecería de valor para el SGBD. 39 Case ℘FORMATOS DE LAS FUNCIONES COLECTIVAS℘ Las funciones colectivas tienen dos posibles formatos: 1. nombre_funcion ([DISTINCT] expresion): este formato es aplicable a las cinco funciones. La palabra DISTINCT indica que antes de aplicar la función al conjunto de valores de la columna se eliminan los valores repetidos. Como por ejemplo ‘sum(DISTINCT comis)’, ‘avg(salar+comis)’ o ‘max(nomem)’. 2. COUNT(*): sólo es válido para la función COUNT. Devuelve como resultado el número de filas que hay al grupo que aplica. 5. CONSULTAS CON AGRUPAMIENTO DE FILAS. En este punto se verá como formar grupos de filas de acuerdo con un determinado criterio para aplicarle posteriormente las funciones colectivas. 5.1. Cláusula GROUP BY: Esta cláusula de la sentencia SELECT sirve para agrupar filas. Aparece a continuación de la cláusula WHERE si esta existe. Su formato es: >GROUP BY columna1 [,columna2]... donde columna1 y columna2 son nombres de columnas y por aparecer en la cláusula GROUP BY se las denomina columnas de agrupamiento. La cláusula GROUP BY especifica que se ha de agrupar las filas de una tabla en grupos. Cada grupo está formado por el conjunto de filas que tienen el mismo valor en las columnas de agrupamiento. Los valores nulos en las columnas de agrupamiento se incluyen en el mismo grupo. Una vez formados los grupos, para cada uno de ellos se evalúan las expresiones de la cláusula SELECT. Por cada grupo se produce una fila en la tabla final resultante de la sentencia SELECT. En la cláusula SELECT sólo pueden aparecer columnas de agrupamiento y columnas que no sean de agrupamiento pero como argumento de funciones de columnas. 5.2. Cláusula HAVING: Esta cláusula se utiliza para seleccionar grupos de filas. Su formato es: >HAVING condición. La cláusula aparece a continuación de la cláusula GROUP BY. La cláusula GROUP BY agrupa las filas de la tabla en grupos; la cláusula HAVING selecciona entre los grupos formados por la cláusula GROUP BY aquellos grupos que cumplen una condición. La condición es un predicado simple o compuesto. En el predicado de la cláusula HAVING sólo puede aparecer columnas de agrupamiento y columnas que no sean de agrupamiento pero como argumento de funciones colectivas. Las funciones de columna que se especifican en la cláusula HAVING se aplican a los valores de cada grupo. 40 Case 5.3. Sentencia SELECT por agrupamiento: Recopilación de las reglas de agrupamiento de filas: 1. Se hace agrupamiento cuando se especifica la cláusula GROUP BY o se usan funciones de columna o ambas cosas, como por ejemplo ‘select sum(salar) from emple’, ‘select sum(salar) from emple group by codde’ o ‘select codde from emple group by codde having count(*)>2’. 2. Si se especifica la cláusula GROUP BY se agrupan las filas que tengan iguales valores en las columnas de agrupamiento. Si no se especifica GROUP BY todas las filas forman un grupo. Una vez formados los grupos se seleccionan los grupos que cumplen las condiciones de la cláusula HAVING. Para cada grupo seleccionado se evalúan las expresiones de la cláusula SELECT, dando como resultado una fila por cada grupo. 3. Las columnas que no sean de agrupamiento solo pueden usarse como argumentos de funciones de columna tanto en la cláusula SELECT como en la condición de la cláusula HAVING. Si se utiliza una sentencia SELECT formada por cláusulas SELECT, FROM, WHERE, GROUP BY, HAVING, y ORDER BY los pasos que sigue el SGBD para obtener el resultado son: Ex: Para cada departamento que tenga más de dos empleados con hijos, obtener el salario máximo y el salario mínimo de aquellos empleados que tienen hijos. Presentarlo ordenado por código de departamento. >SELECT codde, max(salar), min(salar) FROM emple WHERE numhi>0 GROUP BY codde HAVING count(*)>2 ORDER BY codde; EMPLEADO codem salar numhi codde 1 1200 3 20 2 1300 2 20 3 1350 0 20 4 1100 1 20 5 1200 1 10 6 1150 2 10 7 1200 2 10 8 1150 0 30 9 1250 1 30 10 1300 3 30 11 1100 2 40 41 Case Los pasos del SGBD son: 1. Ejecución de la cláusula FROM, que consiste en seleccionar la tabla especificada en esta cláusula que de momento pasa a ser la tabla resultante de la sentencia. 2. Ejecución de la cláusula WHERE que consiste en eliminar de la tabla resultante las filas que no satisfagan la condición especificada en esta cláusula. 3. Ejecución de la cláusula GROUP BY, que consiste en formar grupos con las filas de la tabla resultante del paso anterior que tengan iguales valores en las columnas de agrupamiento. 4. Ejecución de la cláusula HAVING, que consiste en eliminar los grupos que no satisfagan la condición especificada en esta cláusula.ℑ 5. Ejecución de la cláusula SELECT, que consiste en evaluar las expresiones especificadas en esta cláusula para cada uno de los grupos seleccionados en el paso anterior. El resultado es una tabla en la que aparecen una fila por cada grupo y tantas columnas como expresiones aparezcan en la cláusula SELECT. Si aparece la palabra DISTINCT se eliminaran de la tabla resultante las filas repetidas. 6. Ejecución de la cláusula ORDER BY, que consiste en ordenar la tabla resultante del paso anterior por los criterios especificados en la cláusula ORDER BY. codem salar numhi codde 1 1200 3 20 2 1300 2 20 3 1350 0 20 4 1100 1 20 5 1200 1 10 6 1150 2 10 7 1200 2 10 8 1150 0 30 9 1250 1 30 10 1300 3 30 11 1100 2 40 3 2 3 2 4 4 3 4 3 TABLA RESULTANTE [paso 5] [paso 6] codde max(salar) min(salar) 10 1200 1150 20 1300 1100 ℑ Cuando la condición del HAVING tiene la columna de agrupamiento en su condición de selección, entonces esta condición de selección se puede expresar en la cláusula HAVING o en la cláusula WHERE. 42 Case 6. CONSULTAS SOBRE VARIAS TABLAS. Para consultar datos de varias tablas en una sentencia SELECT se puede realizar de 3 formas: 1. Poniendo los nombres de las distintas tablas en la cláusula FROM de la SELECT principal, con lo que se obtiene como resultado datos combinados de las distintas tablas que intervienen en la consulta, mediante una operación llamada JOIN o YUNCIÓN. >SELECT nomde, nomem FROM emple, depto WHERE emple.codde= depto.codde; 2. Utilizando subconsultas en las que no se hace referencia a datos de las tablas mencionadas en la SELECT principal. A este tipo de consultas se las denomina consultas subordinadas no correlacionales. . >SELECT nomem FROM emple WHERE codde in (select codde from depto where presu>100.000); 3. Utilizando subconsultas en las que se hace referencia a datos de tablas mencionadas en una SELECT antecedente. A este tipo de consultas se las llama consultas subordinadas correlacionadas. . >SELECT nomde FROM depto WHERE presu*2>(select sum(salar) from emple where codde=depto.codde); 6.1. Consultas con JOIN o YUNCIÓN: 6.1.1. Conceptos previos: 6.1.1.1. Calificación de columnas: Dentro de una tabla todos los nombres de columnas son diferentes. En una sentencia SELECT, cuando se opera con una sola tabla basta con especificar el nombre de la columna y no hay ningún tipo de ambigüedad. Sin embargo, si interviene más de una tabla en la misma sentencia puede ocurrir que haya columnas con el mismo nombre en distintas tablas. En este caso no basta con especificar una columna únicamente por su nombre, pues se da la ambigüedad de que no se sabe a qué columna de qué tabla nos estamos refiriendo. En estos casos, para eliminar la ambigüedad, lo que se hace es calificar las columnas especificando el nombre de la tabla a la que pertenecen, un punto, y el nombre de la columna (tabla.columna). 6.1.1.2. Alias para tablas: En la cláusula FROM de una sentencia SELECT se pueden especificar alias para los nombres de las tablas, que son nombres alternativos para referirse a la tabla dentro de la misma sentencia SELECT. La forma de definir un alias es poniendo en la cláusula FROM a continuación del nombre de la tabla el nombre del alias. Si se especifica un alias a una tabla, todas las referencias calificadas a sus columnas deben usar el nombre alias. >SELECT d.codde, nomde,nomem FROM emple e, depto d WHERE e.codde=d.codde; 43 Case Los nombres alias se utilizan por dos razones: 1. Por comodidad, para utilizar unos nombres de tablas más cortos y más mnemotécnicos. 2. Una tabla puede especificarse más de una vez en la cláusula FROM de una misma sentencia SELECT. En este caso es obligatorio utilizar nombres alias. >SELECT ------------------- FROM emple e1, emple [e2] ------------; 6.1.1.3. Producto cartesiano: Si una sentencia SELECT utiliza varias tablas, entonces los nombres de las tablas se han de especificar en la cláusula FROM separados por comas. Cuando el sistema ejecuta la cláusula FROM genera una tabla que es el resultado del producto cartesiano de las tablas especificadas, es decir, en la tabla resultante el número de columnas es igual a la suma del número de columnas de las tablas especificadas, y el número de filas es el producto del número de filas de las tablas especificadas. La tabla resultante es donde se aplican el resto de las cláusulas de la sentencia SELECT (WHERE, GROUP BY, HAVING, SELECT, ORDER BY). CENTROS DEPTO codce nomce codde nomde codce 100 C1 10 D1 100 200 C2 20 D2 100 30 D3 200 40 D4 200 >SELECT * FROM depto d, centro c; d.codde d.nomde d.codce c.codce c.nomce 10 D1 100 100 C1 10 D1 100 200 C2 20 D2 100 100 C1 20 D2 100 200 C2 30 D3 200 100 C1 30 D3 200 200 C2 40 D4 200 100 C1 40 D4 200 200 C2 44 Case 6.1.2. Operación JOIN: En la teoría de BD’s relacionales, y concretamente en el álgebra relacional orientada a tuplas se define una operación llamada JOIN NATURAL, que se utiliza para relacionar datos de distintas tablas. En SQL la operación join natural se realiza en la sentencia SELECT utilizando las cláusulas FROM y WHERE. >SELECT * FROM depto, centro WHERE depto.codde=centro.codce; d.codde d.nomde d.codce c.codce c.nomce 10 D1 100 100 C1 10 D1 100 200 C2 20 D2 100 100 C1 20 D2 100 200 C2 30 D3 200 100 C1 30 D3 200 200 C2 40 D4 200 100 C1 40 D4 200 200 C2 En la cláusula WHERE debe haber por lo menos n-1 condiciones de JOIN, donde n es el número de tablas especificadas en la cláusula FROM. 6.1.3. Ejecución de la sentencia con JOIN: >SELECT nomde, count(*) FROM emple e, depto d WHERE e.codde=d.codde AND presu>50000 GROUP BY nomde HAVING max(salar)>1500 ORDER BY nomde desc; EMPLE codem nomem salar codde 1 E1 1600 10 2 E2 900 10 3 E3 1000 20 4 E4 1700 30 5 E5 1700 40 45 Case DEPTO codde nomde presu tidir codjefe 10 D1 55000 F 2 20 D2 70000 P 1 30 D3 60000 F 1 40 D4 45000 F 3 Los pasos que sigue el SGBD para ejecutar una sentencia SELECT con JOIN son: 1. Ejecución de la cláusula FROM, donde forma una tabla con el producto cartesiano de las tablas especificadas en la cláusula FROM. e.codem e.nomem 1 E1 1 E1 1 E1 1 E1 2 E2 2 E2 2 E2 2 E2 3 E3 3 E3 3 E3 3 E3 4 E4 4 E4 4 E4 4 E4 5 E5 5 E5 5 E5 5 E5 e.salar 1600 1600 1600 1600 900 900 900 900 1000 1000 1000 1000 1700 1700 1700 1700 1700 1700 1700 1700 e.codde 10 10 10 10 10 10 10 10 20 20 20 20 30 30 30 30 40 40 40 40 d.codde 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 d.nomde D1 D2 D3 D4 D1 D2 D3 D4 D1 D2 D3 D4 D1 D2 D3 D4 D1 D2 D3 D4 d.presu 55000 70000 60000 45000 55000 70000 60000 45000 55000 70000 60000 45000 55000 70000 60000 45000 55000 70000 60000 45000 d.tidir F P F F F P F F F P F F F P F F F P F F d.codjefe 2 1 1 3 2 1 1 3 2 1 1 3 2 1 1 3 2 1 1 3 2. Ejecución de la cláusula WHERE, donde se aplican las condiciones especificadas en la cláusula WHERE a la tabla resultante del paso anterior, eliminando las filas que no satisfagan la condición. e.codem e.nomem 1 E1 2 E2 3 E3 4 E4 e.salar 1600 900 1000 1700 e.codde 10 10 20 30 d.codde 10 10 20 30 d.nomde D1 D1 D2 D3 d.presu 55000 55000 70000 60000 d.tidir F F P F d.codjefe 2 2 1 1 46 Case - Después de hacer el JOIN hay tantas filas como filas tenga la tabla que contiene la última clave ajena relacionada. En cada fila viene toda la información del empleado y toda la información del departamento al que está asignado. Si varios empleados trabajan en el mismo departamento toda la información del departamento viene repetida por cada uno de los empleados que tiene asignado. 3. Ejecución de la cláusula GROUP BY, que consiste en formar grupos con las filas de la tabla resultante de paso anterior de manera que cada grupo tenga los mismos valores en la columna de agrupamiento. e.codem e.nomem 1 E1 2 E2 3 E3 4 E4 e.salar 1600 900 1000 1700 e.codde 10 10 20 30 d.codde 10 10 20 30 d.nomde D1 D1 D2 D3 d.presu 55000 55000 70000 60000 d.tidir F F P F d.codjefe 2 2 1 1 4. Ejecución de la cláusula HAVING, que consiste en eliminar de los grupos formados en el paso anterior los que no satisfagan la condición expresada en esta cláusula. e.codem e.nomem 1 E1 2 E2 4 E4 e.salar 1600 900 1700 e.codde 10 10 30 d.codde 10 10 30 d.nomde D1 D1 D3 d.presu 55000 55000 60000 d.tidir F F F d.codjefe 2 2 1 5. Ejecución de la cláusula SELECT, que consiste en obtener una fila de cada grupo de los que quedan del paso anterior. Cada fila tendrá los valores resultantes de calcular las expresiones incluidas en la cláusula SELECT. Con todas las filas obtenidas se forma la tabla resultante de la sentencia SELECT. 6. Ejecución de la cláusula ORDER BY, que consiste en presentar la tabla resultante del paso anterior ordenada por los criterios especificados en la cláusula ORDER BY. nomde D3 D1 Count(*) 1 2 6.2.Consultas Subordinadas NO Correlacionales: Una sentencia SELECT puede tener en sus predicados otras sentencias SELECT con la función de subconsulta. A estas sentencias SELECT se las denomina sentencia SELECT o consulta SUBORDINADA. Las consultas subordinadas se pueden especificar en las cláusulas WHERE y HAVING, como parte de uno de los siguientes predicados: 1. Predicado básico de comparación: >SELECT nomem FROM emple WHERE salar>(select avg(salar) from emple); 47 Case 2. Predicados cuantificados: >SELECT nomem FROM emple WHERE nvl(comis,0)>=all (select nvl(comis,0) from emple); 3. Predicado IN: >SELECT nomem FROM emple WHERE codem IN (select codjefe from depto where tidir=’P’); 4. Predicado EXISTS: >SELECT nomem FROM emple WHERE EXISTS (select * from emple where salar>1800); Una sentencia subordinada de otra puede a su vez tener otras subordinadas a ella: >SELECT --------- FROM ------------- WHERE (select ------ from ---------- where (select --------- from ----------------- where ------------))); Se llama sentencia externa a la primera sentencia SELECT de todas, es decir, la que no es subordinada de ninguna otra. Puede haber hasta 50 niveles de anidamiento de la sentencia SELECT. La sentencia externa puede ser en lugar de SELECT algunas de las sentencias DELETE, UPDATE o INSERT. Cuando hay sentencias anidadas diremos que una sentencia es antecedente de ésta cuando ésta es su subordinada directa o subordinada de su subordinada a cualquier nivel. 6.3.Consultas Subordinadas Correlacionadas: En las consultas subordinadas vistas hasta el momento sólo se hacía referencia a columnas de tablas que estén en su propia cláusula FROM. Esto implica que le resultado de la consulta subordinada puede evaluarse independientemente de sus sentencias antecedentes. Por lo tanto el SGBD evalúa la consulta subordinada una sola vez y reemplaza los valores resultantes de la consulta en el predicado en el que se encuentra. Sin embargo, en las sentencias correlacionadas, en la consulta subordinada se especifica alguna columna de alguna tabla especificada en la cláusula FROM de alguna de sus sentencias antecedentes. Una sentencia subordinada correlacionada no puede evaluarse independientemente de las sentencias antecedentes, pues su resultado cambia según la fila de la sentencia antecedente que se evalúe en cada momento. Por lo tanto el SGBD evalúa la sentencia subordinada múltiples veces. Cuando en una sentencia subordinada se especifica un nombre de columna sin calificar se interpreta que se refiere a la primera tabla que conteniendo una columna con este nombre se encuentre a buscar en el siguiente orden: - En las tablas de su propia cláusula FROM. - En la sentencia antecedente inmediata. - En la sentencia antecedente de siguiente nivel superior... y así hasta llegar hasta la sentencia externa. 48 Case 7. SENTENCIAS PARA MODIFICAR DATOS. Estas sentencias son INSERT, DELETE y UPDATE. 7.1. Sentencia INSERT: La sentencia INSERT permite añadir una o más filas completas a una tabla. Puede especificarse con dos formatos: - Formato 1: >INSERT INTO tabla[(col1,col2,...)] VALUES (valor1,valor2...) donde tabla es el nombre de la tabla en la que se desea insertar, col1, col2... es una lista de nombres de columnas de esta tabla (no necesariamente todas las columnas de la tabla ni en el mismo orden en que se han definido en la BD); si se omiten, el sistema lo interpreta como si se especificara una lista en la que se incluye todas las columnas de la tabla en el mismo orden en que aparecen en la definición de la tabla. Valor1, valor2... pueden ser constantes, la palabra NULL o bien variables de programa (si se está en modo programación) y debe haber tantos valores como en la lista anterior nombres de columnas. Este formato permite insertar una fila completa y solo una por cada sentencia, donde el primer valor de la lista se asigna a la primera columna, el segundo valor a la segunda columna, etc.. Si en la lista de columnas no se especifica alguna columna que permita valores nulos, al insertar la fila el sistema asigna nulo a esta columna. - Formato 2: >INSERT INTO tabla [(col1,col2,...)] subconsulta; En este formato todas las filas que resulten de ejecutar la subconsulta se insertan en la tabla. Por tanto, este formato de INSERT permite insertar con una sola sentencia una o varias filas. El número de columnas del resultado de la subconsulta debe ser igual al número de nombres de columnas especificado en las lista de columnas, asignándole el valor de la primera de ellas a la primera columnas de la lista, la segunda a la segunda, etc.. 7.2. Sentencia DELETE: La sentencia DELETE permite borrar filas de una tabla. Su formato es: >DELETE FROM tabla WHERE predicado; donde tabla es el nombre de la tabla en la que se quiere borrar filas, predicado es un predicado que puede contener subconsultas subordinadas. La sentencia DELETE borra todas las filas que cumplan la condición expresada en la cláusula WHERE. Si se omite la cláusula WHERE borra todas las filas de la tabla. 49 Case 7.3. Sentencia UPDATE: La sentencia UPDATE permite modificar o actualizar varias filas de una tabla. Se puede modificar algunas columnas o todas las columnas de la tabla. Su formato es: >UPDATE tabla SET columna1=expresion1 [,columna2=expresion2]... [WHERE predicado]; donde tabla es el nombre de la tabla que se quiere actualizar, las expresiones de la cláusula SET se evalúan y su valor se asigna a las columnas indicadas. En las expresiones se puede hacer referencia a las columnas de la fila que actualmente se modifica. En el lugar de una expresión se puede especificar una subconsulta. Esta subconsulta debe devolver un valor único. En las expresiones no se pueden utilizar funciones colectivas, aunque sí en las subconsultas. La sentencia UPDATE actualiza todas las filas de la tabla que cumplen la condición expresada en el predicado de la cláusula WHERE. Si se omite la cláusula WHERE se actualizan todas las filas de la tabla. 8. OTRAS CARACTERÍSTICAS DE LA SENTENCIA SELECT. 8.1. OUTER JOIN o JOIN EXTERNO: Un JOIN EXTERNO se realiza cuando se incluye en el resultado de una SELECT filas de una tabla que no están relacionadas con ninguna fila de la tabla con la que se relaciona, es decir, que la columna tiene una restricción de integridad referencial pero tiene el valor NULL. El JOIN EXTERNO se especifica con un “(+)” en ORACLE, a continuación de la columna en el predicado con el que se implementa el JOIN. El JOIN EXTERNO puede ser JOIN externo a izquierda o JOIN externo a derecha. - JOIN externo a izquierda: >SELECT nomde, nomce FROM depto, centro WHERE depto.codce(+)=centro.codce; Con esto se obtendría los departamentos que están relacionados y los centros que están relacionados o no. - JOIN externo a derecha: >SELECT nomde, nomce FROM depto, centro WHERE depto.codce=centro.codce(+); Con esto se obtienen todos los departamentos relacionados o no y los centros relacionados. NO SE PUEDEN INCLUIR JOIN’s EXTERNOS A IZQUIERDA Y DERECHA A LA VEZ!!!! Si se desea realizarlo ha de ser mediante el operador UNION. >SELECT nomde, nomce FROM depto d, centro c WHERE d.codce=c.codce(+) UNION SELECT nomde, nomce FROM depto d, centro c WHERE d.codce(+)=c.codce; 50 Case 8.2. Operadores de conjuntos: UNIÓN, INTERSECCIÓN y DIFERENCIA: Se pueden formular consultas en las que aparezcan más de una sentencia SELECT, lo que se denomina consultas compuestas, utilizando los operadores de conjuntos UNIÓN, INTERSECCIÓN y DIFERENCIA. Cada sentencia SELECT daría como resultado una tabla, después se combinan estas tablas de acuerdo con el operador de conjuntos obteniéndose como resultado de la consulta compuesta una única tabla. Las expresiones que aparecen en las cláusulas SELECT han de ser iguales en número y tipo en todas las sentencias SELECT y en el mismo orden. Los operadores son: - UNIÓN: selecciona las filas de las tablas resultantes de las consultas combinadas, eliminando las filas duplicadas. UNION ALL: selecciona las filas de las tablas resultantes de las SELECT combinadas sin eliminar las filas duplicadas. INTERSECT: selecciona las filas que aparezcan en todas las tablas resultantes de las SELECT combinadas, es decir, la intersección. MINUS: selecciona las filas que pertenezcan a la primera tabla, pero no a la segunda. 8.3. Subconsultas de la cláusula FROM: Se pueden especificar subconsultas en la cláusula FROM de una SELECT en lugar de un nombre de tabla. La subconsulta especificada en la cláusula FROM está definiendo una vista, por tanto la SELECT principal hace la consulta sobre una vista. >SELECT nomde FROM (select * from depto) WHERE tidir=’F’; >SELECT nomde, nomce FROM (select * from depto) A, (select * from centro) B WHERE A.codce=B.codce; >SELECT max(total) FROM (select nomde, sum(salar) total from emple e, depto d where e.codde=d.codde group by codde); 8.4. Comparación simultánea de varias columnas en la cláusula WHERE: >SELECT nomem FROM emple WHERE (codde,codem)=some (select codde, codjefe from depto where tidir=’F’); 51 Case 52 Case Apéndices 53 Case 54 APENDICE TEMA 3. CASE 5. TIPOS DE DATOS 5.1 Insertar una fila con el valor ‘10-01-2002/13:54:32’ >INSERT into prueba values(3,to_date(‘10-01-2002/13:54:32’,’dd-mm-yyyy/hh:mi:ss’)); 5.2. Insertar una fila con la fecha del sistema. >INSERT into prueba values(4, to_date(sysdate,’dd-mm-yyyy’)); 5.3.Seleccionar los registros que se han insertado en la fecha de hoy. >SELECT * FROM prueba WHERE to_char(fecha)=to_char(sysdate, ’dd-mm-yyyy’); 5.4. Seleccionar los registros insertados en el presente mes >SELECT * FROM prueba WHERE to_char(fecha,’mm’)=to_char(sysdate,’mm’); 5.5. Obtener la fecha completa de todos los registros que se hayan insertado a partir de las 11 am. >SELECT orden, to_char(fecha,’dd-mm-yyyy/hh24:mi:ss’) FROM prueba WHERE to_char(fecha,’hh24’)>=11; 5.6. Dar la fecha y la hora 10 minutos antes del momento actual. >SELECT to_char(sysdate – 10/1440, ‘dd-mm-yyyy/hh:mi:ss’) from dual; 5.7. Calcular el número de días que he vivido. >SELECT sysdate - to_date(‘02-08-1981’,’dd-mm-yyyy’) from dual; 6. FUNCIONES 6.1. Visualizar la fecha del sistema con el formato: “Alcorcón a 4 de Octubre de 2002”. >SELECT Lpad(to_char(sysdate,’ ”En Alcorcón a “ dd “ de “ month “ de “ yyyy ’),50) from dual; 55 APENDICE TEMA 3. CASE 56 APENDICE TEMA 4. CASE 4. CREACIÓN DE UNA TABLA 4.1Crear una tabla videoclub con los siguientes campos: - Genero(codgen[PK CHAR(3)], dengen[UN y NN VARCHAR2]) - Socio (codsocio[PK NUMBER], nomsocio [NN VARCHAR2], direccion [NN], telefono) - Pelicula (codpel[PK NUMBER], titulo[NN], codgen[NN,FK], Duracion, Director, Precio_alquiler[NN]) - Copia (codpel[FK, PK], numcopia[PK], fecha_adquisicion[NN, DEFAULT sysdate] - Alquiler (codpel[FK*], numcop[FK* **]codsocio [FK**], fecha_alquiler[**PK,NN, DEFAULT sysdate], pagado[CHK(‘S’, ‘N’) DEFAULT ‘N’) >CREATE TABLE genero(codgenero char(3) constraint pk_genero primary key, dengenero varchar2(20) constraint nn_genero_dengenero not null constraint un_genero_dengenero unique); >CREATE TABLE socio(codsocio number(5) constraint pk_socio primary key, nomsocio varchar2(50) constraint nn_socio_nomsocio not null, direccion varchar2(50) constraint nn_socio_direccion not null, telefono char(11)); >CREATE TABLE pelicula(codpel number constraint pk_pelicula primary key, titulo varchar2(25) constraint nn_pelicula_titulo not null, codgenero char(3) constraint nn_pelicula_codgenero not null constraint fk_pelicula_genero references genero(codgenero), duracion number(3), director varchar2(25), precio_alquiler char(4) constraint nn_pelicula_precio not null); >CREATE TABLE copia(codpel number constraint fk_copia_pelicula references pelicula(codpel), numcopia number(3), fecha_adquision date, constraint pk_copia primary key (codpel,numcopia)); >CREATE TABLE alquiler(codpel number, numcopia number(3), codsocio number constraint fk_alquiler_socio references socio(codsocio), fecha_alquiler date default sysdate, pagado char default ‘N’ constraint chk_alquiler_pagado check(pagado in(‘S’,’N’)), constraint fk_alquiler_copia foreign key (codpel, numcopia) references copia(codpel,numcopia) on delete cascade, constraint pk_alquiler primary key (codpel,numcopia,codsocio,fecha_alquiler)); 57 APENDICE TEMA 4. CASE 5. ALTERACIÓN DE UNA TABLA. 5.1. Añadir a la tabla pelicula la columna catalogacion, de tipo de dato char y longitud 1. >ALTER TABLE pelicula add catalogacion char; 7. CONFIDENCIALIDAD DE LOS DATOS. 7.1. Conectarse como Puesto13. >CONNECT puesto13/matrix; 7.2. Otorgar los privilegios select e insert sobre pelicula a Tercero with grant option. >GRANT select, insert on pelicula to Tercero WITH GRANT OPTION; 7.3. Otorgar update sobre la columna titulo de la tabla pelicula a Tercero y Cuarto. >GRANT update(titulo) on pelicula to Tercero, Cuarto; 7.4. Otorgar DELETE sobre pelicula a Tercero. >GRANT delete on pelicula to Tercero; 7.5. Conectarse como tercero. >CONNECT Tercero/matrix; 7.6. Insertar fila en pelicula. >INSERT into puesto13.pelicula values(4,’Misión Imposible 2’,’sus’,125,’John Woo’,2.50,’M’); 7.7. Seleccionar todas las filas de pelicula. >SELECT * from puesto13.pelicula; 7.8. Conectarse con Cuarto. >CONNECT Cuarto/matrix; 7.9. Insertar fila en pelicula; >INSERT into puesto13.pelicula values(5,’Top Gun’,’sus’...); [Insuficientes Privilegios] 58 APENDICE TEMA 4. CASE 7.10. Conectarse como tercero. >CONNECT Tercero/matrix; 7.11. Otorgar insert sobre pelicula a Cuarto. >GRANT insert on puesto13.pelicula to Cuarto; 7.12. Conectarse como Cuarto. >CONNECT Cuarto/matrix; 7.13. Insertar fila en pelicula. >INSERT into puesto13.pelicula values(5,’Top Gun’,’sus’...); 7.14. Borrar la pelicula con codpel=3. >DELETE from puesto13.pelicula WHERE codpel=3; [Privilegios Insuficientes] 7.15. Conectarse como Tercero. >CONNECT Tercero/matrix; 7.16. Otorgar DELETE sobre pelicula a Cuarto. >GRANT delete on puesto13.pelicula to Cuarto; [Privilegios Insuficientes] 7.17. Conectarse como puesto13. >CONNECT Puesto13/matrix; 7.18. Otorgar DELETE sobre pelicula a Cuarto. >GRANT delete on pelicula to Cuarto; 7.19. Conectarse como Cuarto. >CONNECT Cuarto/matrix; 7.20. Borrar la pelicula con codpel3. >DELETE from puesto13.pelicula WHERE codpel=3; 59 APENDICE TEMA 4. CASE 7.21. Modificar el Título de la pelicula con codpel=1. >UPDATE puesto13.pelicula SET titulo=’Guay del Paraguay’ WHERE codpel=1; 7.22. Conectarse como Puesto13. >CONNECT Puesto13/matrix; 7.23. Retirar el privilegio INSERT sobre pelicula a Tercero con cascade constraint. >REVOKE insert on pelicula from Tercero CASCADE CONSTRAINT; 7.24. Conectarse como Cuarto. >CONNECT Cuarto/matrix; 7.25. Insertar una fila en pelicula. >INSERT into puesto13.pelicula values(6, ‘Grease’,...); [Privilegios Insuficientes] 8. CREACIÓN DE ROLES. 8.1. Crear un rol llamado palvideoclub que conceda el permiso de consulta sobre la tabla género. Posteriormente conceder este rol a Tercero, y consultar la tabla genero con Tercero y con Cuarto. >CREATE ROLE palvideoclub; >GRANT select ON genero TO palvideoclub; >GRANT palvideoclub TO Cuarto; >CONNECT Tercero/matrix; >SELECT * from puesto13.genero; >CONNECT Cuarto/matrix; SELECT * from puesto13.genero; [ERROR] 9. CREACION DE ÍNDICES. >CREATE INDEX idx_pelicula_titulo ON pelicula (titulo ASC); >CREATE INDEX idx_alquiler_copia ON alquiler(codpel,numcopia ASC); >SELECT index_name, index_type, table_owner, table_name FROM user_indexes; 60 APENDICE TEMA 4. CASE 10. CREACIÓN DE SINÓNIMOS. >CREATE PUBLIC SYNONYM pelicula for pelicula; >CREATE SYNONYM pelis for pelicula; >SELECT * from pelicula; >SELECT * from pelis; >CONNECT Tercero/matrix; >SELECT * from puesto13.pelicula; >SELECT * from pelicula; 11. CREACIÓN DE VISTAS. 11.1. Crear una vista ‘cartelera’ que tenga las columnas de la tabla pelicula que no permiten nulos. >CREATE VIEW cartelera AS select codpel, titulo, codgen, precio_alquiler FROM pelicula; 11.2. Crear una vista ‘cartelera2’ con las mismas columnas de la vista anterior pero asignándole los nombres de las columnas completos. >CREATE VIEW cartelera2 (codigo_pelicula, Título, Código_Género, Precio_Alquiler) AS select codpel, titulo, codgen, precio_alquiler from pelicula; 11.3. Crear una vista llamada ‘peliculas_suspense’ que contenga las películas de suspense. >CREATE VIEW peliculas_suspense AS select * FROM pelicula WHERE codgen=’sus’; 11.4. Crear de nuevo la vista ‘cartelera2’ con la cláusula with read only >DROP VIEW cartelera2; >CREATE VIEW cartelera2 (Codigo_Pelicula, Título, Código_Género, Precio_Alquiler) AS select codpel, titulo, codgen, precio_alquiler from pelicula WITH READ ONLY; 11.5. Crear de nuevo la vista ‘peliculas_suspense’ con la cláusula check option. >DROP VIEW peliculas_suspense; > CREATE VIEW peliculas_suspense AS select * FROM pelicula WHERE codgen=’sus’ WITH CHECK OPTION; 61 APENDICE TEMA 4. CASE SISTEMA DE INFORMACIÓN Se desea informatizar mediante una BD relacional la información referente al personal de una empresa de servicios ubicada en Madrid. Esta empresa tiene la siguiente organización: 1. La empresa tiene en la actualidad 3 centros o edificios donde se ubican sus oficinas. 2. La empresa está estructurada en departamentos. Cada departamento está ubicado en un centro. 3. Un departamento puede depender orgánicamente de otro departamento. 4. Cada departamento tiene un empleado jefe de departamento y varios empleados que trabajan en el departamento. 5. Un empleado está asignado a un departamento. Es posible que un empleado esté asignado a un departamento pero que sea jefe de otros departamentos distintos al que está asignado. 6. Cada empleado tiene una categoría laboral. CENTRO 1 UBICA N N DEPARTAMENTO 1 DP/E 1 DEPENDE N D/E N 1 EMPLEADO N 1 E/C CATEGORÍA 1. Crear el rol DBGESTOR con los privilegios del sistema para crear roles y 2. 3. 4. 5. 6. 7. 8. sinónimos. Crear el usuario DAI2/DAI2 Conceder a DAI2 los roles de CONNECT, RESOURCES y DBGESTOR. Crear las tablas de la BD de personal. Insertar 2 filas en CATEGO, 1 en CENTRO, 2 en DEPTO (asignando jefe de departamento), y 4 en EMPLE. Crear el rol QUERYPERSONAL que de permisos para insertar, borrar, actualizar y consultar las tablas de personal. Crear sinónimos públicos para las 4 tablas de personal con los mismos nombres de las tablas originales. Crear el usuario PROGRAMADOR otorgándole los roles CONNECT y QUERYPERSONAL. 62 APENDICE TEMA 4. CASE 1. >CREATE role DBGESTOR; >GRANT create role, create synonym TO DBGESTOR; 2. >CREATE user DAI2 IDENTIFIED BY DAI2 default tablespace user; 3. >GRANT connect, resource, dbgestor to DAI2; >CONNECT DAI2/DAI2; 4. >CREATE TABLE emple(codem number(3) constraint nn_emple_codem not null constraint pk_emple primary key, nomem varchar2(25) constraint nn_emple_nomem not null constraint un_emple_nomem unique, codde number(3) constraint nn_emple_codde not null, extel char(4), fecnac date constraint nn_emple_fecnac not null, fecing date constraint nn_emple_fecing not null, salar number(7,2) constraint nn_emple_salar not null, comis number(7,2), numhi number(2) constraint nn_emple_numhi not null, codcat number(2) constraint nn_emple_codcat not null); CREATE TABLE centro(codce number(2) constraint pk_centro primary key, nomce varchar2(20) constraint nn_centro_nomce not null constraint un_centro_nomce unique, dirce vasrchar2(40)); CREATE TABLE catego(codcat number(2) constraint pk_catego primary key, nomcat varchar2(20) constraint nn_catego:nomcat not null constraint un_catego_nomcat unique); CREATE TABLE depto(codde number(3) constraint pk_depto primary key, nomde varchar2(20) constraint nn_depto_nomde not null constraint un_depto_nomde unique, codce number(2) constraint nn_depto_codce not null constraint fk_depto_centro references centro(codce), codjefe number(3) constraint fk_depto_emple references emple(codem), tidir char(1) constraint chk_depto_tidir check(tidir in(‘P’,’F’)) constraint nn_depto_tidir not null, presu number(9,2), depde number(3) constraint fk_depto_depto references depto(codde)); >ALTER TABLE emple ADD constraint fk_emple_depto FOREIGN KEY (codde) references depto(codde) ON DELETE CASCADE; >ALTER TABLE emple ADD constraint fk_emple_catego FOREIGN KEY (codcat) references catego(codcat) ON DELETE CASCADE; 63 APENDICE TEMA 4. CASE 5. >INSERT INTO catego VALUES (1, ‘DIRECTOR GENERAL’); >INSERT INTO catego VALUES (2, ‘OPERADOR’); >INSERT INTO centro VALUES (1, ‘LA ARBOLEDA’, ‘AVDA. OESTE S/N’); >ALTER TABLE depto DISABLE constraint fk_depto_emple; >INSERT INTO depto VALUES (1, ‘INFORMATICA’,1,1,’P’.’’.’’); >INSERT INTO depto VALUES (2, ‘ATNCION AL CLIENTE’,1,’’,’F’,’’,’’); >ALTER TABLE emple DISABLE constraint fk_emple_depto; >INSERT INTO emple VALUES(1,’RODRIGUEZ RINCON, DAVID’...) x4; >ALTER TABLE emple ENABLE constraint fk_emple_depto; >ALTER TABLE depto ENABLE constraint fk_depto_emple; 6. >CREATE ROLE querypersonal; >GRANT insert, delete, update, select ON emple TO querypersonal; >GRANT insert, delete, update, select On depto TO querypersonal; >GRANT insert, delete, update, select ON centro TO querypersonal; >GRANT insert, delete, update, select ON catego TO querypersonal; >SELECT * FROM emple, depto, centro, catego; 7. >CONNECT DeMoN/matrix; >GRANT create public synonym TO dbgestor; >CONNECT dai2/dai2; >CREATE PUBLIC SYNONYM depto FOR depto; >CREATE PUBLIC SYNONYM emple FOR emple; >CREATE PUBLIC SYNONYM centro FOR centro; >CREATE PUBLIC SYNONYM catego FOR catego; 8. >CONNECT DeMoN/matrix >CREATE USER programador IDENTIFIED BY matrix default tablespace user; >GRANT connect, querypersonal TO programador; SELECT constraint_name, status FROM user_constraints; 64 APENDICE TEMA 5. CASE 1. CONSULTAS SENCILLAS. 1.1. Obtener todos los nombres de los centros de trabajo de la empresa ordenados alfabéticamente. >SELECT nomce FROM centro ORDER BY nomce; 1.2. Obtener los nombres de los empleados que trabajan en el departamento 121 ordenados por orden alfabético. >SELECT nomem FROM emple WHERE codde=121 ORDER BY 1; 1.3. Obtener toda la información del departamento 121. >SELECT * FROM depto WHERE codde=121; 1.4. Obtener los nombres y salarios de los empleados con más de 3 hijos, ordenado alfabéticamente. >SELECT nomem, salar FROM emple WHERE numhi>=3 ORDER BY 1; 1.5. Obtener el código del departamento en que trabajan, el nombre del empleado y su comisión de aquellos empleados cuyo salario es inferior a 1.200€, clasificándolos por departamento en orden descendente, por comisión en orden ascendente dentro de cada departamento. >SELECT codde, nomem, comis FROM emple WHERE salar<1200 ORDER BY 1 DESC, 3 ASC; 1.6. Obtener por orden alfabético los nombres de los departamentos cuyo presupuesto sea superior a 120.000€. >SELECT nomde FROM depto WHERE presu>120000 ORDER BY 1; 1.7. Obtener por orden alfabético los nombres de los departamentos que tienen jefe en propiedad. >SELECT DISTINCT nomde FROM depto WHERE tidir=’P’ ORDER BY 1; 1.8. Obtener un listín telefónico de los empleados del departamento 121 en el que se incluya nombre de empleado, código de empleado y extensión telefónica. >SELECT nomem, codem, extel FROM emple WHERE codde=121; 65 APENDICE TEMA 5. 1.9. CASE Obtener una relación de todas las extensiones telefónicas con el nombre del empleado que la tiene asignada, ordenándola en orden decreciente de extensión telefónica y dentro de cada extensión en orden alfabético. >SELECT extel, nomem FROM emple ORDER BY 1 DESC,2; 1.10. Obtener el nombre, salario y comisión de aquellos empleados con más de 3 hijos clasificados por comisión, y dentro de ésta por orden alfabético. >SELECT nomem, salar, comis FROM emple WHERE numhi>3 ORDER BY 3,1; 2. EXPRESIONES. 2.1. Obtener los nombres y salarios anuales de los empleados, expresados en ptas. de los empleados del departamento 100, presentados ordenados en orden decreciente de salario anual. >SELECT nomem, salar*166.386 *12 FROM emple WHERE codde=100 ORDER BY salar DESC; 2.2. Obtener los nombres de los empleados cuya comisión es superior o igual al 20% de su salario. >SELECT nomem FROM emple WHERE comis>salar*0.20; 2.3. En una campaña de ayuda familiar se ha decidido dar a los empleados una paga extra de 50€ por hijo a partir del 4º hijo inclusive. Obtener por orden de paga extra y dentro de ésta ordenado alfabéticamente el nombre del empleado y el sueldo que incluya la paga extra. >SELECT nomem, salar+comis+((numhi-3)*50) FROM emple WHERE numhi>=4 ORDER BY (numhi-3)*50,1; 2.4. A los empleados se les concede una gratificación de 30€/hijo. Obtener los nombres de los empleados cuya gratificación supere el 5% de su salario, ordenado alfabéticamente. >SELECT nomem FROM emple WHERE numhi*30>salar*0.05 ORDER BY 1; 66 APENDICE TEMA 5. 2.5. CASE Llamamos presupuesto medio anual de un departamento al resultado de dividir su presupuesto anual entre 12. Se decide aumentar los presupuestos medios mensuales de todos los departamentos en un 10% a partir del mes de octubre inclusive. Obtener por orden alfabético el nombre de departamento, su presupuesto anual después del incremento de aquellos departamentos cuyo presupuesto mensual medio anterior a octubre es de 10.000€. >SELECT nomde, ((presu*0.10)/12)*3+presu FROM depto WHERE presu/12=10000 ORDER BY 1; 2.6. A pesar de que en el próximo año todos los indicadores económicos preveen una inflacción del 2%, el gobierno se empeña en decir que será de un 3%. Los empresarios, más interesados en la previsión del gobierno del 3%, deciden aumentar el salario de los empleados en un 3%. Obtener por orden alfabético el nombre del empleado, su suelda anual actual y su sueldo anual con la subida. Presentar las magnitudes separadas por puntos decimales y comas de millar. >SELECT nomem, to_char((salar+comis)*12,’99,999.00’), to_char((salar*1.03+comis)*12,’99,999.00’) FROM emple ORDER BY 1; 2.7. Obtener el código de empleado, su nombre, su sueldo en pesetas de aquellos empleados que tienen un sueldo superior a 1.800€. Ordenar por departamento y alfabéticamente. >SELECT codem, nomem, (salar+comis)*166.386 FROM emple WHERE salar+comis>1800 ORDER BY codem, nomem; 2.8. Obtener los códigos de departamento en los que haya algún empleado cuya comisión supere el 15% de su salario. >SELECT DISTINCT codde FROM emple WHERE comis>salar*0.15; 2.9. Obtener la relación de empleados que comparten la extensión 880 o 3131. Ordenar por código de departamento y dentro de éstos alfabéticamente. >SELECT codde, nomem FROM emple WHERE extel=3131 or 880 ORDER BY codde, nomem; 67 APENDICE TEMA 5. CASE 3. PREDICADOS. 3.1. Obtener por orden alfabético los empleados que trabajan en el mismo departamento que NIETO ORTEGA, RUBÉN. >SELECT nomem FROM emple WHERE codde=(select codde from emple where nomem=’NIETO ORTEGA, RUBEN’) ORDER BY nomem; 3.2. Obtener por orden alfabético los nombres de los empleados cuyo salario sea igual o superior en más del 15% al salario del empleado ‘NIETO ORTEGA, RUBEN’. >SELECT nomem FROM emple WHERE salar<=1.15*(select salar from emple where nomem=’NIETO ORTEGA, RUBEN’); 3.3. Obtener los empleados que no tengan extensión telefónica. >SELECT nomem FROM emple WHERE extel IS NULL; 3.4. Obtener los nombres de departamento que no dependen orgánicamente de otros. >SELECT nomde FROM depto WHERE depde IS NULL; 3.5. De los empleados que cobran comis, obtener su nombre y sueldo total. >SELECT nomem, salar+comis FROM emple WHEER comis IS NOT NULL; 3.6. Obtener los nombres de los empleados que cobran menos de 150€ de comisión. >SELECT nomem, comis FROM emple WHERE nvl(comis,0)<150; 3.7. Obtener el sueldo total de los empleados que no tienen extensión telefónica. >SELECT nomem, salar+nvl(comis,0) FROM emple WHERE extel IS NULL; 3.8. Obtener los nombres de los empleados que trabajen en un departamento con presupuesto inferior a 100.000€. >SELECT nomem FROM emple WHERE codde=SOME(select codde from depto where presu<100000); 68 APENDICE TEMA 5. 3.9. CASE Obtener por orden alfabético los nombres de los empleados cuyo salario supera al máximo salario de los empleados del departamento 122. >SELECT nomem FROM emple WHERE salar>ALL (select salar from emple where codde=122) ORDER BY 1; 3.10. Obtener el nombre del empleado que más cobra del departamento 100. >SELECT nomem FROM emple WHERE codd=100 AND salar>=ALL(select salar from emple where codde=100); 3.11. Obtener el nombre y el sueldo total de los empleados que tienen un jefe en funciones. >SELECT nomem, salar+nvl(comis,Ø) FROM emple WHERE codde=SOME (select codde from depto where tidir=’F’); 3.12. Obtener el nombre de los empleados que comparten extensión telefónica con el empleado “EGIDO COLL, OSCAR”. >SELECT nomem FROM emple WHERE extel= (select extel from emple where nomem=’EGIDO COLL, OSCAR’); 3.13. Obtener los nombres de los empleados que trabajan en el departamento del cual es jefe el empleado con código 180. >SELECT nomem FROM emple WHERE codde=SOME (select codde from depto where codjefe=180); 3.14. Obtener los nombres de departamento cuyo presupuesto supere en un 25% el presupuesto del departamento ‘ORGANIZACIÓN’. >SELECT nomde FROM depto WHERE presu > (select presu*1.25 from depto where nomde=’ORGANIZACIÓN’); 3.15. Obtener los nombres de los empleados que van a trabajar a la ‘SEDE CENTRAL’. >SELECT nomem FROM emple WHERE codde=SOME (select codde from depto where codce= (select codce from centro where nomce=’SEDE CENTRAL’)); 69 APENDICE TEMA 5. CASE 3.16. Obtener los nombres de los empleados que trabajan en el departamento del que es jefe el empleado ‘MONROY DE CELIS, JAIME’. >SELECT nomem FROM emple WHERE codde=SOME (select codde from depto where codjefe= (select codem from emple where nomem=’MONROY DE CELIS, JAIME’)); 3.17. Obtener el nombre del jefe de departamento de informática. >SELECT nomem FROM emple WHERE codem= (select codjefe from depto where nomde=’INFORMATICA’); 3.18. Obtener el nombre de departamento del que es jefe el empleado ‘COZAR MENCHERO, IVÁN’. >SELECT nomde FROM depto WHERE codjefe= (select codem from emple where nomem=’COZAR MENCHERO, IVAN’); 3.19. Obtener por orden alfabético los nombres y sueldos de los jefes de departamento de la empresa. >SELECT nomem, salar+nvl(comis,Ø) FROM emple WHERE codem= SOME (select codjefe from depto); 3.20. Obtener los nombres de los empleados cuyo salario este entre 1.200€ y 1.400€. >SELECT nomem FROM emple WHERE salar+nvl(comis,Ø) BETWEEN 1200 and 1400; 3.21. Obtener el nombre de los empleados cuyo primer apellido empiece por las letras p,q,r ó s. >SELECT nomem FROm emple WHERE nomem BETWEEN ‘P’ and ‘T’; 3.22. Obtener los empleados cuyo primer apellido es ‘MARTIN’. >SELECT nomem FROM emple WHERE nomem LIKE ‘MARTIN%’; 3.23. Obtener los empleados cuyo nombre de pila contenga el nombre ‘JOSÉ’. >SELECT nomem FROM emple WHERE nomem LIKE ‘%,%JOSE’ OR nomem LIKE ‘%,JOSE%’ 70 APENDICE TEMA 5. CASE 3.24. Obtener los empleados que tengan un nombre de pila de más de 7 letras. >SELECT nomem FROM emple WHERE nomem LIKE ‘%,_ _ _ _ _ _ _%’; 3.25. Obtener en orden alfabético los nombres de los empleados cuya extensión telefónica sea 880/650/780. >SELECT nomem FROM emple WHERE extel IN(‘880’,’650’,’780’) ORDER BY 1; 3.26. Obtener los nombres de los empleados que son compañeros de trabajo de ‘PUMAR REY, JOSÉ’ y ‘RINCÓN FERNANDEZ, LEONARDO’. >SELECT nomem FROM emple WHERE codde IN (select codde from emple where nomem in(‘PUMAR REY, JOSE’, ‘RINCON FERNANDEZ, LEONARDO’)); 3.27. Obtener los nombres de departamento en los que haya empleados que no cobren comisión. >SELECT nomde FROM depto WHERE codde IN (select codde from emple where comis is null); 3.28. Si algún empleado se apellida de segundo apellido ‘MARTIN’, entonces visualizar el nombre de todos los empleados de la empresa, y si no no visualizar nada. >SELECT nomem FROM emple WHERE EXISTS (select * from emple where nomem like ‘%MARTIN,%’); 3.29. Si en el departamento 100 hay algún empleado que se llama de primer apellido MARTIN, visualizar los nombres de todos los empleados del departamento 100. >SELECT nomem FROM emple WHERE codde=100 AND EXISTS (select * from emple where nomem like’MARTIN %,%’ AND codde=100); 3.30. Obtener en orden alfabético los nombres y salarios de los empleados que no tienen hijos y ganan más de 1.500€ o tienen hijos y ganan menos de 1.500€. >SELECT nomem, salar FROM emple WHERE (numhi=Ø AND salar>1500) OR (numhi<>Ø AND salar<1500) ORDER BY 1; 71 APENDICE TEMA 5. CASE 3.31. Obtener el código de departamento, el nombre del empleado y el sueldo total de los empleados que no tienen hijos y no cobran comisión. Presentarlo ordenado por departamento y dentro de él alfabéticamente. >SELECT codde, nomem, salar D¡FROM emple WHERE numhi=Ø AND comis IS NULL ORDER BY 1,2; 3.32. Obtener el código de departamento, el nombre del empleado y el sueldo de los empleados que trabajan en los departamento 110 y 112. >SELECT codde, nomem, salar+nvl(comis,Ø) FROM emple WHERE codde=110 OR codde=112 ORDER BY 1; 3.33. Obtener el código de departamento, nombre de empleado y salario de los empleados que trabajan en el departamento 110y 112 y cobran más de 1.400€. >SELECT codde, nomde, salar FROM emple WHERE (codde=110 OR codde=112) AND salar>1400 ORDER BY 1; 3.34. Obtener los nombres de departamento que no sean de dirección ni de sección. >SELECT nomde FROM depto WHERE nomde<>ALL (select nomde from depto where nomde like ‘DIRECCION%’ or nomde like ‘SECCION%’); 3.35. Obtener el nombre y fecha de nacimiento de los empleados que ingresaron en la empresa hace más de 8 años. >SELECT nomem, fecnac FROM emple WHERE (SYSDATE- fecing)/365>8; 3.36. Obtener los nombres de los empleados que trabajan en la calle Alcalá. >SELECT nomem FROM emple WHERE codde=SOME (select codde from depto where codce=some (select codce from centro where dirce like ‘C/ALCALA,%’)); 3.37. Obtener el nombre del empleado y el sueldo total en pesetas de aquellos empleados cuya comisión supere el 10% de su salario y trabajen en un departamento que tenga un presupuesto superior a 100.000€ y que no esté ubicado en la calle Alcalá. >SELECT nomem, (salar+nvl(comis,Ø))*166.386 FROM emple WHERE comis>salar*0.10 AND codde>SOME (select codde from depto where presu>100000 and codce <>all(select codce from centro where dirce like ‘C/ALCALA,%’)); 72 APENDICE TEMA 5. CASE 3.38. Obtener los nombres de los empleados que tienen la misma extensión telefónica que el empleado 120 y trabajan en un departamento cuyo presupuesto es inferior al presupuesto del departamento 110. >SELECT nomem FROM emple WHERE extel= (select extel from emple where codem=120) AND codde=SOME (select codde from depto where presu< (select presu from depto where codde=110)); 3.39. Obtener los nombres de centro en los que haya jefes de departamento en funciones con un sueldo total superior a 1.200€. >SELECT nomce FROM centro WHERE codce=SOME (select codce from depto where tidir=’F’ and codjefe=SOME (select codem from emple where salar+nvl(comis,Ø)>1200)); 3.40. Obtener los nombres de empleado cuyo salario es superior al 75% del salario del jefe del departamento ‘INGENIERIA’ y trabaja en un departamento con jefe en funciones. >SELECT nomem FROM emple WHERE salar> (select salar*Ø.75 from emple where codem= (select codjefe from depto where nomde=’INGENIERIA’)) AND codde=SOME (select codde from depto where tidir=’F’); 3.41. Obtener el sueldo total , el nombre de empleado y el código del departamento en que trabaja de aquellos empleados que tienen la categoría profesional ‘ASESOR TÉCNICO’ y su salario supera los salarios de los empleados con categoría profesional ‘CONSULTOR’ del departamento informático. Presentarlos ordenados por código de departamento y sueldo total. >SELECT nomem, salar+nvl(comis,Ø), codde FROM emple WHERE codcat= (select codcat from catego where nomcat=’ASESOR TECNICO’) AND salar>ALL (select salar from emple where codcat= (select codcat from catego where nomcat=’CONSULTOR’) and codde= (select codde from depto where nomde=’INFORMATICA’)) ORDER BY 3,2; 3.42. Obtener los nombres de departamento donde no haya empleados de la categoría ‘RELACIONES PUBLICAS’. >SELECT nomde FROM depto WHERE codde<>ALL (select codde from emple where codcat= (select codcat from catego where nomcat=’RELACIONES PUBLICAS’)); 73 APENDICE TEMA 5. CASE 3.43. Obtener el nombre y sueldo total de los empleados cuyo sueldo total supera al salario mínimo de la empresa en 250€. >SELECT nomem, salar+nvl(comis,Ø) FROM emple WHERE salar+nvl(comis,Ø)>SOME (select salar+250 from emple); 4. FUNCIONES DEL LENGUAJE SQL. 4.1. Obtener en orden alfabético los nombres de los empleados que tengan más de 20 caracteres en su nombre completo. >SELECT nomem FROM emple WHERE LENGTH(nomem)>20; 4.2. Obtener los nombres abreviados de los departamentos tomando las 10 primeras letras. >SELECT SUBSTR(nomde,1,10) FROM depto; 4.3. Obtener los códigos de departamento y los 5 caracteres siguientes que están a continuación del carácter 12 de sus nombres. >SELECT codde, SUBSTR(nomde,12,5) FROM depto, 4.4. Obtener los códigos de departamento y las 5 últimos caracteres de su nombre de aquellos departamentos que tengan en nombre con más de 12 caracteres. >SELECT codde, SUBSTR(nomde,-5) FROM depto WHERE LENGTH(nomde)>12; 4.5. Obtener por orden alfabético los nombres de los empleados suprimiendo las 3 últimas cifras del nombre de pila para aquellos empleados cuyo nombre de pila tenga más de 6 letras. >SELECT SUBSTR(nomem,1,LENGTH(nomem)-3) FROM emple WHERE nomem LIKE ‘%,_ _ _ _ _ _%’; >SELECT SUBSTR(nomem, INSTR(nomem,’,’)+2, LENGTH(SUBSTR(nomem, INSTR(nomem,’,’)+2))-3) FROM emple WHERE LENGTH(SUBSTR(nomem,INSTR(nomem,’,’)+2))>6 ORDER BY nomem; 4.6. Obtener el valor máximo, mínimo, media aritmética y suma de los salarios de los empleados de la empresa. >SELECT MAX(salar), MIN(salar), SUM(salar), AVG(salar) FROM emple; 74 APENDICE TEMA 5. 4.7. CASE Obtener los mismos datos del ejercicio anterior de los empleados que trabajan en el departamento 120 y no cobran comisión. >SELECT MAX(salar), MIN(salar), AVG(salar) FROM emple WHERE codde=120 AND comis IS NULL; 4.8. Obtener en orden alfabético los salarios y nombres de los empleados cuyo salario sea mayor aquel 60% del máximo salario de la empresa. >SELECT nomem, salar FROM emple WHERE salar> (select max(salar)*0.60 from emple) ORDER BY 1; 4.9. Obtener cuantos empleados hay en la empresa. >SELECT COUNT(*) FROM emple; 4.10. Obtener cuantos empleados y cuantas extensiones telefónicas hay en el departamento 112. >SELECT COUNT(*), COUNT (DISTINCT extel) FROM emple WHERE codde=112; 4.11. Obtener cuantos empleados han nacido antes del año 1970. >SELECT COUNT(nomem) FROM emple WHERE to_char(fecnac,’yyyy’)<’1970’; 4.12. Obtener el código de empleado, su nombre y su sueldo total de los empleados cuyo sueldo total supera al salario mínimo de informática en más de 400€. >SELECT codem, nomem, salar+nvl(comis,Ø) FROM emple WHERE salar+nvl(comis,Ø)> (select min(salar)+400 from emple where codde= (select codde from depto where nomde=’INFORMATICA’)); 4.13. Obtener el preupuesto medio de los departamentos cuyo presupuesto supera al presupuesto medio de todos los departamentos de la empresa. >SELECT AVG(presu) FROM depto WHERE presu>(select avg(presu) from depto); 4.14. Obtener el salario medio de los empleados cuyo salario supera en más del 20% al salario mínimo de los empleados que tienen hijos y su salario medio por hijo es mayor de 300€. >SELECT AVG(salar) FROM emple WHERE salar> (select min(salar)*1.20 from emple where salar/numhi>300 and numhi>Ø); 75 APENDICE TEMA 5. CASE 4.15. Obtener el nombre y presupuesto de los departamentos ubicados en la C/Alcalá cuyo presupuesto supere al mínimo presupuesto de los departamentos no ubicados en la C/Alcalá. >SELECT nomde, presu FROM depto WHERE codce= SOME (select codce from centro where dirce like ‘C/ALCALA%’) AND presu>(select min(presu) from depto where codce<>all (select codce from centro where dirce like ‘C/ALCALA%’)); 5. CONSULTAS CON AGRUPAMIENTO DE FILAS. 5.1. Obtener para cada departamento la suma de los salarios de sus empleados, el máximo y el mínimo salario. >SELECT codde, SUM(salar), MAX(salar), MIN(salar) FROM emple GROUP BY codde ORDER BY codde; 5.2. Obtener de cada departamento la fecha de nacimiento del empleado con mayor edad que tenga comisión. >SELECT codde, MIN(fecnac) FROM emple WHERE comis IS NOT NULL GROUP BY codde; 5.3. Presentar las extensiones telefónicas de la empresa indicando cuantos empleados la utilizan. >SELECT extel, COUNT(*) FROM emple GROUP BY extel; 5.4. Agrupando por código de departamento y número de hijos obtener cuántos empleados hay en cada grupo. >SELECT codde, numhi, COUNT(*) FROM emple GROUP BY codde, numhi; 5.5. Obtener el código de departamento y la suma de los salarios de sus empleados para aquellos departamentos en los que trabajan m´s de 3 empleados. >SELECT codde, SUM(salar), COUNT(*) FROM emple GROUP BY codde HAVING count(*)>3; 76 APENDICE TEMA 5. 5.6. CASE Obtener el salario máximo y mínimo de los empleados que cobran comisión para cada grupo de empleados con igual número de hijos, de aquellos grupos en los que hay más de 4 empleados y el salario máximo del grupo supera los 1.400€. >SELECT MAX(salar), MIN(salar), numhi, COUNT(*) FROM emple WHERE comis IS NOT NULL GROUP BY numhi HAVING COUNT(*)>4 AND MAX(salar)>1400; 5.7. Obtener la media aritmética de los salarios de los empleados de cada departamento para aquellos departamentos cuyo salario máximo es menor a la media de salarios de la empresa. >SELECT AVG(salar) FROM emple GROUP BY codde HAVING MAX(salar)<(select avg(salar) from emple); 5.8. Para cada departamento que tenga más 2 empleados con hijos obtener el salario máximo y el salario mínimo de los empleados que trabajan en el departamento, tanto de los que tienen hijos como los que no. >SELECT codde, MAX(salar), MIN(salar) FROM emple GROUP BY codde HAVING codde=SOME(select codde from emple where numhi)Ø group by codde having count(*)>2); 5.9. Obtener para cada departamento cuantos empleados trabajna en el, la suma de sus salarios y la suma de sus comisiones para aquellos departamentos en los que haya empleados cuyo salario sea mayor de 1.700€. >SELECT codde, COUNT(*), SUM(salar), SUM(nvl(comis,Ø)) FROM emple GROUP BY codde HAVING codde=SOME(select codde from emple where salar>1700); 5.10. Para cada extensión telefónica obtener cuantos empleados la utilizan y su salario medio. >SELECT extel, COUNT(*), AVG(salar) FROM emple GROUP BY extel; 5.11. Para cada departamento obtener la media de las comisiones con respecto a los empleados que reciben comisión y la media aritmética de comisiones con respecto al total de empleados. >SELECT codde, AVG(comis), AVG(nvl(comis,Ø)) FROM emple GROUP BY CODDE; 77 APENDICE TEMA 5. CASE 5.12. De cada extensión telefónica cuantos empleados la utilizan en cada departamento. >SELECT extel, codde, COUNT(*) FROM emple GROUP BY extel, codde; 5.13. Obtener la media de salarios de los empleados que son jefes de departamento en funciones. >SELECT AVG(salar) FROM emple WHERE codem=SOME (select codjefe from depto where tidir’F’); 5.14. Para cada extensión telefónica obtener en cuantos departamentos se utiliza. >SELECT nvl(extel,’sin extension’), COUNT(DISTINCT codde) FROM emple GROUP BY extel; 5.15. Para los departamentos en los que hay algún empleado que no cobra comisión obtener cuantos empleados hay en promedio por extensión telefónica. >SELECT codde, COUNTcodem)/COUNT(DISTINCT extel) FROM emple GROUP BY codde HAVING codde=SOME(select codde from emple where comis IS NULL); 5.16. Para los departamentos en los que la media de salario supera la media de salarios de todos lod empleados de la empresa, obtener cuantas extensiones telefónicas tiene asignadas. >SELECT codde, COUNT(DISTINCT extel) FROM emple GROUP BY codde HAVING AVG(salar)>(select avg(salar) from emple); 5.17. Obtener la suma de los salarios de aquel departamento que tenga mayor coste de salarios de sus empleados. >SELECT codde, SUM(salar) FROM emple GROUP BY codde HAVING SUM(salar)>=all(select sum(salar) from emple group by codde); 5.18. Obtener la extensión telefónica y los nombres de los empleados que la tienen asignada de aquellas extensiones que son utilizadas por más de 3 empleados. >SELECT extel, nomem FROM emple WHERE extel=SOME(select extel from emple group by extel having count(*)>2); 78 APENDICE TEMA 5. CASE 5.19. De cada departamento en el que trabajan más de 3 empleados cuyo salario supere los 1.400€ obtener la media aritmética de los salrios de todos los empleados del departamento. >SELECT codde, AVG(salar) FROM emple GROUP BY codde HAVING codde=SOME (select codde from emple where salar>1400 group by codde having count(*)>3); 5.20. Obtener las extensiones telefónicas que pertenezcan a un departamento en el que hayan más de 2 extensiones telefónicas y que estén compartidas por mas de un empleado y por menos de 5 empleados del mismo departamento. >SELECT codde, extel FROM emple WHERE codde=SOME (select codde from emple group by codde having count(distinct extel)>2) AND estel IS NOT NULL GROUP BY codde, extel HAVING count(*) BETWEEN 1 AND 5; 5.21. Obtener el nombre del departamento con mayor índice de natalidad. >SELECT nomde FROOM depto WHERE codde= (select codde from emple group by codde having sun(numhi)>=all (select sum(numhi) from emple group by codde)); 6. CONSULTAS SOBRE VARIAS TABLAS. 6.1. Obtener todos los departamentos de la empresa indicando el código de departamento, el nombre del departamento y el nombre del centro en el que se ubica. >SELECT depto.codde, depto.nomde, centro.nomce FROM depto, centro WHERE depto.codce=centro.codce; 6.2. Obtener los nombres de todos los empleados indicando el nombre del departamento donde están asignados y el nombre del centro al que van a trabajar. >SELECT e.nomem, d.nomde, c.nomce FROM emple e, depto d, centro c WHERE d.codce=c.codce AND e.codde=d.codde ORDER BY 1; 79 APENDICE TEMA 5. 6.3. CASE Obtener los nombres de los empleados que cobran comisión indicando los nombres de departamento en que trabajan y el centro en el que se ubica su departamento. >SELECT e.nomem, d.nomde, c.nomce FROM emple e, depto d, centro c WHERE e.comis IS NOT NULL AND c.codce=d.codce AND e.codde=d.codde; 6.4. Obtener los nombres de los empleados de la empresa y la dirección a la que van a trabajar. >SELECT e.nomem, c.dirce FROM emple e, depto d, centro c WHERE d.codce=c.codce AND e.codde=d.codde; 6.5. Obtener el nombre de empleado, el nombre del departamento en el que trabaja y el nombre del centro en que se ubica el departamento de aquellos empleados que van a trabajar a la C/Alcalá. >SELECT e.nomem, d.nomde, c.nomce FROM emple e, depto d, centro c WHERE e.codde=d.codde AND d.codce=c.codce AND c.codce=SOME(select codce from centro where dirce like ‘C/ALCALA%’); 6.6. obtener el nombre de departamento y el nombre del departamento del que depende de aquellos departamentos que dependen de un departamento con presupuesto inferior a 100.000€. >SELECT d1.nomde, d2.nomde FROM depto d1, depto d2 WHERE d2.presu<100000 AND d2.codde=d1.depde; 6.7. Obtener los nombres de los jefes del departamento y los nombres de departamento de los que son jefes cuando los jefes son en funciones. >SELECT e.nomem, d.nomde FROM emple e, depto d WHERE tidir?’F’ AND e.codem=d.codjefe; 6.8. Obtener los nombres de y los nombres de sus jefes de departamento de aquellos empleados que cobran más que sus jefes. >SELECT e1.nomem, e1.salar, e2.nomem, e2.salar FROM emple e1, emple e2, depto d WHERE e2.codem=d.codjefe AND e1.codde=e2.codde AND e1.salar>e2.salar; 80 APENDICE TEMA 5. 6.9. CASE Obtener los nombres de los empleados cuyos salarios superen a la media de los salarios de sus compañeros de departamento. >SELECT nomem FROM emple WHERE salar>(select avg(salar) from emple e1 where e1.codde=emple.codde); 6.10. Obtener el nombre de empleado cuyo salario supere la media de salarios de los compañeros de departamento sin incluirse él. >SELECT nomem FROM emple e1 WHERE salar>(select avg(salar) from emple where codde=e1.codde and codem<>e1.codem); 6.11. De cada departamento obtener cuantos empleados son mayores que su jefe de departamento. Presentar el nombre de empleado y el número de empleados. >SELECT nomde, count(*) FROM depto d, emple e1 WHERE e1.codde=d,codde AND fecnac<(select fecnac from emple where codem=some (select codjefe from depto) and emple.codde=d.codde) GROUP BY nomde; >SELECT nomde, count(*) FROM depto d, emple e WHERE e.codde=d.codde AND fecnac<(select fecnac from emple where codem=d.codjefe) GROUP BY nomde; 6.12. De cada departamento obtener cuantos empleados son mayores que su jefe de departamento. Presentar el nombre de empleado y el número de empleados. (sin usar correlacionadas). >SELECT nomde, count(*) FROM depto d, emple e1, emple e2 WHERE e1.codde=d.codde AND d.codjefe=e2.codem AND e1.fecnac<e2.fecnac GROUP BY nomde; 81 APENDICE TEMA 5. CASE 6.13. Obtener los nombres de departamento y la dirección donde se ubican de aquellos departamentos cuyo presupuesto es inferior a 10 veces la suma de los salarios de sus empleados que cobran comisión. >SELECT nomde, dirce FROM depto d, centro c WHERE d.codce=c.codce AND d.presu<(select sum(salar)*10 from emple where comis is not null And emple.codde=d.codde); 6.14. Obtener los nombres de departamento y los nombres de centro donde se ubican de aquellos departamentos cuyo presupuesto es superior a la media aritmética de los presupuestos de los departamentos que dependen de él. >SELECT nomde, nomce FROM depto d, centro c WHERE d.codce=c.codce AND d.presu>(select avg(presu) from depto where depde=d.codde); 6.15. Para los departamentos cuyo presupuesto supera los 90.000€ obtener el promedio de empleados por extensión telefónica. >SELECT codde, count(distinct extel)/count(*) FROM emple WHERE codde=some(slect codde from depto where presu>90000) GROUP BY codde; >SELECT d,nomde, count(distinct extel)/count(*) FROM depto d, emple e WHERE d.codde=e.codde AND d.presu>90000 GROUP BY nomde; 6.16. De cada departamento que tenga un presupuesto inferior a 100.000€ obtener cuantos empleados cobran más de 1.000€. >SELECT codde, count(*) FROM emple WHERE codde=some (select codde from depto where presu<100000) AND salar+nvl(comis,Ø)>1000 GROUP BY codde; >SELECT d.nomde, count(*) FROM emple e, depto d WHERE d.codde=e.codde AND d.presu<100000 AND e,salar+nvl(comis,Ø)>1000 GROUP BY nomde; 82 APENDICE TEMA 5. CASE 6.17. Obtener el nombre de los jefes de departamento en funciones. >SELECT codde, nomde FROM emple WHERE codem=SOME(select codjefe FROM depto where tidir=’F’); >SELECT nomde, nomem FROM emple e, depto d WHERE d.codjefe=e.codem AND d.tidir=’F’; >SELECT nomem FROM emple WHERE EXISTS(slect * from depto where codjefe=codem and tidir=’F’); 6.18. Obtener los nombres de departamento que son de nueva creación, es decir, que no tenga empleados asignados y no tengan jefe en propiedad. >SELECT nomde FROM depto WHERE tidir<>’P’ AND NOT EXISTS (select * from emple where codde=depto.codde); 6.19. Obtener los nombres de jefes de primer nivel, es decir, que son jefes de un departamento que no depende de otro departamento. >SELECT nomem FROM emple e WHERE EXISTS (select * from depto where codjefe=e.codem and depde is null); >SELECT nomem FROM emple, depto WHERE depto.codjefe=emple.codem AND depto.depde IS NULL; 6.20. Obtener los nombres de jefe de último nivel, es decir, que sean jefes de un departamento del cual no dependen otros departamentos. >SELECT nomem FROM emple e, depto d WHERE e.codem=d.codjefe AND NOT EXISTS (select * from depto where depde=d.codde) GROUP BY nomem; >SELECT nomem FROM emple, depto WHERE codem=codjefe AND depto.codde<>ALL(select depde from depto where depde is not null); 83 APENDICE TEMA 5. CASE 6.21. Obtener los nombres de los empleados que trabajan en un departamento que tiene jefe en propiedad y además ese jefe es jefe en funciones de otro departamento. >SELECT nomem FROM emple e, depto d WHERE e.codde=d.codde AND d.tidir=’P’ AND d.codjefe=SOME(select codjefe from depto where tidir=’F’); >SELECT nomem FROM emple e, depto d WHERE e.codde=d.codde AND tidir=’P’ AND EXISTS (select * from depto where tidir=’F’ and codjefe=d.codjefe); 6.22. Obtener los nombres de departamento en que todos sus empleados tienen la misma categoría laboral. >SELECT distinct nomde FROM emple e, depto d WHERE e.codde=d.codde AND codcat=ALL (select codcat from emple where codde=d.codde); >SELECT distinct nomde FROM emple e, depto d WHERE e.codde=d.codde AND NOT EXISTS (select * from emple where codde=e.codde and codcat<>e.codcat); >SELECT nomde FROM depto WHERE codde=SOME (select codde from emple where codcat=all (select codcat from emple where codde=depto.codde)); 7. SENTENCIAS PARA MODIFICAR DATOS. 7.1. Se ha creado un nuevo departamento que depende del 110. Darlo de alta. >INSERT INTO depto VALUES(666,’DeMoN’,10,180,’F’,150000,110); >INSERT INTO depto (nomde, codde, depde, presu, codjefe, tidir, codce) VALUES (’DeMoN’,666,110,150000,180,’F’,10); 84 APENDICE TEMA 5. CASE >INSERT INTO depto (codde, nomce, codce, tidir) VALUES (666,’DeMoN’,10,’F’); 7.2. Supongamos que disponemos de una tabla vacía llamada EMPLEA2 con las mismas columnas de la tabla EMPLE. Se desea insertar en esta tabla los empleados de emple que hayan ingresado en la empresa a partir de la década de los 90. >CREATE TABLE emplea2(codem...); >INSERT INTO emplea2 SELECT * FROM emple WHERE to_char(fecing,’yyyy’)>=’1990’; 9. CONSULTAS COMPLEJAS EN SISTEMAS DE INFORMACIÓN COMPLEJOS. 9.1. Obtener un listado de los grupos que asisten en turno de mañana, presentando el código del grupo, el nombre de los alumnos que asisten al grupo y el nombre de las asignaturas que estudian cada uno de los alumnos. Ordenados por grupos, orden alfabético de alumno y orden alfabético de asignatura. >SELECT g.codgrupo, nomalumno, substr(denasigna,1,25) FROM alumno al, grupo g, estudia e, asigna a WHERE al.codgrupo=g.codgrupo AND e.dni=al.dni AND e.codasigna=a.codasigna AND turno=’M’ ORDER BY 1,2; 9.2. Obtener los nombres de los alumnos que estudias CASE organizados por grupos. >SELECT al.codgrupo, al.nomalumno FROM alumno al, estudia e WHERE e.dni=al.dni AND e.codasigna=’CASE’ ORDER BY 1,2; 9.3. Obtener la lista de alumnos asistentes a cada grupo y en cada asignatura. >SELECT al.codgrupo, a.denasigna, al.nomalumno FROM alumno al, estudia e, asigna a WHERE e.dni=al.dni AND e.codasigna=a.codasigna ORDER BY 1,2,3; 85 APENDICE TEMA 5. 9.4. CASE Obtener un listado de los profesores presentando el nombre del departamento al que está asignado y el nombre del profesor. Presentarlo por departamentos. >SELECT d.dendepar, p.nomprofe FROM departamento d, profesor p WHERE d.coddepar=p.coddepar ORDER BY 1,2; 9.5. Obtener un listado de los profesores presentando el nombre del departamento, el nombre del profesor y la relación de los grupos a los que imparte clase cada profesor. Clasificar por departamento y profesor. >SELECT distinct d.dendepar,p.nomprofe,c.codgrupo FROM clase c, profesor p, departamento d WHERE d.coddepar=p.coddepar AND c.ordenprofe=p.ordenprofe AND c.coddepar=p.coddepar ORDER BY 1,2; 9.6. Obtener un listado de los profesores presentando el nombre de departamento, el nombre del profesor y la relación de asignaturas que imparte cada profesor. Presentarlo ordenado por profesor. >SELECT d.dendepar, p.nomprofe, a.denasigna FROM departamento d, profesor p, asigna a, clase c WHERE c.ordenprofe=p.ordenprofe AND c.coddepar=p.coddepar AND c.codasigna=a.codasigna AND d.coddepar=c.coddepar ORDER BY 2; 9.7. Obtener los alumnos de la rama DAI del segundo curso, clasificados por grupo. >SELECT al.codgrupo, al.nomalumno, g.curso FROM alumno al, grupo g WHERE g.codgrupo=al.codgrupo AND g.curso=2 AND g.rama=’DAI’ ORDER BY al.codgrupo; 9.8. Obtener los nombres de los alumnos que asisten al mismo grupo que ‘ROIG FELIU, JORGE’. >SELECT nomalumno FROM añumno WHERE codgrupo=(select codgrupo from alumno where nomalumno=’ROIG FELIU, JORGE’); 86 APENDICE TEMA 5. 9.9. CASE Obtener el grupo y nombre de los alumnos de la rama ‘Desarrollo de Aplicaciones Informáticas’ que están matriculados en un grupo de 2º y cursan alguna asignatura de 1º. >SELECT distinct g.codgrupo, nomalumno FROM alumno al, rama r, grupo g, estudia e, asigna a WHERE r.codrama=al.codrama AND e.dni=al.dni AND e.codasigna=a.codasigna AND g.codgrupo=al.codgrupo AND al.codrama=r.codrama AND r.denrama=’DESARROLLO DE APLICACIONES INFORMATICAS’ AND g.curso=2 AND e.codasigna= SOME (select codasigna from asigna where curso=1); >SELECT nomalumno FROM alumno al, grupo g, rama r WHERE al.codgrupo=g.codgrupo AND al.codrama=r.codrama AND denrama=’DESARROLLO DE APLICACIONES INFORMATICAS’ AND curso=2 AND dni IN (select dni from estudia e, asigna a where e.codasigna=a.codasigna and curso=1); 9.10. Obtener el grupo y el nombre de los alumnos de DAI que están matriculados en un grupo de 2º y cursan alguna asignatura de 1º. Se han de visualizar los nombres delas asignaturas de 1º en las que están matriculados. >SELECT g.codgrupo, nomalumno, a.denasigna FROM alumno al, grupo g,estudia e, asigna a WHERE e.dni=al.dni AND e.codasigna=a.codasigna AND g.codgrupo=al.codgrupo AND al.codrama=’DAI’ AND g.curso=2 AND a.curso=1; 9.11. Obtener el nombre de los alumnos de 2º DAI que cursan alguna asignatura de 1º, visualizando tanto las asignaturas de 1º como las de 2º en las que esté matriculado. >SELECT nomalumno, denasigna FROM alumno al, grupo g, estudia e, asigna a WHERE al.dni=e.dni AND a.codasigna=e.codasigna AND g.codgrupo=al.codgrupo AND g.curso=2 AND al.codrama=’DAI’ AND EXISTS (select * from estudia, asigna where estudia.dni=al.dni and estudia.codasigna=asigna.codasigna and asigna.curso=1); 87 APENDICE TEMA 5. CASE >SELECT nomalumno, denasigna FROM alumno al, grupo g, estudia e, asigna a WHERE al.codgrupo=g.codgrupo AND al.dni=e.dni AND e.codasigna=a.codasigna AND al.codrama=’DAI’ AND g.curso=2 AND al.dni=SOME(select dni from estudia, asigna where estudia.codasigna=asigna.codasigna and curso=1); 9.12. obtener los nombres de los alumnos que no tienen que presentarse al examen final de GRAF y CASE. >SELECT nomalumno FROM alumno WHERE dni NOT IN (select dni from estudia where codasigna=’CASE’ and (nota1+nota2+nota3)/3<5) AND dni NOT IN (select dni from estudia where codasigna=’GRAF’ and (nota1+nota2+nota3)/3<5) AND dni IN (select dni from estudia where codasigna=’CASE’ or codasigna=’GRAF’); 9.13. Obtener los grupos en los que no hay matriculados alumnos. >SELECT codgrupo FROM grupo WHERE NOT EXISTS (select * from alumno where alumno.codgrupo=grupo.codgrupo); 9.14. Obtener de cada grupo cuántos alumnos han de presentarse al examen final de alguna asignatura (los alumnos que tengan más de 1 asignatura suspensa han de ser contados como 1 solo alumno). >SELECT al.codgrupo, count(al.nomalumno) FROM alumno al WHERE EXISTS (select * from estudia where estudia.dni=al.dni and (nota1+nota2+nota3)/3<5) GROUP BY codgrupo; 9.15. Obtener el nombre de los alumnos que tengan clase con el profesor ‘FOLGUERA PEREZ, LUIS’. >SELECT nomalumno FROM alumno al, clase c, profesor p, estudia e WHERE c.codgrupo=al.codgrupo AND c.ordenprofe=p.ordenprofe AND c.coddepar=p.coddepar AND e.dni=al.dni AND c.codasigna=e.codasigna AND p.nomprofe=’FOLGUERA PEREZ, LUIS’; 88 APENDICE TEMA 5. CASE 9.16. Obtener los nombres de los alumnos que estén matriculados de todas las asignaturas de 2º DAI. >SELECT nomalumno FROM alumno al WHERE NOT EXISTS (select codasigna from asigna where codrama=’DAI’ and curso=2 and codasigna<>all(select codasigna from estudia where al.dni=estudia.dni)); 9.17. Obtener los nombres de los alumnos que han aprobado todos los parciales de todas las asignaturas que estudia. >SELECT nomalumno FROM alumno al WHERE NOT EXISTS (select * from estudia e where e.dni=al.dni and (nota1<5 or nota2<5 or nota3<5)); 9.18. Obtener cuantos alumnos tiene cada profesor. > SELECT nomprofe, count(*) FROM profesor p, clase c, estudia e, alumno al WHERE p.ordenprofe=c.ordenprofe AND p.coddepar=c.coddepar AND c.codasigna=e.codasigna AND c.codgrupo=al.codgrupo AND e.dni=al.dni GROUP BY nomprofe; 9.19. Obtener aquellos alumnos cuya nota media de cada asignatura sea la mejor de lsa notas medias obtenidas por los alumnos de esa asignatura. >SELECT nomalumno FROM alumno WHERE dni=SOME(select dni from estudia where not exists (select * from estudia e where e.dni=estudia.dni and (nota1+nota2+nota3)/3<some(select (nota1+nota2+nota3)/3 from estudia where e.codasigna=estudia.codasigna))); 9.20. Obtener el grupo que tiene la nota media más alta. > SELECT codgrupo FROM estudia e, alumno al WHERE al.dni=e.dni GROUP BY al.codgrupo HAVING avg((nota1+nota2+nota3)/3)>=all (select avg((nota1+nota2+nota3)/3) from estudia e, alumno al where e.dni=al.dni group by al.codgrupo) 89