Documentos de Académico
Documentos de Profesional
Documentos de Cultura
PASO Descripción
Definir en el disco duro, el área física que contendrá las tablas de la base de datos.
1
Sentencia SQL --> CREATE DATABASE
Crear las diferentes tablas de la base de dato.
2
Sentencia SQL --> CREATE TABLE
Insertar las filas de las diferentes tablas, sin violar la integridad de datos.
3
Sentencia SQL --> INSERT INTO
Actualizar los datos que cambien con el tiempo en las diferentes tablas.
4
Sentencia SQL --> UPDATE
Eliminar las filas que ya no se requieran en las diferentes tablas.
5
Sentencia SQL --> DELETE
Realizar las consultas deseadas a las tablas de la base de datos a través de la
6
poderosa sentencia de consultas del SQL, llamada SELECT
Dar nombre a las consultas. Elaboradas en el paso No.6 cuando se requiera ocultar
7 el diseño y columnas de las tablas a través de la creación de vistas lógicas.
Sentencia SQL ----> CREATE VIEW
El DDL es la parte del lenguaje SQL que realiza la función de definición de datos del
SGBD. Fundamentalmente se encarga de la creación, modificación y eliminación de los
objetos de la base de datos (es decir de los metadatos). Por supuesto es el encargado
de la creación de las tablas.
Cada usuario de una base de datos posee un esquema. El esquema suele tener el mismo
nombre que el usuario y sirve para almacenar los objetos de esquema, es decir los
objetos que posee el usuario.
Esos objetos pueden ser: tablas, vistas, índices y otras objetos relacionados con la
definición de la base de datos. Los objetos son manipulados y creados por los usuarios.
En principio sólo los administradores y los usuarios propietarios pueden acceder a cada
objeto, salvo que se modifiquen los privilegios del objeto para permitir el acceso a otros
usuarios.
Las instrucciones DDL generan acciones que no se pueden deshacer (salvo que
dispongamos de alguna copia de seguridad).
Según los estándares actuales, una base de datos es un conjunto de objetos pensados
para gestionar datos. Estos objetos están contenidos en esquemas, los esquemas suelen
estar asociados al perfil de un usuario en particular.
En el estándar SQL existe el concepto de catálogo que sirve para almacenar esquemas.
Así el nombre completo de un objeto vendría dado por: catálogo.esquema.objeto
Si no se indica el catálogo se toma el catálogo por defecto. Si no se indica el esquema se
entiende que el objeto está en el esquema actual. En Oracle, cuando se crea un usuario,
se crea un esquema cuyo nombre es el del usuario.
1
Elaborado a partir del material base de: Alvaro E. García Manual Práctico de SQL, ORIENTADO A SQL 7.0
(noviembre de 2003); y Juan Ramón López Rodríguez. 2.4.-ElLenguajeSQL. Licenciatura en Documentación: Bases de
datos documentais Curso 2011 – 2012
Guia estudio práctica 5-GD-2019 Página 3
UNIVERSIDAD TECNOLOGICA NACIONAL - FACULTAD REGIONAL MENDOZA
CATEDRA: GESTION DE DATOS - INGENIERIA EN SISTEMAS DE INFORMACION
PROFESOR: María E. STEFANONI – JTP: Higinio A. FACCHINI – Matilde I. CESARI
Ejemplo a utilizar
Antes de abordar la descripción del lenguaje SQL, estableceremos el ejemplo de partida
que utilizaremos a lo largo de la explicación de la instrucción SELECT.
Se trata del esquema lógico - relativo a la gestión de una empresa – que habíamos
obtenido al analizar la transformación desde el modelo ER al modelo relacional.
Las relaciones, desde el punto de vista de SQL, deben ser consideradas como tablas;
asumiremos que, como tales, contienen los siguientes datos en un momento dado:
Departamentos
Empleados
Proyectos
LocalidadDept
TrabajaEn
CREACIÓN DE TABLAS
Sentencia CREATE
Dentro del Lenguaje de Definición (DL) del SQL, la sentencia CREATE permiten la
definición o creación de muchos objetos de la base de datos tales como: tablas
(esquemas), índices, vistas, dominios, ligaduras de integridad y procedimientos.
En esta oportunidad veremos las sentencias correspondientes a la creación de los
esquemas o lo que es lo mismo las tablas que contendrán los datos de la base de datos.
La sentencia CREATE TABLE. Define el nombre de la tabla, las columnas con su tipo de
datos, las ligaduras de intengridad que vigilan el valor que se guarde como dato en las
columnas o atributos sean llaves o no.
CREATE TABLE Proyectos ( nombre VARCHAR(50) );
Sólo se podrá crear la tabla si el usuario posee los permisos necesarios para ello. Si la
tabla pertenece a otro esquema (suponiendo que el usuario tenga permiso para grabar
tablas en ese otro esquema), se antepone al nombre de la tabla, el nombre del
esquema: CREATE TABLE otroUsuario.Proyectos (nombre VARCHAR(50));
Se puede indicar un valor por defecto para el atributo mediante la cláusula DEFAULT:
CREATE TABLE Proyectos (
nombre VARCHAR(50),
localidad VARCHAR(30) DEFAULT ‘Ciudad’);
De este modo si añadimos un proyecto y no indicamos localidad, se tomará Ciudad como
localidad de dicho Proyecto.
Sintaxis completa:
CREATE TABLE nombre_tabla (
campo1 tipo dato [NULL/NOT NULL] | CHECK (expresiónLógica) |
[DEFAULT expresiónConstante],
campo2 tipo dato [NULL/NOT NULL] | CHECK (expresiónLógica) |
[DEFAULT expresiónConstante ],
campo-N,
PRIMARY KEY(campo_llave),
FOREIGN KEY (campo_llave) REFERENCES tabla2 (campo_llave-tabla2)
)
- nombre_tabla se refiere a un nombre de tabla concreto
Deben cumplir las siguientes reglas (reglas de Oracle, en otros SGBD podrían cambiar):
- Deben comenzar con una letra
- No deben tener más de 30 caracteres
- Sólo se permiten utilizar letras del alfabeto (inglés), números o el signo de subrayado
(también el signo $ y #, pero esos se utilizan de manera especial por lo que no son
recomendados)
- No puede haber dos tablas con el mismo nombre para el mismo esquema (pueden
coincidir los nombres si están en distintos esquemas)
- No puede coincidir con el nombre de una palabra reservada SQL (por ejemplo no se puede
llamar SELECT a una tabla)
- En el caso de que el nombre tenga espacios en blanco o caracteres nacionales (permitido
sólo en algunas bases de datos), entonces se suele entrecomillar con comillas dobles. En
el estándar SQL 99 (respetado por Oracle) se pueden utilizar comillas dobles al poner el
nombre de la tabla a fin de hacerla sensible a las mayúsculas (se diferenciará entre
“FACTURAS” y “Facturas”)
- [ ] (corchetes). Los corchetes sirven para encerrar texto que no es obligatorio en el comando,
es decir para indicar una parte opcional.
- | (barra vertical). Este símbolo (|), la barra vertical, indica opción. Las palabras separadas
con este signo indican que se debe elegir una de entre todas las palabras.
- ... (puntos suspensivos) Indica que se puede repetir el texto anterior en el comando
continuamente (significaría, y así sucesivamente)
- {} (llaves) Las llaves sirven para indicar opciones mutuamente exclusivas pero obligatorias.
Es decir, opciones de las que sólo se puede elegir una opción, pero de las que es obligado
elegir una
Tipos de datos
A la hora de crear tablas, hay que indicar el tipo de datos de cada campo. Necesitamos
pues conocer los distintos tipos de datos
Descripción Tipos Estándar SQL Oracle SQL
Texto
Texto de anchura fija CHARACTER(n) CHAR(n) CHAR(n)
Texto de anchura variable CHARACTER VARYING(n) VARCHAR (n) VARCHAR2(n)
Texto de anchura fija para NATIONAL CHARACTER(n) NATIONAL NCHAR(n)
caracteres nacionales CHAR(n) NCHAR(n)
Texto de anchura variable NATIONAL CHARACTER VARYING(n) NVARCHAR2(n)
para caracteres nacionales NATIONAL CHAR VARYING(n)
NCHAR VARYING(n)
Números
Enteros pequeños (2 bytes) SMALLINT
Enteros normales (4 bytes) INTEGER INT
Enteros largos (8 bytes) BIGINT
(en realidad no es estándar, pero es muy
utilizado en muchas bases de datos)
Enteros NUMBER(n)
precisión
decimal
Decimal de coma variable FLOAT NUMBER
DOUBLE
DOUBLE PRECISSION
REAL
Decimal de coma fija NUMERIC(m,d) DECIMAL(m,d) NUMBER(m,d)
Fechas
Fechas DATE DATE
Fecha y hora TIMESTAMP TIMESTAMP
Intervalos INTERVAL INTERVAL
En definitiva, la precisión debe incluir todos los dígitos del número (puede llegar hasta 38
dígitos). La escala sólo indica los decimales que se respetarán del número, pero si es negativa
indica ceros a la izquierda del decimal.
- Fechas y horas
DATE. El tipo DATE permite almacenar fechas. Las fechas se pueden escribir en formato
día, mes y año entre comillas. El separador puede ser una barra de dividir, un guión y casi
cualquier símbolo. Para almacenar la fecha actual la mayoría de bases de datos
proporcionan funciones (como SYSDATE en Oracle) que devuelven ese valor. Las fechas
no se pueden manejar directamente, normalmente se usan funciones de conversión. En el
caso de Oracle se suele usar TO_DATE (que se detallará en el tema siguiente). Ejemplo:
TO_DATE(‘3/5/2007’)
TIMESTAMP. Es una extensión del anterior, almacena valores de día, mes y año, junto
con hora, minuto y segundos (incluso con decimales). Con lo que representa un instante
concreto en el tiempo. Un ejemplo de TIMESTAMP sería ‘2/2/2004 18:34:23,34521’. En
este caso si el formato de fecha y hora del sistema está pensado para el idioma español,
el separador decimal será la coma (y no el punto).
- Intervalos
Sirven para almacenar intervalos de tiempo (no fechas, sino una suma de elementos de
tiempo). En el caso de Oracle son:
INTERVAL YEAR TO MONTH. Este tipo de datos almacena años y meses. Tras la palabra
YEAR se puede indicar la precisión de los años (cifras del año), por defecto es de dos Para
los intervalos de año a mes los valores se pueden indicar de estas formas:
/* 123 años y seis meses */
INTERVAL '123-6' YEAR TO MONTH
/* 123 años */
INTERVAL '123' YEAR TO MONTH
/* 6 meses */
INTERVAL '6' MONTH TO MONTH
INTERVAL DAY TO SECOND
Representa intervalos de tiempo que expresan días, horas, minutos y segundos. Se puede
indicar la precisión tras el texto DAY y el número de decimales de los segundos tras el
texto SECOND.
Ejemplos:
/* 4 días 10 horas 12 minutos y 7 con 352 segundos */ /*12 minutos*/
INTERVAL '4 10:12:7,352' DAY TO SECOND(3) INTERVAL '12' MINUTE
/* 4 días 10 horas 12 minutos */ /*30 segundos */
INTERVAL '4 10:12' DAY TO MINUTE INTERVAL '30' SECOND
/* 4 días 10 horas */ /*8 horas y 50 minutos */
INTERVAL '4 10' DAY TO HOUR INTERVAL '8:50’ HOUR TO MINUTE;
/* 4 días*/ /*7 minutos 6 segundos*/
INTERVAL '4' DAY INTERVAL '7:06' MINUTE TO SECOND;
/*10 horas*/ /*8 horas 7 minutos 6 segundos*/
INTERVAL '10' HOUR INTERVAL '8:07:06' HOUR TO SECOND;
/*25 horas*/
INTERVAL '253' HOUR
Ligaduras
Esto de las ligaduras es muy importante que le presenten atención. Ayuda a que dejes la
vigilancia de la entrada de datos al DBMS y no al que programa la aplicación que a veces
puede darse que no haga tal validación en la entrada de los datos.
Esto tiene la ventaja de ahorrar líneas de códigos en los programas y no te que se
implementan en la sentencia SQL CREATE TABLE .
Tipo: INTEGRIDAD DE DOMINIO O COLUMNA
Especifica un conjunto de valores que son válidos a ingresar sobre una columna específica para una tabla de la base de
datos . Esta integridad se verifica a través de una la validación de los valores de datos que se ingresan y el tipo de los
datos a introducir (numérico, alfanumérico, alfabético, etc.).
Tipos de
Descripción Cláusula SQL
Restricción
DEFAULT
Por ejemplo, sí las reglas del negocio dicen que no se
Esta restricción asigna un valor específico a contratan a menores de edad, en la columna EDAD en
una columna cuando el valor para ello no haya la tabla EMPLEADO se restringe a que si una edad para
Por Defecto sido explícitamente proporcionado para tal un empleado que ingresa no es señalada
columna en una sentencia “INSERT” o de explícitamente, el DBMS asigne 18 que es la mayoría
adición de un nuevo registro en la tabla. de edad.
CREATE TABLE EMPLEADO (ID_EMPL int Primary KEY,
EDAD int not null default 18)
CHECK
CREATE TABLE EMPLEADO ( ID INT PRIMARY KEY,
Por Específica los valores de datos que el DBMS EDAD INT DEFAULT 18, SEXO VARCHAR(1) CHECK (
Validación acepta le sean ingresados para una columna. SEXO IN (‘F’,’M’) ) )
Por ejemplo, la columna SEXO, solo permitirá el ingreso
del carácter F o M.
REFERENCES
CREATE TABLE JOBS (job_id int primary key not null,
func_id int unique)
Especifica los valores de datos que son CREATE TABLE EMPLEADO ( ID INT PRIMARY KEY,
Por aceptables para actualizar una columna y que EDAD INT DEFAULT 18, SEXO VARCHAR(1) CHECK (
Referencia están basados en valores de datos localizados SEXO IN (‘F’,’M’) ) , NO_FUNC int REFERENCES
en una columna de otra tabla. jobs(func_id))
El valor de lo que entre en la columna NO_FUNC en la
tabla EMPLEADO deberá ser uno de los valores
contenido en la columna FUNC_ID en la Tabla JOBS.
Dominios
En Oracle se echa de menos una instrucción que forma parte del estándar SQL y que
permite crear dominios. Sin embargo en SQL estándar sí hay esa posibilidad y de hecho
es muy interesante. Se trata de CREATE DOMAIN:
Ejemplo:
CREATE DOMAIN Tdireccion AS VARCHAR(3);
Gracias a esa instrucción podemos crear la siguiente tabla:
CREATE TABLE Empleado(
rut SMALLINT, nombreP VARCHAR(30), apellido VARCHAR(30),
direccion Tdireccion
)
A continuación se muestran las sentencias CREATE TABLE que crean las tablas de la
Base de Datos “bdempleados”, de la cual ya se creo en MySQL al principio de esta
guía.
- Ingresamos al Explorador de MySQL y creamos un nuevo srcip
Es muy importante el orden en que se crean las tablas. Se debe a que no debe violarse
la referencia cruzada entre las ligaduras de integridad del tipo referencial (es decir llave
primaria con foráneas). Por ejemplo no puede crear la tabla de EMPLEADOS primero que la
tabla de DEPARTAMENTOS, pues la tabla de EMPLEADOS hace referencia a DEPARTAMENTOS.
Primero crear las tablas que solo tienen llave primaria y luego las tablas que incluyen
llaves foráneas.
- Creación de Tabla (Seleccionar la base de dato de MySQL a usar)
ELIMINACIÓN DE TABLAS:
La sentencia para eliminar una tabla y por ende todo los objetos asociados con esa tabla
como: las vistas, disparadores, etc., DROP TABLE, donde r es el nombre de una tabla
existente.
Al borrar una tabla:
Desaparecen todos los datos
Cualquier vista y sinónimo referente a la tabla seguirá existiendo, pero ya no
funcionará (conviene eliminarlos)
Las transacciones pendientes son aceptadas (COMMIT), en aquellas bases de datos
que tengan la posibilidad de utilizar transacciones.
Lógicamente, sólo se pueden eliminar las tablas sobre las que tenemos permiso de
borrado.
Normalmente, el borrado de una tabla es irreversible, y no hay ninguna petición de
confirmación, por lo que conviene ser muy cuidadoso con esta operación.
DROP TABLE r
Por ejemplo si deseamos eliminar a la tabla LocalidadDpt, revisemos haber si esta ya
existe, de la siguiente manera
SELECT * FROM LocalidadDpt
Posteriormente una vez veriifcada que la tabla existe, se procede a borrar la tabla,
escribiendo lo siguiente en la interface de consultas del SQL:
DROP TABLE LocalidadDpt
MODIFICAR TABLAS
Después que una tabla ha sido utilizada durante algún tiempo, los usuarios suelen
descubrir que desean almacenar información adicional con respecto a las tablas. Por
ejemplo en la base de datos EMPLEADOS, se podría desear:
- Añadir el nombre y número de una persona de contacto a cada fila de la tabla EMPLEADOS para
contactar a los empleados.
- Añadir una columna de punto de re orden mínimo en la tabla PROYECTO, para que la base de
datos pueda alertar automáticamente cuando la cantidad de presupuesto asignado a un
proyecto en particular esta por debajo de lo optimo para su viabilidad.
Por lo general, esta sentencia ALTER TABLE se utiliza sobre tablas que ya poseen desde
cientos a miles de filas por ser tablas de un sistemas de Base de Datos que ya esta en
producción. Los cambios que se pueden realizar con la sentencia SQL ALTER TABLE son
(ver ejemplo con la figura) :
(1) Cambiar de nombre a una tabla. De forma estándar (SQL estándar) se hace:
(2) Borrar contenido de tablas. Oracle dispone de una orden no estándar para
eliminar definitivamente los datos de una tabla; es la orden TRUNCATE TABLE
seguida del nombre de la tabla a borrar. Hace que se elimine el contenido de la tabla,
pero no la estructura de la tabla en sí. Incluso borra del archivo de datos el espacio
ocupado por la tabla.
(3) Añadir columnas. Añadir una definición de la columna de una tabla. Puede crearse
con valores nulos o valores
Permite añadir nuevas columnas a la tabla. Se deben indicar su tipo de datos y sus
propiedades si es necesario (al estilo de CREATE TABLE). Las nuevas columnas se
añaden al final, no se puede indicar otra posición (hay que recordar que el orden de
las columnas no importa). Ejemplo:
ALTER TABLE T1 ADD (a6 VARCHAR(30) NULL); ALTER TABLE facturas ADD (fecha DATE);
Muchas bases de datos (pero no Oracle) requieren escribir la palabra COLUMN tras
la palabra ADD. Normalmente suele ser opcional
(4) Borrar columnas. Eliminar una columna de la tabla. Pero antes de su eliminación
deben ser eliminados por ALTER TABLE todas las restricciones que estén definidas
sobre esta columna.
La tabla representa la tabla a la que queremos añadir el registro y los valores que
siguen a VALUES son los valores que damos a los distintos campos del registro. Si no se
especifica la lista de campos, la lista de valores debe seguir el orden de las columnas
según fueron creados (es el orden de columnas según las devuelve el comando
DESCRIBE).
La lista de campos a rellenar se indica si no queremos rellenar todos los campos. Los
campos no rellenados explícitamente con la orden INSERT, se rellenan con su valor por
defecto (DEFAULT) o bien con NULL si no se indicó valor alguno. Si algún campo tiene
restricción de obligatoriedad (NOT NULL), ocurrirá un error si no rellenamos el campo
con algún valor.
Por ejemplo, supongamos que tenemos una tabla de empleados cuyos campos son: dni,
nombreP, apellido1, apellido2, Sexo y dirección; supongamos que ese es el orden de
creación de los campos de esa tabla y que la localidad tiene como valor por defecto
Masculino y la dirección no tiene valor por defecto. En ese caso estas dos instrucciones
son equivalentes:
INSERT INTO empleados VALUES( '11111111','Pedro','Gutiérrez',
'Masculino',DEFAULT,NULL);
INSERT INTO empleados (dni,nombreP,apellido1,apellido2)
VALUES('11111111','Pedro','Gutiérrez', ' Masculino ');
Son equivalentes puestos que en la segunda instrucción los campos no indicados se
rellenan con su valor por defecto y la dirección no tiene valor por defecto. La palabra
DEFAULT fuerza a utilizar ese valor por defecto.
El uso de los distintos tipos de datos debe de cumplir los requisitos ya comentados en
apartados anteriores.
ACTUALIZACIÓN DE REGISTROS
La modificación de los datos de los registros lo implementa la instrucción
UPDATE. Sintaxis:
BORRADO DE REGISTROS
Se realiza mediante la instrucción DELETE:
Es más sencilla que las anteriores, elimina los registros de la tabla que cumplan
la condición indicada.
Ejemplo: DELETE FROM empleados WHERE seccion=23;
Hay que tener en cuenta que el borrado de un registro no puede provocar fallos de
integridad y que la opción de integridad ON DELETE CASCADE hace que no sólo se
borren los registros indicados en el SELECT, sino todos los relacionados.
TRANSACCIONES
Una transacción está formada por una serie de instrucciones DML. Una transacción
comienza con la primera instrucción DML que se ejecute y finaliza con alguna de estas
circunstancias:
- Una operación COMMIT o ROLLBACK
- Una instrucción DDL (como ALTER TABLE por ejemplo)
- Una instrucción DCL (como GRANT)
- El usuario abandona la sesión
- Caída del sistema
Hay que tener en cuenta que cualquier instrucción DDL o DCL da lugar a un COMMIT
implícito, es decir todas las instrucciones DML ejecutadas hasta ese instante pasan a ser
definitivas.
COMMIT La instrucción COMMIT hace que los cambios realizados por la transacción sean
definitivos, irrevocables. Sólo se debe utilizar si estamos de acuerdo con los cambios,
conviene asegurarse mucho antes de realizar el COMMIT ya que las instrucciones ejecutadas
pueden afectar a miles de registros. Además el cierre correcto de la sesión da lugar a un
COMMIT, aunque siempre conviene ejecutar explícitamente esta instrucción a fin de
asegurarnos de lo que hacemos.
ROLLBACK. Esta instrucción regresa a la instrucción anterior al inicio de la transacción,
normalmente el último COMMIT, la última instrucción DDL o DCL o al inicio de sesión. Anula
definitivamente los cambios, por lo que conviene también asegurarse de esta operación. Un
abandono de sesión incorrecto o un problema de comunicación o de caída del sistema dan
lugar a un ROLLBACK implícito.
Estado de los datos durante la transacción
Si se inicia una transacción usando comandos DML hay que tener en cuenta que:
- Se puede volver a la instrucción anterior a la transacción cuando se desee
- Las instrucciones de consulta SELECT realizadas por el usuario que inició la transacción
muestran los datos ya modificados por las instrucciones DML
- El resto de usuarios ven los datos tal cual estaban antes de la transacción, de hecho los
registros afectados por la transacción aparecen bloqueados hasta que la transacción finalice.
Esos usuarios no podrán modificar los valores de dichos registros.
- Tras la transacción todos los usuarios ven los datos tal cual quedan tras el fin de transacción.
Los bloqueos son liberados y los puntos de ruptura borrados.
El ejemplo crea un índice para los campos apellido1, apellido2 y nombre. Esto no es lo
mismo que crear un índice para cada campo, este índice es efectivo cuando se buscan u
ordenan clientes usando los tres campos (apellido1, apellido2, nombre) a la vez.
Se aconseja crear índices en campos que:
- Contengan una gran cantidad de valores
- Contengan una gran cantidad de nulos
- Sean parte habitual de cláusulas WHERE, GROUP BY u ORDER BY
- Seann parte de listados de consultas de grandes tablas sobre las que casi siempre se
muestran como mucho un 4% de su contenido.
No se aconseja en campos que:
- Pertenezcan a tablas pequeñas
- No se usen a menudo en las consultas
- Pertenecen a tablas cuyas consultas muestran menos de un 4% del total de registros
- Pertenecen a tablas que se actualizan frecuentemente
Se utilizan en expresiones
Los índices se pueden crear utilizando expresiones complejas:
CREATE INDEX nombre_complejo ON empleados (UPPER(nombre));
Esos índices tienen sentido si en las consultas se utilizan exactamente esas expresiones.
LISTA DE ÍNDICES.Para ver la lista de índices en Oracle se utiliza la vista
USER_INDEXES. Mientras que la vista USER_IND_COLUMNS Muestra la lista de
columnas que son utilizadas por índices.
BORRAR ÍNDICES. La instrucción DROP INDEX seguida del nombre del índice permite
eliminar el índice en cuestión.
Secuencias
Una secuencia sirve para generar automáticamente números distintos. Se utilizan para
generar valores para campos que se utilizan como clave forzada (claves cuyo valor no
interesa, sólo sirven para identificar los registros de una tabla). Es decir se utilizan en
los identificadores de las tablas (campos que comienzan con la palabra id), siempre y
cuando no importe qué número se asigna a cada fila. Es una rutina interna de la base de
datos la que realiza la función de generar un número distinto cada vez. Las secuencias
se almacenan independientemente de la tabla, por lo que la misma secuencia se puede
utilizar para diversas tablas.
CREACIÓN DE SECUENCIAS
Sintaxis:
Donde:
- secuencia. Es el nombre que se le da al objeto de secuencia
- INCREMENT BY. Indica cuánto se incrementa la secuencia cada vez que se usa. Por defecto
se incrementa de uno en uno
- START WITH. Indica el valor inicial de la secuencia (por defecto 1)
- MAXVALUE. Máximo valor que puede tomar la secuencia. Si no se toma NOMAXVALUE que
permite llegar hasta el 1027
- MINVALUE. Mínimo valor que puede tomar la secuencia. Por defecto -1026
- CYCLE. Hace que la secuencia vuelva a empezar si se ha llegado al máximo valor.
Ejemplo:
CREATE SEQUENCE numeroPlanta INCREMENT 100 STARTS WITH 100 MAXVALUE 2000;
VER LISTA DE SECUENCIAS
La vista del diccionario de datos de Oracle USER_SEQUENCES muestra la lista de
secuencias actuales. La columna LAST_NUMBER muestra cual será el siguiente número
de secuencia disponible
USO DE LA SECUENCIA
Los métodos NEXTVAL y CURRVAL se utilizan para obtener el siguiente número y el
valor actual de la secuencia respectivamente. Ejemplo de uso (Oracle):
SELECT numeroPlanta.NEXTVAL FROM DUAL;
En SQL estándar: SELECT nextval(‘numeroPlanta’);
Eso muestra en pantalla el siguiente valor de la secuencia. Realmente NEXTVAL
incrementa la secuencia y devuelve el valor actual. CURRVAL devuelve el valor de la
secuencia, pero sin incrementar la misma.
Ambas funciones pueden ser utilizadas en:
- Una consulta SELECT que no lleve DISTINCT, ni grupos, ni sea parte de una vista, ni sea
subconsulta de otro SELECT, UPDATE o DELETE
- Una subconsulta SELECT en una instrucción INSERT
- La cláusula VALUES de la instrucción INSERT
- La cláusula SET de la instrucción UPDATE
No se puede utilizar (y siempre hay tentaciones para ello) como valor para la cláusula
DEFAULT de un campo de tabla.
Su uso más habitual es como apoyo al comando INSERT (en Oracle):
INSERT INTO plantas(num, uso) VALUES(numeroPlanta.NEXTVAL, 'Suites');
MODIFICAR SECUENCIAS
Se pueden modificar las secuencias, pero la modificación sólo puede afectar a
los futuros valores de la secuencia, no a los ya utilizados. Sintaxis:
BORRAR SECUENCIAS
Lo hace el comando DROP SEQUENCE seguido del nombre de la secuencia a borrar.
LISTA DE SECUENCIAS
En SQL estándar, a través de INFORMATION_SCHEMA.SEQUENCES podemos
acceder a la información sobre todas las secuencias creadas. En Oracle se hace
mediante la vista USER_SEQUENCES permite observar la lista de secuencias del
usuario.
Sinónimos
En Oracle, un sinónimo es un nombre que se asigna a un objeto cualquiera.
Normalmente es un nombre menos descriptivo que el original a fin de facilitar la
escritura del nombre del objeto en diversas expresiones.
CREACIÓN
objeto es el objeto al que se referirá el sinónimo. La cláusula PUBLIC hace que el
sinónimo esté disponible para cualquier usuario (sólo se permite utilizar si disponemos
de privilegios administrativos).
BORRADO
LISTA DE SINÓNIMOS. La vista USER_SYNONYMS permite observar la lista de sinónimos
del usuario, la vista ALL_SYNONYMS permite mostrar la lista completa de sinónimos
de todos los esquemas a los que tenemos acceso.
CONSULTAS SIMPLES
El corazón o poder del Lenguaje SQL es el poder hacer consultas de cualquier tipo a la
base de datos en forma no procedural. La sentencia SELECT es muy poderosa y
ampliamente rica en sus cláusulas y variantes permitiendo la capacidad de atender en
poco tiempo a consultas complejas sobre la base de datos. Está en el especialista
desarrollador de aplicaciones conocerlo a profundidad para explotar las bondades y
virtudes.
Se trata de una instrucción que toma como parámetros de entrada una o mas tablas, y
devuelve como resultado una nueva tabla, generada dinámicamente, que contiene la
información solicitada. El resultado puede ser desde una tabla con una única fila y una
única columna (es decir, un único valor) hasta una tabla con múltiples filas y columnas.
Gracias a esta sentencia es que se pueden realizar todas las operaciones del Algebra
Relacional. En esta sección veremos la sintaxis de como se utiliza. La sentencia SELECT,
obtiene filas de la base de datos y permite realizar la selección de una o varias filas o
columnas de una o varias tablas.
Veamos cales son las funciones de cada una de las cláusulas de la sentencia SELECT.
- La cláusula SELECT: permite especificar la información a recuperar exactamente, y, de ser
necesario, el procesamiento que debe ser realizado sobre esos datos
Lista las columnas de las tablas que se desean ver en el resultado de una consulta. Además de
las columnas se pueden listas columnas a calcular por el SQL cuando actué la sentencia. Esta
cláusula no puede omitirse.
- La cláusula FROM: permite especificar la tabla o tablas de la base de datos desde donde se va
a recuperar la información que se necesita.
Lista las tablas que deben ser analizadas en la evaluación de la expresión de la cláusula WHERE
y de donde se listarán las columnas enunciadas en el SELECT. Esta cláusula no puede omitirse.
- La cláusula WHERE: permite especificar un conjunto de condiciones para la selección de los
datos que se recuperarán de las tablas para elaborar el resultado
Establece criterios de selección de ciertas filas en el resultado de la consulta gracias a las
condiciones de búsqueda. Si no se requiere condiciones de búsqueda puede omitirse y el
resultado de la consulta serán todas las filas de las tablas enunciadas en el FROM.
- La cláusula GROUP BY: especifica una consulta sumaria. En vez de producir una fila de
resultados por cada fila de datos de la base de datos, una consulta sumaria agrupa todas las
filas similares y luego produce una fila sumaria de resultados para cada grupo de los nombres
de columnas enunciado en esta cláusula. En otras palabras, esta cláusula permitirá agrupar un
conjunto de columnas con valores repetidos y utilizar las funciones de agregación sobre las
columnas con valores no repetidas. Esta cláusula puede omitirse.
- La cláusula HAVING: le dice al SQL que incluya sólo ciertos grupos producidos por la cláusula
GROUP BY en los resultados de la consulta. Al igual que la cláusula WHERE, utiliza una
condición de búsqueda para especificar los grupos deseados. La cláusula HAVING es la
encargada de condicionar la selección de los grupos en base a los valores resultantes en las
funciones agregadas utilizadas debidas que la cláusula WHERE condiciona solo para la selección
de filas individuales. Esta cláusula puede omitirse.
- La cláusula ORDER BY: permite especificar el orden en el que va a ser presentada la
información en la tabla resultante
Establecer la columna o columnas sobre las cuales las filas resultantes de la consulta deberán
ser ordenadas.
En realidad, no todas estas cláusulas deben aparecer obligatorias en una consulta
Select. Sólo las cláusulas SELECT y FROM son imprescindibles para formar una consulta
Select mínima. Muestra como resultado a todas las filas existentes en las tablas
especificadas en el FROM.
Supongamos que queremos recuperar el NSS y el nombre completo (nombre de pila +
apellidos) de todos los empleados de la empresa. Una consulta que lo permite sería la
siguiente:
SELECT NSS, NPila, Ap1, Ap2 FROM Empleado
...y el resultado de evaluar la consulta sería el siguiente:
¿Cómo se obtiene esta tabla? Una consulta Select se evalúa de la siguiente manera:
1. En primer lugar, se evalúa la cláusula FROM: es necesario determinar de qué tabla
vamos a recuperar la información: por ejemplo, EMPLEADO.
2. A continuación, se accede a la tabla indicada, y se recuperan, una a una, todas sus
filas, sobre las que será evaluada, una por una, la cláusula SELECT: cada fila de la
tabla original (EMPLEADO) va a dar lugar a una nueva fila en la tabla que contendrá el
resultado de la consulta.
3. La cláusula SELECT debe contener una lista de una o más expresiones, separadas por
comas.
- Cada una de esas expresiones será evaluada sobre cada fila de la tabla original, dando
lugar a una lista de valores atómicos (tantos como expresiones)
- La lista obtenida servirá para crear una nueva fila en la tabla resultado.
- La tabla resultado tendrá una columna por cada expresión incluida en la cláusula SELECT
- El nombre de cada columna será igual a la expresión que la genera.
4. Serán expresiones válidas (expresiones que pueden ser utilizadas en la cláusula
SELECT):
- Un valor constante, de cualquiera de los tipos de datos admitidos en SQL: por
ejemplo „Juan‟, 5, 03/02/2004. El resultado de evaluar un valor constante sobre
una fila coincide siempre con el propio valor constante.
- Un nombre de columna de aquellos incluidos en la tabla indicada en el FROM: por
ejemplo, NSS, NPila, Ap1 o Ap2. Al evaluar un nombre de columna sobre una fila
determinada, el resultado será el valor de la fila en esa columna.
- Una expresión que incluya operaciones realizadas sobre valores constantes y/o
nombres de columnas. El resultado de la expresión será el mismo que el resultado
de evaluar primero los valores constantes y los nombres de columnas, y operarlos
después.
Por ejemplo:
2
(Resultado: 2)
2+3
(Resultado: 5)
‘Fede’ + ‘rico’
(Resultado: „Federico‟)
Ap1 + Ap2
(Resultado: dada una fila de la tabla original, la concatenación de los valores de sus
columnas Ap1 y Ap2)
‘Nombre:’ + NPila
(Resultado: dada una fila de la tabla original, la concatenación de la cadena
‘Nombre:’ y el valor de la fila en la columna NPila)
Si una consulta incluye la llave primaria (pk) de una tabla en su lista de selección,
entonces cada fila de resultados será única (ya que la llave primaria (pk) tiene un valor
diferente en cada fila). Si no se incluye la llave primaria en los resultados, pueden
producirse filas duplicadas.
Como último paso, las filas obtenidas se unen para obtener la tabla resultante:
Como se puede apreciar, las columnas tienen por nombre la expresión (incluida
en la cláusula SELECT) que da lugar a sus valores
La consulta que hemos visto utiliza expresiones en la cláusula SELECT que están
constituidas por simples nombres de columnas. Sin embargo, podemos realizar
consultas más sofisticadas incluyendo expresiones más complejas. Por ejemplo,
podemos modificar la consulta anterior para que el nombre completo de cada empleado
aparezca en una única columna:
SELECT NSS, Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila FROM Empleado
En esta nueva consulta, reemplazamos las tres expresiones que se referían a las
columnas de nombre y apellidos de los empleados por una expresión única, en la que se
utiliza el operador de concatenación de cadenas (+) para unir los valores de dichas
columnas, separados por espacios y comas: se trata de una expresión en la que se
combinan nombres de atributos y valores constantes („ „ y „,‟ ).
La consulta se evaluará de la siguiente forma:
Para la primera fila...
Como último paso, las filas obtenidas se unen para obtener la tabla resultante:
Las expresiones complejas no tienen por que utilizar sólo atributos o valores de tipo
carácter. La siguiente consulta devuelve el número mensual de horas que cada
empleado le dedica a cada proyecto (que se obtienen multiplicando por 4 el número de
horas semanal por proyecto, almacenado en la tabla TrabajaEn):
SELECT NSS, Numero, Horas* 4 FROM TrabajaEn
Veremos a continuación dos ejemplos del uso de la cláusula ORDER BY para precisar
mejor su funcionamiento.
Ejemplo: Obtener la lista de empleados de la empresa, ordenados alfabéticamente por
sus apellidos.
SELECT NSS, Ap1+ ‘ ‘ + Ap2 + ‘,’ + Npila FROM Empleado ORDER BY Ap1, Ap2, Nombre
Esta consulta se evalúa de la siguiente forma:
Para cada fila de la tabla Empleado se evalúan las expresiones de ordenación:
Las filas se ordenan empleando la primera expresión (Ap1), de forma ascendente (la
opción por defecto):
Como se puede observar, dos filas (las correspondientes a María y Pedro) presentan en
mismo valor para Ap1. Para decidir su orden, recurrimos a la segunda expresión (Ap2)
Ejemplo: Indicar los NSS de todos los empleados de la empresa, ordenados por
departamento y por edad (los más jóvenes primero).
Ordenar por edad, de forma ascendente, implica ordenar por fecha de nacimiento (el
dato que poseemos sobre los empleados) de forma descendente. Por lo tanto, la
consulta a realizar sería esta:
SELECT NSS, NumDept FROM Empleado ORDER BY NumDept, Fnac DESC
Obsérvese el uso que se hace del modificador DESC para exigir que las filas se ordenen
por fecha de forma descendente (de mayor a menor, en lugar de de menor a mayor)
El resultado de la consulta sería el siguiente:
(Se da la casualidad en el ejemplo que el orden solicitado en origen para las tuplas es
aquel en el que las habíamos presentado inicialmente).
FILAS REPETIDAS:
El modificador DISTINCT
Supongamos que necesitamos conocer las diferentes localidades en las que nuestra
empresa dispone de alguna sede. En la base de datos contamos con información
referente a las sedes de los departamentos de la empresa (concretamente, en la tabla
LocalidadDpt); y conociendo las sedes de los departamentos, conoceremos las de la
empresa (ya que, en buena lógica, deben coincidir). Por lo tanto, la siguiente consulta
debería servir a nuestros fines:
SELECT Loc FROM LocalidadDpt
Como en los casos anteriores, la consulta se evalúa recuperando una por una las filas de
la tabla indicada y evaluando las expresiones de la cláusula SELECT sobre cada una de
ellas:
Como se puede apreciar, una de las localidades aparece repetida: se trata de A Coruña,
como resultado de ser obtenida como sede de dos departamentos diferentes. Esto es así
porque SQL incumple la restricción de clave del modelo relacional, que exige que en una
relación (una tabla) no puede haber filas repetidas. Así, al verse liberado de la obligación
de comprobar esta restricción, cualquier intérprete de SQL podrá procesar una consulta
mucho más rápidamente.
Sin embargo, SQL sí que permite eliminar filas repetidas en el resultado de una consulta
(aunque provocando, probablemente, un retraso adicional por parte del intérprete en la
obtención del resultado final).
Para hacerlo, la cláusula SELECT cuenta con el modificador distinct: añadiendo este
modificador a nuestra consulta...
SELECT DISTINCT Loc
FROM LocalidadDpt
...el resultado de la misma pasaría a ser este:
Si bien en la columna NumDept hay varios valores repetidos, no hay ninguna fila
repetida; por lo tanto, la presencia o no de distinct en la consulta no afecta al resultado
final.
Versión abreviada del SELECT
Es bastante usual encontrarse en la necesidad de recuperar toda la información
contenida en una tabla. Hacerlo por medio de una consulta SQL implicaría escribir uno
por uno todos los nombres de sus columnas en la cláusula SELECT:
SELECT NSS, Npila, Ap1, Ap2, Sexo, Direccion, Fnac, NumDept, NSSSupervisor
FROM Empleado
Para evitar esto, la cláusula SELECT admite un carácter comodín, que representa a todas
las columnas de una tabla: el asterisco (*). Así, la siguiente consulta sería equivalente a
la anterior: SELECT * FROM Empleado
Cálculos
Además de las columnas cuyos valores serán introducidos a la base de datos a través de
la sentencia INSERT, una consulta SQL puede incluir en su cláusula SELECT columnas
calculadas cuyo valor se calculan a partir de los valores de las otras columnas
almacenadas en las tablas. Estas columnas, son especie de una columna virtual pues no
existen físicamente en la tabla y sus valores calculados corresponden a los valores por
fila. Esta es una ventaja del SQL que evita que se tengan que diseñar columnas
calculadas físicas en la base de datos trayendo perdida en almacenamiento físico y
inconsistencia por falta de mantenimiento de la misma.
ARITMÉTICOS
Los operadores + (suma), - (resta), * (multiplicación) y / (división), se pueden utilizar
para hacer cálculos en las consultas. Cuando se utilizan como expresión en una consulta
SELECT, no modifican los datos originales sino que como resultado de la vista generada
por SELECT, aparece un nueva columna. Ejemplo:
SELECT nombre, precio,precio*1.16 FROM articulos;
Esa consulta obtiene tres columnas. La tercera tendrá como nombre la expresión
utilizada, para poner un alias basta utilizar dicho alias tras la expresión:
SELECT nombre, precio, precio*1.16 AS precio_con_iva FROM articulos;
La prioridad de esos operadores es la normal: tienen más prioridad la multiplicación y
división, después la suma y la resta. En caso de igualdad de prioridad, se realiza primero
la operación que esté más a la izquierda. Como es lógico se puede evitar cumplir esa
prioridad usando paréntesis; el interior de los paréntesis es lo que se ejecuta primero.
Cuando una expresión aritmética se calcula sobre valores NULL, el resultado es el
propio valor NULL. Se puede utilizar cualquiera de los operadores aritméticos: suma
(+), resta (-), multiplicación (*), división (/). Como es habitual, la multiplicación y la
división tienen preferencia sobre la suma y la resta en el orden de ejecución de la
instrucción; dicho orden se puede alterar mediante el uso de los paréntesis.
CONCATENACIÓN DE TEXTOS
Todas las bases de datos incluyen algún operador para encadenar textos. En
SQLSERVER es el signo + en Oracle son los signos ||.
Ejemplo (Oracle): SELECT tipo, modelo, tipo || '-' || modelo "Clave Pieza" FROM piezas;
El resultado sería:
TIPO MODELO Clave Pieza
AR 6 AR-6
AR 7 AR-7
AR 8 AR-8
AR 9 AR-9
AR 12 AR-12
AR 15 AR-15
AR 20 AR-20
AR 21 AR-21
BI 10 BI-10
BI 20 BI-20
BI 22 BI-22
BI 24 BI-24
Condiciones
La cláusula WHERE
Se pueden realizar consultas que restrinjan los datos de salida de las tablas. Para ello se
utiliza la cláusula WHERE. Esta cláusula permite colocar una condición que han de
cumplir todos los registros, los que no la cumplan no aparecen en el resultado.
La cláusula WHERE permite afinar en mayor medida la recuperación de información
mediante una instrucción SELECT. Hasta ahora hemos visto cómo seleccionar cuáles de
las columnas de una tabla nos interesan; mediante WHERE podremos seleccionar
cuáles de las filas contenidas en una tabla nos interesan.
Eso nos permitirá, por ejemplo, restringir cualquiera de las consultas que hemos
realizado hasta ahora a los empleados de un determinado departamento. Así, la consulta
siguiente permitirá obtener el nombre de todos los empleados del departamento de
Ventas.
SELECT NSS, Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila FROM Empleado WHERE NumDept=’D01’
Para seleccionar las filas que nos interesen, la cláusula WHERE va acompañada de un
conjunto de condiciones de selección. Sólo las filas que cumplan esas condiciones serán
tenidas en cuenta para evaluar la consulta.
OPERADORES DE COMPARACIÓN
La condición de selección más sencilla que se puede definir es aquella que obliga a
comparar los valores de dos expresiones evaluadas sobre cada fila de la tabla. Se
pueden utilizar en la cláusula WHERE
La idea es que tanto Expresión1 como Expresión2 se evalúen sobre los valores de cada
fila de la tabla original. Una vez evaluados, se comparan. Si la condición especificada se
cumple, la fila se selecciona. Si la condición no se cumple, la fila es descartada.
Condiciones de Búsqueda
Operador Significado
> Mayor que
< Menor que
>= Mayor o igual que
<= Menor o igual que
= Igual
<> Distinto
!= Distinto
Se pueden utilizar tanto para comparar números como para comparar textos y fechas.
En el caso de los textos, las comparaciones se hacen en orden alfabético. Sólo que es un
orden alfabético estricto. Es decir el orden de los caracteres en la tabla de códigos.
En muchas bases de datos hay problemas con la Ñ y otros símbolos nacionales (en
especial al ordenar o comparar con el signo de mayor o menor, ya que la el orden ASCII
no respeta el orden de cada alfabeto nacional). No obstante es un problema que tiende
a arreglarse en la actualidad en todos los SGBD (en Oracle no existe problema alguno)
especialmente si son compatibles con Unicode.
En el caso del ejemplo
SELECT NSS, Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila FROM Empleado WHERE NumDept=’D01’
la evaluación se haría así:
En primer lugar, seleccionar las filas a utilizar para calcular el resultado, aplicando la
condición de selección del WHERE
Otro ejemplo podría ser este: Nombres de todos los empleados de la empresa que
hayan nacido antes que Pedro.
La consulta que nos permite obtener esa información es esta:
SELECT NPila FROM Empleado WHERE Fnac<23/12/50
Como se puede apreciar, ninguna fila de la tabla satisface la condición, por lo que el
resultado de la consulta será una tabla vacía: ¡Pedro es el empleado más viejo de la
empresa!
IS NULL
Los valores nulos también afectan a la evaluación de las condiciones de selección. La
evaluación de cualquier condición de selección en la que intervenga una expresión con
evaluación desconocida, será también desconocida.
Para una fila determinada, el resultado de una condición de búsqueda puede ser TRUE o
FALSE, o puede ser NULL debido a que una de las columnas utilizadas en la evaluación
de la condición de búsqueda contenga un valor NULL.
¿ 2 > Nulo ? -> Desconocido
¿ ‘Casa’ <> Nulo ? -> Desconocido
¿ NSS = 5 ? -> Desconocido (si NSS se evalúa a Nulo)
Siempre que no sea posible determinar si una condición se verifica para una
determinada fila, adoptaremos una postura conservadora: al ser desconocido el
resultado de la comparación, descartaremos la fila al calcular el resultado de la
condición, por si en un momento dado, y con más información, llegásemos a determinar
que la condición no se cumple.
Ejemplo: Recuperar el NSS de todos los empleados de la empresa que cuentan con un
supervisor. La consulta que nos permite obtener esta información es la siguiente:
SELECT NSS FROM Empleado WHERE NSSSupervisor > 0
…y se evalúa de la siguiente forma:
El problema es el siguiente: cualquier comparación con un valor nulo hará que una fila
sea descartada, precisamente lo contrario de lo que deseamos en este caso. Por
ejemplo, es fácil ver cómo la siguiente consulta...
SELECT NSS FROM Empleado WHERE NSSSupervisor = NULL
… devolvería como resultado una tabla vacía, por la propia semántica definida para la
cláusula WHERE: el operador de comparación = se evalúa a nulo si hay un nulo de por
medio, y en este caso todas las filas de la tabla original serían descartadas (en todas las
comparaciones intervendrá el valor NULL).
Para resolver este contratiempo, SQL permite una alternativa en forma de predicado
lógico2: IS NULL. Este predicado (asociado a un nombre de columna) nos permitirá
saber si el valor de dicha columna para una fila es nulo o no.
- Si el valor de la columna es nulo, IS NULL se evaluará como Verdadero
- Si el valor de la columna no es nulo, IS NULL se evaluará como Falso
Utilizando IS NULL en nuestro ejemplo, la consulta se resuelve así:
SELECT NSS FROM Empleado WHERE NSSSupervisor IS NULL
Y se evalúa de esta manera:
El predicado IS NULL presenta además una forma negada, que nos permite resolver de
forma más elegante la consulta original (la lista de empleados con jefe):
SELECT NSS FROM Empleado WHERE NSSSupervisor IS NOT NULL
Esta consulta se evalúa de esta manera:
2
Podemos entender un predicado como una función que devuelve como resultado un valor lógico
de Verdadero o Falso
Guia estudio práctica 5-GD-2019 Página 38
UNIVERSIDAD TECNOLOGICA NACIONAL - FACULTAD REGIONAL MENDOZA
CATEDRA: GESTION DE DATOS - INGENIERIA EN SISTEMAS DE INFORMACION
PROFESOR: María E. STEFANONI – JTP: Higinio A. FACCHINI – Matilde I. CESARI
VALORES LÓGICOS
La cláusula WHERE permite especificar condiciones más complejas de consulta, por
medio de las conectivas lógicas: AND , OR y NOT. Las conectivas lógicas permiten
combinar dos o más condiciones (simples o compuestas), de la siguiente forma:
Como se ve, solo hay un empleado que cumpla las dos condiciones. El resultado de la
consulta sería este:
Como se ve, solo hay un empleado que no cumple ninguna de las dos condiciones, y
que por lo tanto debe ser descartado. El resultado de la consulta sería este:
Ahora sí hemos conseguido descartar solamente a Pedro, que es el único empleado que
tiene a Juan por jefe.
Como hemos podido comprobar en este ejemplo, la presencia de valores nulos complica
siempre la realización de consultas. Se trata de uno de los motivos por los que – como
ya ha sido señalado en alguna ocasión – el diseño de las tablas de una BD debe ser
analizado detenidamente para evitar en lo posible la necesidad del uso de valores nulos.
BETWEEN El operador BETWEEN nos permite obtener datos que se encuentren en un
rango. Uso: SELECT tipo,modelo,precio FROM piezas WHERE precio BETWEEN 3 AND 8;
Saca piezas cuyos precios estén entre 3 y 8 (ambos incluidos).
IN Permite obtener registros cuyos valores estén en una lista de valores:
SELECT tipo,modelo,precio FROM piezas WHERE precio IN (3,5, 8);
Obtiene piezas cuyos precios sean 3, 5 u 8 (no valen ni el precio 4 ni el 6, por ejemplo).
LIKE Se usa sobre todo con textos, permite obtener registros cuyo valor en un campo
cumpla una condición textual. LIKE utiliza una cadena que puede contener estos
símbolos:
% Una serie cualquiera de caracteres
_ Un carácter cualquiera
Ejemplos:
/* Selecciona nombres que empiecen por S */
SELECT nombre FROM personas WHERE nombre LIKE 'S%';
/*Selecciona las personas cuyo apellido sea Sanchez, Senchez, Stnchez,...*/
SELECT apellido1 FROM Personas WHERE apellido1
LIKE 'S_nchez';
PRECEDENCIA DE OPERADORES
A veces las expresiones que se producen en los SELECT son muy extensas y es difícil
saber que parte de la expresión se evalúa primero, por ello se indica la siguiente tabla
de precedencia (tomada de Oracle):
Orden de
Operador
precedencia
1 *(Multiplicar) / (dividir)
2 + (Suma) - (Resta)
3 || (Concatenación)
4 Comparaciones (>, <, !=, ...)
5 IS [NOT] NULL, [NOT ]LIKE, IN
6 NOT
7 AND
8 OR
FUNCIONES
Todos los SGBD implementan funciones para facilitar la creación de consultas complejas.
Esas funciones dependen del SGBD que utilicemos, las que aquí se comentan son
algunas de las que se utilizan con Oracle.
Todas las funciones devuelven un resultado que procede de un determinado cálculo. La
mayoría de funciones precisan que se les envíe datos de entrada (parámetros o
argumentos) que son necesarios para realizar el cálculo de la función.
Este resultado, lógicamente depende de los parámetros enviados. Dichos parámetros se
pasan entre paréntesis.
De tal manera que la forma de invocar a una función es:
Si una función no precisa parámetros (como SYSDATE) no hace falta colocar los
paréntesis.
En realidad hay dos tipos de funciones:
- Funciones que operan con datos de la misma fila
- Funciones que operan con datos de varias filas diferentes (funciones de
agrupación).
En LA Página 122 Alvaro E. García Manual Práctico de SQL, ORIENTADO A SQL 7.0
(noviembre de 2003) se describen algunas de las funciones más interesantes.
Para que se puedan realizar consultas a múltiples tablas el requisito principal es que las
tablas a reunirse en una consulta tengan columnas con valores o dominios comunes, es
decir columna de conexión.
Si reunimos a las tablas de la figura, de tal forma que la Tabla1 se reúna con la Tabla2 y
la Tabla2 se reuniera con la Tabla3, el requisito indispensable sería: la Tabla1 debe
tener una columna común en la Tabla2 y Tabla2 debe tener una columna de conexión en
la Tabla3.
Por lo general estas columnas comunes son: en una tabla la columna es la llave primaria
y en la otra tabla la columna asociada es la llave foránea que referencia a la primaria.
Para este tipo de consultas a múltiples tablas la cláusula FROM es la responsable de
indicar cual será la(s) tabla(s) fuentes.
Existen dos formas de sintaxis permitidas para la escritura de la sentencia SELECT para
la reunión de tablas, basada en la figura 4.4.a, estas formas son las siguientes:
FORMA 1:
SELECT a1, a2, a5, b1, b2, b3, c1, c2, c3 FROM Tabla1, Tabla2, Tabla3
WHERE Tabla1.a1 = Tabla2.b2 AND Tabla2. b1 = Tabla3.c1
FORMA 2:
SELECT a1, a2, a5, b1, b2, b3, c1, c2, c3 FROM Tabla1
INNER JOIN Tabla2 ON Tabla1.a1 = Tabla2.b2
INNER JOIN Tabla3 Tabla2. b1 = Tabla3.c1
Note que las columnas comunes en ambas tablas han de calificarse con el nombre de la
tabla que pertenecen para evitar errores de ambigüedad.
La Forma 2, tiene la ventaja de liberar a la cláusula WHERE y dejar esta para filtros
específicos sobre las filas resultantes de la reunión de tablas.
Sin embargo, la evaluación de la consulta va a diferir ligeramente con respecto al
mecanismo que habíamos visto hasta ahora. Dicho mecanismo de evaluación constaba
de los siguientes pasos:
1. Determinar la tabla de origen, indicada en la cláusula FROM
2. Seleccionar aquellas filas que cumplen la condición o condiciones especificadas en la
cláusula WHERE
3. Ordenar las filas de la tabla original de acuerdo con lo especificado en la cláusula ORDER
BY
4. A partir de cada fila de la tabla original, generar una fila en la tabla resultante, a partir de
la evaluación de las expresiones indicadas en la cláusula SELECT
El mecanismo a seguir en el caso de consultas definidas sobre varias tablas va a ser
ahora:
1. Determinar las tablas de origen, indicadas en la cláusula FROM
2. Combinar las tablas originales, de forma que se genere una tabla única sobre la que
trabajar.
3. Seleccionar aquellas filas de la tabla original que cumplen la condición o condiciones
especificadas en la cláusula WHERE
4. Ordenar las filas de la tabla original de acuerdo con lo especificado en la cláusula ORDER
BY
5. A partir de cada fila de la tabla original, generar una fila en la tabla resultante, a partir de
la evaluación de las expresiones indicadas en la cláusula SELECT
Como se puede apreciar, los cambios (2 y 3) son mínimos: La esencia del cambio radica
en que vamos a obtener, de las tablas originales, una nueva tabla, única, sobre la que
trabajar.
Una vez obtenida esa tabla, podremos continuar procediendo como habíamos visto hasta
ahora: evaluando las cláusulas WHERE, ORDER BY y SELECT sobre una única tabla.
Evidentemente, la clave del correcto funcionamiento de la consulta está en la forma en
la que se realizará la combinación de las (dos o mas) tablas originales. La idea es
combinar las filas de una tabla con las filas que tenga asociadas en el resto de tablas. En
el caso de nuestro ejemplo, deberíamos intentar combinar cada fila correspondiente a un
empleado con la fila correspondiente a su departamento. De esta forma, en la tabla
combinada seguiríamos contando con una fila por cada empleado, que incluiría además
toda la información relativa a su departamento.
Como se puede apreciar, sería sencillo definir una consulta sobre la tabla combinada
para recuperar la información que se solicita en el ejemplo.
Como se ve en la figura, en la tabla resultante del primer paso han sido incluidas las
siguientes combinaciones:
- La fila del empleado 1 (Juan) ha sido combinada con las filas de los departamentos D01 y D02
- La fila del empleado 2 (Pedro) ha sido combinada con las filas de los departamentos D01 y D02
- La fila del empleado 3 (María) ha sido combinada con las filas de los departamentos D01 y D02
- La fila del empleado 4 (Antonio) ha sido combinada con las filas de los departamentos D01 y
D02
...resultando un total de 8 filas, tal y como habíamos calculado
El producto cartesiano a veces es útil para realizar consultas complejas, pero en el
caso normal no lo es. Necesitamos discriminar ese producto para que sólo aparezcan los
registros de empleados relacionadas con los de departamento. A eso se le llama asociar
(join) tablas
Como se puede ver, estamos dando dos usos a la tabla Empleado; o, dicho de otra
manera, estamos contemplando la tabla desde dos puntos de vista:
1. Tabla que mantiene información sobre los empleados de la empresa.
2. Tabla que mantiene información sobre los jefes de la empresa.
O lo que es lo mismo: estamos combinando una tabla ¡consigo misma!
Este hecho sugiere una posible vía para la elaboración de una consulta SQL que permita
obtener la información deseada: incluir dos veces la misma tabla (Empleado) en la
cláusula FROM; y combinar las “dos” tablas de forma que cada fila de un empleado se
una a la fila correspondiente a su jefe. De ese modo, la tabla resultante tendrá una fila
por cada empleado de la empresa, e incluirá en cada una de ellas el nombre del
empleado, y el nombre de su jefe: precisamente, la información que necesitamos.
La consulta a realizar sería esta:
SELECT Emp.Npila, Jefe.NPila FROM Empleado Emp, Empleado Jefe
WHERE Emp.NSSSupervisor = Jefe.NSS
Para poder entender la consulta, debemos aclarar una serie de cuestiones:
- Incluir dos veces a Empleado la misma tabla en la cláusula FROM nos da la ilusión de contar
con dos copias exactamente iguales de la tabla: una con información sobre empleados y otra
con información sobre jefes.
- Para poder diferenciar cada una de las “copias”, utilizaremos sendos alias de la tabla:
nombres (apodos) que le daremos a la tabla original cada vez que la incluyamos en la
cláusula FROM, y que utilizaremos en todo el resto de la consulta para referirnos a cada una
de las “copias” resultantes.
En el ejemplo, usamos el alias Emp para referirnos a la tabla Empleado en su papel de
contenedora de información sobre los empleados; y el alias Jefe para referirnos a
Empleado en su papel de contenedora de información sobre los jefes - supervisores - de
empleados.
- Cada vez que debamos referirnos a una columna de alguna de las “copias”, usaremos el alias
como prefijo para indicar de cuál de ellas. Si queremos acceder a un dato sobre un
empleado, usamos la “copia” Emp; y si queremos referirnos a un dato sobre un jefe, usamos
la “copia” Jefe.
- Para combinar los datos de cada empleado con los datos de su jefe, establecemos la condición
de reunión siguiente: una fila de la “copia” Emp y otra de la “copia” Jefe se unirán si la
segunda representa al jefe del empleado representado por la primera: es decir, si el NSS de
la segunda (Jefe.NSS) es igual al NSS del jefe indicado por la primera (Emp.NSSSupervisor).
Podemos verlo mejor acudiendo a los datos, y viendo cómo se combinan. Partimos de
dos “copias” idénticas de la tabla Empleado: Emp y Jefe
Nos quedamos, pues, con sólo dos filas, sobre las que evaluamos las expresiones del
SELECT:
Vistas
Una vista, en SQL, es una consulta a la que se le asigna un nombre. De ese modo
podemos utilizar una consulta como si fuese una tabla, e incluirla incluso en otras
consultas. La utilidad principal de las vistas es proporcionar una manera de dar
diferentes visiones de la BD a los diferentes usuarios de la misma3.
Lo veremos con un ejemplo: comprobaremos como mediante una vista podemos ampliar
la tabla Empleado permitiendo representar en ella un atributo derivado (la edad del
empleado), calculada con una función especial de SQL (datediff) que permite calcular la
diferencia en años entre dos fechas dadas.
La consulta que nos permite añadir esa columna a la tabla Empleado es esta:
SELECT *, DateDiff("yyyy", FNac,Now()) AS Edad
FROM Empleado
...con el siguiente resultado:
Para convertir esta consulta en una vista, utilizamos la instrucción de SQL CREATE
VIEW, que presenta la siguiente sintaxis:
CREATE VIEW <Nombre vista> AS <Consulta Select>
En el caso de nuestro ejemplo:
CREATE VIEW EmpleadoEdad AS
SELECT *, DateDiff("yyyy", FNac,Now()) AS Edad
FROM Empleado
Una vez definida la vista, ya podrá ser utilizada en cualquier consulta:
SELECT * FROM EmpleadoEdad
NOTA: Access no soporta la definición de vistas. En su lugar, todas las consultas
creadas en Access se convierten implícitamente en una vista.
3
Recordar el nivel externo de la arquitectura de la información, ya visto anteriormente
Guia estudio práctica 5-GD-2019 Página 52
UNIVERSIDAD TECNOLOGICA NACIONAL - FACULTAD REGIONAL MENDOZA
CATEDRA: GESTION DE DATOS - INGENIERIA EN SISTEMAS DE INFORMACION
PROFESOR: María E. STEFANONI – JTP: Higinio A. FACCHINI – Matilde I. CESARI
Implementación de la BD
Para cada caso, elija un motor de BD y explique el paso, a paso de su creación y
manipulación.
CASO PRACTICO 1: Gestión fondos de un museo
4
Libro, Desarrollo_de_Bases_de_Datos_2a_Ed
Guia estudio práctica 5-GD-2019 Página 57
UNIVERSIDAD TECNOLOGICA NACIONAL - FACULTAD REGIONAL MENDOZA
CATEDRA: GESTION DE DATOS - INGENIERIA EN SISTEMAS DE INFORMACION
PROFESOR: María E. STEFANONI – JTP: Higinio A. FACCHINI – Matilde I. CESARI
END IF;
END;
/
Por segundo disparador se muestra como ejemplo de TRIGGER, uno que comprueba que un restaurador
sólo trabaja en restauraciones de cuadros de pintores que tenga asignado. Se ejecutará antes de insertar en la
tabla REST. Consulta la tabla PUEDE_REST para hacer la comprobación, en el caso de que el pintor del cuadro
a restaurar no sea de los asignados al restautador, el TRIGGER no permitirá realizar la operación.
CHECK ('fecha_alta'<'fecha_baja')
);
Para controlar que un contratado supervisa como máximo a tres promotores, está el
siguiente TRIGGER, “Trigger_maximo_supervisiones”, que se ejecutará en la tabla
PROMOTORES cuando se inserte un nuevo vendedor promotor. Consulta la misma tabla
PROMOTORES. No permitirá realizar la operación en el caso de que el vendedor
contratado que se le quiera asignar como supervisor tenga ya tres promotores a
supervisar.
CREATE OR REPLACE TRIGGER Trigger_maximo_supervisiones
BEFORE INSERT ON PROMOTORES FOR EACH ROW
DECLARE
n_supervisiones INTEGER;
BEGIN
SELECT COUNT (*) INTO n_supervisiones
FROM PROMOTORES
WHERE (contratado =:new.contratado);
IF n_supervisiones>=3
THEN
RAISE_application_error (-20001, 'No se puede asignar este
Contratado como supervisor, ya esta supervisando ya a
tresvendedorespromotores');
END IF;
END;
/
En el apartado GROUP BY, se indican las columnas por las que se agrupa. La función de
este apartado es crear un único registro por cada valor distinto en las columnas del
grupo.
5
Fuente original: M2109 - Databases . Rafafel Camps Paré, Luís Alberto Casillas Santillán, Dolors Costal Costa, Marc
Gibert Ginestà, Carme Martín Escofet, Óscar Pérez Mora. Official Master in Free and Open Source Software Technology.
Open University of Catalonia
Guia estudio práctica 5-GD-2019 Página 63
UNIVERSIDAD TECNOLOGICA NACIONAL - FACULTAD REGIONAL MENDOZA
CATEDRA: GESTION DE DATOS - INGENIERIA EN SISTEMAS DE INFORMACION
PROFESOR: María E. STEFANONI – JTP: Higinio A. FACCHINI – Matilde I. CESARI
CONDICIONES HAVING
A veces se desea restringir el resultado de una expresión agrupada
Se utiliza la cláusula HAVING, que se ejecuta una vez realizados los grupos.
El orden de ejecución de la consulta marca lo que se puede utilizar con WHERE y lo que
se puede utilizar con HAVING:
Para evitar problemas estos podrían ser los pasos en la ejecución de una instrucción de
agrupación por parte del gestor de bases de datos
- Seleccionar las filas deseadas utilizando WHERE. Esta cláusula eliminará columnas
en base a la condición indicada
- Se establecen los grupos indicados en la cláusula GROUP BY
- Se calculan los valores de las funciones de totales (COUNT, SUM, AVG,...)
- Se filtran los registros que cumplen la cláusula HAVING
- El resultado se ordena en base al apartado ORDER BY.
Subconsultas
USO DE SUBCONSULTAS SIMPLES
Se trata de una técnica que permite utilizar el resultado de una tabla SELECT en otra
consulta SELECT. Permite solucionar consultas que requieren para funcionar el resultado
previo de otra consulta.
La sintaxis es:
Ejemplo:
SELECT nombre_empleado, paga FROM empleados
WHERE paga <
(SELECT paga FROM empleados WHERE nombre_empleado='Martina') ;
Lógicamente el resultado de la subconsulta debe incluir el campo que estamos
analizando. Se pueden realizar esas subconsultas las veces que haga falta:
SELECT nombre_empleado, paga FROM empleados WHERE paga <
(SELECT paga FROM empleados WHERE nombre_empleado='Martina') AND paga >
(SELECT paga FROM empleados WHERE nombre_empleado='Luis');
En realidad lo primero que hace la base de datos es calcular el resultado de la
subconsulta:
La última consulta obtiene los empleados cuyas pagas estén entre lo que gana Luís
(1870 euros) y lo que gana Martina (2500) .
Las subconsultas siempre se deben encerrar entre paréntesis y se debería colocar a la
derecha del operador relacional. Una subconsulta que utilice los valores >,<,>=,... tiene
que devolver un único valor, de otro modo ocurre un error. Además tienen que tener el
mismo tipo de columna para relacionar la subconsulta con la consulta que la utiliza (no
puede ocurrir que la subconsulta tenga dos columnas y ese resultado se compare
usando una sola columna en la consulta general).
CONSULTAS EXISTS
Este operador devuelve verdadero si la consulta que le sigue devuelve algún valor. Si
no, devuelve falso. Se utiliza sobre todo en consultas correlacionadas
Normalmente las consultas EXISTS se pueden realizar de alguna otra forma con los
operadores ya comentados.
Combinaciones especiales
UNIONES
La palabra UNION permite añadir el resultado de un SELECT a otro SELECT. Para ello
ambas instrucciones tienen que utilizar el mismo número y tipo de columnas. Ejemplo:
SELECT nombre FROM provincias UNION SELECT nombre FROM comunidades
El resultado es una tabla que contendrá nombres de provincia y de comunidades. Es
decir, UNION crea una sola tabla con registros que estén presentes en cualquiera de las
consultas. Si están repetidas sólo aparecen una vez, para mostrar los duplicados se
utiliza UNION ALL en lugar de la palabra UNION.
Es muy importante señalar que tanto ésta cláusula como el resto de combinaciones
especiales, requieren en los dos SELECT que unen el mismo tipo de columnas (y en el
mismo orden).
INTERSECCIONES
De la misma forma, la palabra INTERSECT permite unir dos consultas SELECT de modo
que el resultado serán las filas que estén presentes en ambas consultas.
Ejemplo; tipos y modelos de piezas que se encuentren sólo en los almacenes 1 y 2:
SELECT tipo,modelo FROM existencias WHERE n_almacen=1
INTERSECT
SELECT tipo,modelo FROM existencias WHERE n_almacen=2
DIFERENCIA
Con MINUS también se combinan dos consultas SELECT de forma que aparecerán los
registros del primer SELECT que no estén presentes en el segundo.
Ejemplo; tipos y modelos de piezas que se encuentren el almacén 1 y no en el 2
(SELECT tipo,modelo FROM existencias WHERE n_almacen=1)
MINUS(SELECT tipo,modelo FROM existencias WHERE n_almacen=2)
Se podrían hacer varias combinaciones anidadas (una unión cuyo resultado se
intersectará con otro SELECT por ejemplo), en ese caso es conveniente utilizar
paréntesis para indicar qué combinación se hace primero:
(SELECT... ....
UNION
SELECT...
...
)
MINUS
SELECT.... /* Primero se hace la unión y luego la diferencia*/
Consultas avanzadas
CONSULTAS CON ROWNUM
La función ROWNUM devuelve el número de la fila de una consulta. Por ejemplo en:
SELECT ROWNUM, edad, nombre FROM clientes
Aparece el número de cada fila en la posición de la tabla. Esa función actualiza sus
valores usando subconsultas de modo que la consulta:
SELECT ROWNUM AS ranking, edad, nombre FROM clientes
FROM (SELECT edad, nombre FROM clientes ORDER BY edad DESC)
Puesto que la consulta SELECT edad, nombre FROM clientes ORDER BY edad DESC,
obtiene una lista de los clientes ordenada por edad, el SELECT superior obtendrá esa
lista pero mostrando el orden de las filas en esa consulta. Eso permite hacer consultas el
tipo top-n, (los n más....).
Por ejemplo para sacar el top-10 de la edad de los clientes (los 10 clientes más
mayores):
SELECT ROWNUM AS ranking, edad, nombre FROM clientes
FROM (SELECT edad, nombre FROM clientes ORDER BY edad DESC)
WHERE ROWNUM<=10
En el ejemplo se observa como un jefe puede tener otro jefe, generando una estructura
jerárquica:
En este tipo de estructuras, a veces se requieren consultas que muestren todos los
empleados de un jefe, mostrando los mandos intermedios. Se trata de una consulta que
recorre ese árbol. Este tipo de consultas posee esta sintaxis:
El apartado CONNECT permite indicar qué relación hay que seguir para recorrer el
árbol. La palabra PRIOR indica hacia dónde se dirige el recorrido. Finalmente el
apartado START indica la condición de inicio del recorrido (normalmente la condición
que permita buscar el nodo del árbol por el que comenzamos el recorrido, es decir sirve
para indicar desde donde comenzamos.
Ejemplo:
SELECT nombre FROM empleados START WITH nombre='Andrés'
CONNECT BY PRIOR n_jefe=n_empleado;
Resultado:
Sin embargo:
SELECT nombre FROM empleados START WITH nombre='Andrés'
CONNECT BY n_jefe= PRIOR n_empleado;
Devuelve
Cuando los datos forman un árbol jerárquico (como ocurre con los ejemplos) no suele
haber ningún problema. Pero hay diseños en los que hay padres de hijos que a su vez
pueden ser sus padres. Con los padres e hijos no ocurre esta situación evidentemente.
Pero por ejemplo si tuviéramos un diseño de redes sociales donde se apunta el nombre
del usuario y el nombre de sus amigos, entonces resulta que yo estaré apuntado como
amigo de una persona que, a su vez, es mi amigo.
En ese caso resultaría un bucle infinito cuando se hace esta consulta:
SELECT amigo FROM contactos
START WITH nombre='Ángel'
CONNECT BY PRIOR amigo=nombre;
-- Ocurre un bucle imposible de solucionar
Para esos casos disponemos de la cláusula NOCYCLE que controla los resultados
repetidos y evita esos caminos. En cualquier caso consultas en datos no jerarquizados
en forma de árbol sino en forma de grafo (como el comentado ejemplo de las redes
sociales), pueden ocupar muchísimo tiempo a Oracle por lo que no es mala idea pensar
en otra solución con ayuda de PL/SQL (lenguaje que se comenta en estos mismos
apuntes).
SELECT DISTINCT amigo FROM contactos
START WITH nombre='Ángel'
CONNECT BY NOCYCLE PRIOR amigo=nombre; -- Ahora sí
Por cierto, el DISTINCT impide que aparezcan muchas veces las mismas personas. Ya
que pueden ser amigos de muchos de mis amigos (e incluso de muchos de los amigos
de mis amigos).
CUBE
Es muy similar al anterior, sólo que este calcula todos los subtotales relativos a la
consulta. Ejemplo:
SELECT tipo, modelo, SUM(cantidad) FROM existencias
GROUP BY CUBE (tipo,modelo);
Es decir, calcula totales por tipo, por modelo y el total absoluto.
GROUPING
Se trata de una función que funciona con ROLLUP y CUBE y que recibe uno o más
campos e indica si la fila muestra un subtotal referido a los campos en cuestión. Si la fila
es un subtotal de esos campos pone 1, sino lo marca con 0. Ejemplo:
SELECT tipo, modelo, SUM(cantidad),
GROUPING(tipo), GROUPING(modelo) FROM existencias GROUP BY CUBE
(tipo,modelo);
Se utiliza sobre todo para preparar un consulta para la creación de informes.
GROUPING SETS
Se trata de una mejora de Oracle 9i que permite realizar varias agrupaciones para la
misma consulta. Sintaxis:
SELECT...
...
GROUP BY GROUPING SETS (listaDeCampos1) [,(lista2)...]
Las listas indican los campos por los que se realiza la agrupación. Ejemplo:
SELECT tipo, modelo, n_almacen, SUM(cantidad) FROM existencias
GROUP BY GROUPING SETS ((tipo,modelo), (n_almacen));
Se trata de dos consultas de totales unidades
CONJUNTOS DE AGRUPACIONES COMBINADAS
Se pueden combinar agrupaciones de diversas formas creando consultas como:
SELECT tipo, modelo, n_almacen, SUM(cantidad) FROM existencias
GROUP BY tipo, ROLLUP(modelo), CUBE(n_almacen)
Que mostraría un informe espectacular sobre las tablas anteriores. Así como:
SELECT tipo, modelo,n_almacen, SUM(cantidad) FROM existencias
GROUP BY GROUPING SETS(tipo,modelo), GROUPING SETS(tipo,n_almacen)
Ese relleno se basa en una consulta SELECT que poseerá los datos a añadir.
Lógicamente el orden de esos campos debe de coincidir con la lista de campos indicada
en la instrucción INSERT.
Sintaxis:
Ejemplo:
INSERT INTO clientes2004 (dni, nombre, localidad, direccion)
SELECT dni, nombre, localidad, direccion FROM clientes WHERE problemas=0;
Lógicamente las columnas del SELECT se tienen que corresponder con las columnas a
rellenar mediante INSERT (observar las flechas).
SUBCONSULTAS EN LA INSTRUCCIÓN UPDATE
La instrucción UPDATE permite modificar filas. Es muy habitual el uso de la cláusula
WHERE para indicar las filas que se modificarán. Esta cláusula se puede utilizar con las
mismas posibilidades que en el caso del SELECT, por lo que es posible utilizar
subconsultas. Por ejemplo:
UPDATE empleados SET sueldo=sueldo*1.10
WHERE id_seccion =(SELECT id_seccion FROM secciones
WHERE nom_seccion='Producción');
Esta instrucción aumenta un 10% el sueldo de los empleados de la sección llamada
Producción. También podemos utilizar subconsultas en la cláusula SET de la instrucción
UPDATE.
Ejemplo:
UPDATE empleados SET puesto_trabajo=(SELECT puesto_trabajo
FROM empleados
WHERE id_empleado=12)
WHERE seccion=23;
Esta instrucción coloca a todos los empleados de la sección 23 el mismo puesto de
trabajo que el empleado número 12. Este tipo de actualizaciones sólo son válidas si el
subselect devuelve un único valor, que además debe de ser compatible con la columna
que se actualiza.
Hay que tener en cuenta que las actualizaciones no pueden saltarse las reglas de
integridad que posean las tablas.
SUBCONSULTAS EN LA INSTRUCCIÓN DELETE
Al igual que en el caso de las instrucciones INSERT o SELECT, DELETE dispone de
cláusula WHERE y en dicha cláusulas podemos utilizar subconsultas. Por ejemplo:
DELETE empleados WHERE id_empleado IN
(SELECT id_empleado FROM errores_graves);
En este caso se trata de una subconsulta creada con el operador IN, se eliminarán los
empleados cuyo identificador esté dentro de la tabla de errores graves.
Optimización de consultas
Considere el siguiente esquema:
CLIENTE {cli_id, cli_nom, cli_renta_anual, cli_tipo}
CAMION {cam_id, cam_nombre_chofer}
CIUDAD {ciu_nombre, ciu_poblacion}
EMBARQUE {emb_id, emb_cli_id, emb_peso, emb_camion_id, emb_destino,
emb_fecha}
Clave foránea: emb_cli_id referencia a cli_id en CLIENTE
Clave foránea: emb_destino referencia a ciu_nombre en ciudad
Clave foránea: emb_id_camion referencia a cam_id en CAMION
Considere además los siguientes tamaños de las tablas:
CLIENTE: 200 registros
CAMION: 30 registros
CIUDAD: 30 registros
EMBARQUE: 7000 registros
Optimice la consulta: Cómo se llaman los clientes que han enviado paquetes a
Antofagasta.
En SQL la consulta sería:
SELECT cli_nom
FROM CLIENTE, EMBARQUE
WHERE cli_id = emb_cli_id AND emb_destino = ‘Antofagasta’
Pasando a álgebra relacional, la consulta es:
DATOSALUMNO
RUT NOMBRE DIRECCION TELEFONO
12345 Julio Escudero El sauce 134 4563215
32456 Ignacio Ampuero Violetas 445 6556554
67899 Daniela Torres Los andes 23 3225222
78654 Tania Torres Tucanes 456 8856877
34321 Julio Cruz Los alpes 78 5552355
ASIGNATURAALUMNO
RUT CODIGO A
12345 B01
12345 B02
32456 C03
32456 B03
32456 B01
67899 B03
78654 B01
78654 B02
34321 B03
34321 C03
PROFESOR
CODIGOP NOMBRE DEPARTAMETO TELEFONO CODIGO A
11001 Mauricio Cid Informática 6554337 B01
11002 Rosa Barrera Informática 5565667 B02
11003 Marlene Cruz Idioma 7878666 C03
11004 Jose Orellana Informatica 7689555 B03
DATOSASIGNATURA
CODIGOA NOMBRE JORNADA CREDITOS
B01 Base de datos Diurna 4
B02 Informática Diurna 6
C03 Ingles Vespertina 6
B03 Programación Vespertina 5
/* grupo i
Nombres */
/* Consulta N1 */
SELECT …
FROM …
…
;
…
/* Consulta N5 */
SELECT …
…
;
II. Realice las siguientes actividades en una bas de datos de Oracle 10g:
a. Crear las tablas de la base de datos.
b. Insertar 4 tuplas por tabla.
c. Realizar 10 consultas multitabla a la base de datos creada con encabezados en un
archivo .txt
d. Escribir los códigos SQL de las consultas y entregarlos en un fichero denominado
consultasOracle.sql
Se pide:
1. Obtener el nombre de la comunidad autónoma con menor número de habitantes.
2. Obtener el nombre de las comunidades autónomas con un número de habitantes por
debajo de la media de todas las comunidades.
3. Obtener el nombre de las localidades con un número de habitantes por debajo de la media
de todas las localidades.
4. Obtener las localidades accesibles a través de un solo tramo desde la localidad de Cuenca.
5. Obtener el nombre de las localidades de la comunidad autónoma CLM.
6. Obtener el número de habitantes de cada provincia, ordenando por comunidad autónoma
y provincia.
7. Obtener las comunidades autónomas que tienen de media una distancia superior a 30
kilómetros entre las localidades de su comunidad.
8. Nombre de las provincias con un censo inferior a 40000 habitantes.
9. Obtener localidades que no figuren en ninguno de los tramos o en los que no figure la
distancia entre los nodos del tramo.
10. Escribir los códigos SQL de las consultas y entregarlos en un fichero denominado
consultasDB2.sql.
La Base de Datos estará compuesta por tres tablas: SOCIOS, LIBROS y PRÉSTAMOS.
Las características de cada una de las tablas se muestran a continuación:
A partir de la base de datos “BIBLIO” que contiene información sobre los libros de
una biblioteca, realizar las siguientes consultas.
11. Nombre, dirección y teléfono de las editoriales de Nueva York (New York).
12. Nombre, dirección y teléfono de las editoriales del estado Massachusetts (MA).
13. Nombre y año de nacimiento de los escritores nacidos antes de 1950.
14. Nombre de los escritores de los que no se conoce el año de nacimiento.
15. Título de los libros publicados por editoriales de Boston después de 1990.
16. Nombre, dirección y teléfono de las editoriales con número de teléfono que empiece por
2.
17. Nombre completo de los escritores que se llamen Michael.
18. Título y año de publicación de los libros publicados recientemente (desde 1995) y que
contengan la palabra “Access” en su titulo.
19. Título y año de publicación de los libros escritos por un autor determinado.
20. Título y año de publicación de los libros publicados por una determinada editorial (indicad
el nombre de la compañía).
21. Cread una consulta con los campos autor y año de nacimiento de la tabla autores
mostrando solo aquellos que tienen año de nacimiento. Añadid un campo que calcule la
edad actual de los autores.
22. Realizad una consulta similar para conocer los años que llevan publicados los libros.
23. Calculad cuál es el año de publicación de los libros más reciente.
24. Calculad la media de edad de los autores.
25. ¿Cuál es el año de publicación más antiguo? A partir de este dato mostrad los libros más
antiguos.
A partir de la base de datos “Videoclub” realizar las siguientes tareas con las tablas
en Vista Hoja de Datos:
1. Ordenar por ...
- año de estreno la tabla Películas.
- título de películas la tabla Dvd.
- nombre la tabla de Clientes.
- DNI del cliente la tabla Alquiler.
2. Filtros: (Antes de aplicar cada filtro elimina el anterior)
- Mostrar todas las comedias en la tabla películas.
- Mostrar los dramas del año 2000 en la tabla películas.
- Mostrar las películas dirigidas por Vicente Aranda.
- Mostrar los alquileres de 4,00 €.
- Mostrar los alquileres de 3,00 € del cliente con DNI 33333333C .
3. Buscar registros:
En la tabla películas buscar ...
- directores que se llamen Pedro.
- directores o intérpretes que se llamen Alex.
En la tabla clientes buscar la palabra SE en cualquier campo.
4. Modificar el formato de la Hoja de Datos:
- Cambiar las propiedades del texto y de la cuadrícula de cada una de las tablas.
5. Ident-Dvd y título de los dvd sin devolver (Fecha devolución = nulo).
6. DNI, nombre, dirección, teléfono y correo electrónico de los clientes que han alquilado
algún dvd el año 2001. (Cuidado que el campo fecha de alquiler es de tipo fecha).
7. Título de los dramas del 1999, comedias de 1997 y de todas las películas del 2001.
8. Nombre de los clientes que han alquilado una película que se estrenó en 1997. Incluid
también el título de la película.
9. Ident-dvd y título de los dvd alquilados por cliente en concreto (solicitad el DNI). Incluid
también la fecha de alquiler y devolución.
10. Nombre, dirección y teléfono de los clientes que han alquilado cierto Dvd.
11. Ident-dvd y título de los dvd sin devolver de un cliente concreto (solicitad el DNI). Incluid
también la fecha de alquiler.
12. Ident-dvd y título de los dvd de un género determinado.
13. ¿Cuántos alquileres de 3,00€ se han realizado?
14. ¿Cuántos dvd hay disponibles?
15. ¿Cuántas películas hay de género drama estrenadas en el 1998?
16. Calculad la media del precio de alquiler.
17. Cread una consulta con los campos Ident-dvd, nombre y apellidos del cliente. Añadid un
campo que muestre los días que el cliente tiene la película en su poder.
18. Actualización del precio de películas de 1998: Reducción del 10%.
19. Creación de una tabla con las películas vistas por los clientes.
20. Eliminar todos los datos de un cliente.
21. Presentar una consulta de tablas de referencias cruzadas que muestre el número de
películas de cliente por día.
22. Copiar la tabla alquileres y posteriormente realizar una consulta de datos anexados que
anexe esta copia a la original.
6 Manuel Torres Gil. Departamento de Lenguajes y Computación. Universidad de Almera. Asignatura Web de Bases de datos
(ITIG) página 42 de Práctica 3. Desarrollo de bases de datos con ORACLE (http://indalog.ual.es/mtorres/BD/bdp3.pdf)
Tras captar las impresiones del usuario, si es necesario, vuelva a revisar la interfaz de
usuario para que se ajuste a las críticas del usuario
c. Diseño de un formulario con Form Builder
En esta sección veremos cómo crear un formulario sencillo y cómo crear un formulario
maestro-detalle con Form Builder. Pero antes de eso, comentemos algunos conceptos
básicos.
Los formularios creados con Form Builder están compuestos de lo que se denominan
módulos. Concretamente hay cuatro tipos de módulos:
Módulo Formulario (Form). Colección de objetos como ventanas, cuadros de texto,
casillas de verificación, botones, cuadros de lista y bloques de código PL/SQL
denominados disparadores.
Módulo Menú. Colección de menús y elementos de menús (órdenes).
Módulo Librería PL/SQL (PL/SQL Library). Colección de procedimientos, funciones y
paquetes que pueden ser llamados por otros módulos de la aplicación.
Módulo Librería de objetos (Object Library). Colección de objetos que se pueden
utilizar para el desarrollo de una aplicación.
Figura Un formulario
Hay dos tipos de bloques: bloques de datos, que se utilizan como puente entre el usuario y la
fuente de datos, y bloques de control, que no están asociados a ninguna fuente de datos. Cada
bloque de datos permite a un usuario acceder a los datos de una tabla, consulta o vista de la
fuente de datos. Además, los bloques pueden tener un solo registro (como el bloque
Departamento de la figura anterior), lo que significa que sólo se puede acceder a una fila en un
instante, o pueden tener varios registros (como el bloque Empleados de la figura anterior), lo que
significa que se pueden ver varios registros a la vez.
Una región es un rectángulo que agrupa de forma lógica ciertos campos dentro de un bloque,
mientras que un marco es una forma de organización predefinida de elementos en un bloque.
Concretamente el marco configura aspectos como los márgenes y distancias entre elementos.
2. Ventanas y canvas
Una ventana es el contenedor en el que se muestran todos los objetos visuales de un formulario.
Un formulario puede constar de varias ventanas, pero lo más común es tener un formulario para
cada ventana.
En Form Builder tenemos los siguientes tipos de ventanas:
- Contenedor (MDI). Contiene al resto de las ventanas. Suele contener a la barra de
herramientas y al menú principal.
- No modales. Permiten al usuario interactuar con cualquier otra ventana, así como con la barra
de herramientas y el menú.
- Modales. Obligan al usuario a trabajar con una única ventana, de forma que sólo pueda
aceptar o cancelar los cambios que realice. La barra de herramientas y el menú no son
accesibles. Se suelen utilizar en los cuadros de diálogo de configuración de propiedades y en
los asistentes.
Un canvas (lienzo o superficie) es el objeto implícito sobre el que aparecen los elementos de la
interfaz. Un formulario puede tener varios canvas, como si se tratasen de las páginas de un
formulario. Un canvas puede mostrar elementos de uno o más bloques. Para poder ver los
elementos de un canvas, tiene que colocar el canvas en una ventana.
Existen cuatro tipos de lienzos:
- Canvas de contenido. Ocupan toda la ventana. Cada ventana tiene al menos un lienzo de
contenido.
- Canvas apilados. Aparecen apilados sobre el lienzo de contenido. Se utilizan para ocultar
zonas de un lienzo de contenido.
- Canvas con fichas. Un conjunto de fichas que le permiten agrupar y presentar una gran
cantidad de información relacionada en el espacio de un solo lienzo.
- Canvas de barras de herramientas. Se utilizan para crear barras de herramientas. Cada
ventana puede presentar un canvas o más, y además se pueden presentar de forma
condicional, dependiendo de si se cumplen ciertas condiciones.
3. Creación de un formulario
Puede crear un formulario de varias formas.
Ejecutando Form Builder. Esto le lleva al cuadro de diálogo de bienvenida de Form Builder que
se muestra en la figura siguiente. En este cuadro de diálogo podrá:
- Utilizar el Asistente para bloques de datos, que le asiste en el proceso de creación de un
bloque de datos.
- Crear un formulario de forma manual, que muestra directamente el Explorador de objetos
para cree un formulario a partir de uno vacío.
- Crear un formulario a partir de una plantilla.
Para activar el Cuadro de Propiedades, basta con pulsar dos veces en el Explorador de objetos
sobre el objeto cuyas propiedades queremos configurar o consultar. Esta acción abrirá el Cuadro
de Propiedades y mostrará las propiedades del objeto activo junto con sus valores, de forma que
si en el Explorador de objetos seleccionamos otro objeto, el Cuadro de Propiedades mostrará las
propiedades del nuevo objeto seleccionado.
Veamos ahora cómo crear un bloque de datos nuevo.
Un formulario consta de uno o más bloques de datos y bloques de control. Ahora que ya sabemos
crear módulos de formulario, vamos a ver cómo podemos crear los bloques de datos del
formulario.
NOTA: La creación de un bloque de datos supone la creación del propio bloque de datos y la
creación de su diseño para su presentación en el formulario. Puede crear los bloques de datos de
forma manual o utilizando los asistentes de Form Builder.
Veamos cómo crear un bloque de datos y su presentación para la tabla de departamentos
utilizando el Asistente para bloques de datos (Data Block Wizard) y el Asistente de presentación
(Layout Wizard).
Lo primero que tenemos que hacer, a no ser que ya lo hayamos hecho, es conectarnos a la base
de datos. Para ello, introduciremos nuestro nombre de usuario, contraseña y nombre de la base
de datos.
A continuación iniciaremos el Asistente para bloques de datos seleccionado Tools|Data Block
Wizard. Una vez pasada la pantalla de bienvenida, hay que indicar al asistente si nuestro bloque
de datos está basado en una tabla o vista, o bien está basado en un procedimiento, tal y como
muestra la figura siguiente.
Para ello, pulsaremos el botón Browse para examinar las tablas de nuestra base de datos y elegir
la tabla de departamentos. A continuación aparecerán en el cuadro de Available Columns las
columnas de nuestra tabla, y podremos seleccionar cuáles son las columnas que queremos que
formen nuestro bloque de datos. En este ejemplo pasaremos todas al cuadro de Database Items,
tal y como muestra la figura siguiente.
A continuación vamos a crear una presentación para nuestro bloque de datos, y comenzaremos
seleccionando el tipo de canvas que vamos a crear. El tipo puede ser Content, para ser uno
principal o continente, Stacked, Vertical Toolbar u Horizontal Toolbar para la creación de barras
de herramientas, o bien del tipo Tab si lo que queremos es crear un canvas con fichas. En
nuestro caso elegiremos el tipo Content, tal y como muestra la figura y a continuación pasaremos
al paso siguiente.
Introducción de parámetros
Presentación de resultados
Figura. Definición de una variable para especificar una condición múltiple sobre Ciudad.
Si ahora pulsa el botón Execute Query aparecerá el cuadro de diálogo Query/Where, en el que
debe especificar su predicado WHERE en SQL, utilizando la variable junto los dos puntos que ha
definido en el formulario, tal y como se muestra en la figura siguiente. Además, en este editor
podrá hacer búsquedas y sustituciones de cadenas.
Una vez que finalice la introducción de la consulta, pulse OK y aparecerán en su formulario los
registros que cumplen la condición que ha especificado.
Para editar la consulta basta con volver a introducir una consulta (puede ser la misma) que utilice
variables de este tipo, y el cuadro de diálogo que aparece es el mismo. La figura siguiente
muestra una modificación realizada a la consulta para que presente los resultados ordenados por
Estado. En cuando a las ordenaciones, las puede realizar directamente sobre el nombre de la
columna, sin necesidad de utilizar un nombre de variable, tal y como se muestra en la figura
siguiente.
Para la interconexión de la parte maestro y de la parte detalle se utilizan las claves externas, es
decir se presentan todos los registros de la parte detalle en los que los valores de la clave
externa en la tabla que actúa como detalle coincida con los valores de la clave en la tabla que
actúa como maestro. Esta idea de formularios no tiene una configuración única, ya que el
formulario detalle, puede ser a su vez maestro de otro formulario, o un formulariomaestro puede
ser maestro de formularios detalle, tal y como se ilustra en la figura siguiente.
Una vez finalizada la creación del bloque de datos, falta crear el diseño de su presentación, y a
continuación detallamos los pasos que vamos a seguir.
El primer paso importante es elegir si queremos presentar nuestro detalle junto a la parte
maestro (en el mismo canvas), o lo queremos presentar en un cuadro aparte (en otro canvas
nuevo). Nosotros elegiremos el mismo canvas que es la forma más común.
En el paso siguiente, nos aseguraremos que el bloque de datos seleccionado es el de EMP, y a
continuación pasaremos al cuadro de Displayed Items todos los campos excepto NUMDEP, puesto
que ya aparece en la parte maestro, de forma que nuestro cuadro de diálogo quedaría así.
Si lo que desea es que aparezca una sugerencia cuando el puntero del ratón se sitúe sobre un
elemento de la interfaz, debe configurar la propiedad Tooltip con el texto que desea que aparezca
(p.e. Un número de cuatro dígitos que identifica al empleado en la empresa).
Una vez seleccionados los dos nuevos elementos de bloque de datos, y una vez que se han
configurado como casillas de verificación, acepte los cambios. Por último, lo único que falta por
hacer es asignarle a cada uno de ellos un valor para cuando la casilla esté marcada y otro valor
para cuando la casilla no esté marcada.
Esto se realiza escribiendo un valor en las propiedades Value When Checked y Value When
Unchecked, que si bien pueden tomar cualquier valor permitido por el tipo de datos del elemento,
se suelen utilizar los valores V y F, o T y F, ya que se trata de variables lógicas. Observe cómo se
ha realizado esto para la columna internacional en la figura siguiente.
Por tanto, no son tan flexibles, pero son útiles cuando se conocen previamente los valores del
dominio del campo sobre el que se van a definir.
Form Builder permite la utilización de tres tipos de cuadros de lista:
Listas emergentes (Pop-Up Lists): Se trata de un campo con una flecha a la derecha para
mostrar la lista de valores. Este tipo de listas no permite la introducción de valores desde
teclado.
Cuadros combinados (Combo Boxes): Son listas emergentes que permiten la introducción de
datos por parte del usuario.
Listas rectangulares (TLists): Se trata de cuadros que tienen una lista de valores que pueden
ser recorridos mediante una barra de desplazamiento.
La figura siguiente muestra distintas presentaciones del nombre del departamento para que
observe la diferencia entre las listas emergentes y las listas rectangulares.
Una vez creado el grupo de botones hay que crear cada uno de los botones, que en este caso
serán dos, uno para inscrito y otro para no inscrito.
Una vez creados los dos botones de opción, hay que configurar algunas propiedades.
Concretamente configuraremos:
Name: INSCRITO
Label: Sí/No
Radio Button Value: T/F
Observe la diferencia entre la propiedad de la etiqueta, que indica lo que se muestra en la
interfaz, y la propiedad del valor, que contiene lo que realmente se guarda en la base de datos.
A continuación puede crear un rectángulo para crear un grupo lógico con los dos botones de
opción, y cambiar las propiedades del fondo (none) y las del título (label), de forma que su
formulario sea similar al de la figura siguiente.
A continuación crearemos los bloques de datos para cada una de las fichas, y este proceso es
similar al que se siguió en su momento para crear el formulario Maestro-Detalle. Lo único que
hay que tener en cuenta ahora en el Asistente para diseño (Layout Wizard) es situar el bloque de
datos en la ficha correspondiente, tal y como se muestra en la figura siguiente.
NOTA: Si tiene problemas al ejecutar la consulta y sólo puede consultar por la parte detalle,
cambie el orden de los bloques de datos, ya que siempre se pregunta por el que está en primer
lugar.