Curso oracle por temas

  • 896 views
Uploaded on

temas sobre taller de base de datos

temas sobre taller de base de datos

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
896
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
59
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 2.2. Actualización, modificación y eliminación del esquema de base de datos Oracle Una tabla es un sistema de elementos de datos (atributo - valores) que se organizan que usando un modelo vertical - columnas (que son identificados por su nombre)- y horizontal filas. Una tabla tiene un número específico de columnas, pero puede tener cualquier número de filas. Cada fila es identificada por los valores que aparecen en un subconjunto particular de la columna que se ha identificado por una llave primaria. Una tabla de una base de datos es similar en apariencia a una hoja de cálculo, en cuanto a que los datos se almacenan en filas y columnas. Como consecuencia, normalmente es bastante fácil importar una hoja de cálculo en una tabla de una base de datos. La principal diferencia entre almacenar los datos en una hoja de cálculo y hacerlo en una base de datos es la forma de organizarse los datos.
  • 2. Por lo tanto, la creación de las tablas en el proceso de programación en Oracle juegan un papel muy importante. En el momento de crear las tablas se definen características a dos niveles: Tabla y Columna, como se muestra a continuación: A nivel de tabla: Refieren a una o a varias columnas, donde cada columna se define individualmente. Nombre: Nombre de la tabla puede ser de 1 a 30 caracteres. La tabla tiene como propietario al usuario que las crea. Por ejemploEQUIPO. Hay que tener en cuenta también ciertas restricciones con los nombres de las tablas: longitud máxima de 30 caracteres, no puede haber nombres de tabla duplicados, deben comenzar con un carácter alfabético, permitir caracteres alfanuméricos y el guión bajo '_', y Oracle no distingue entre mayúsculas y minúsculas. Propietario: La tabla tiene como propietario al usuario que las crea En nuestro caso somos el usuario ALUMNO. Otro usuario que desee usar
  • 3. nuestras tablas debe tener autorización para ello y hacer referencia a la tabla como ALUMNO.EQUIPO (propietario.tabla) Cantidad de Columnas: Una tabla puede tener un máximo de 254 columnas. A nivel de Columna el nombre de la columna puede tener un máximo de 30 caracteres. En Oracle podemos implementar diversos tipos de tablas. A continuación se presenta una recompilación no exhaustiva de ellas. Tipo Tabla Descripción Regular (heap) Son el mecanismo de almacenamiento de los datos en una base de datos Oracle. Contienen un conjunto fijo de columnas. Las columnas de una tabla describen los atributos de la entidad que se representa con la tabla. Cada columna tiene un nombre y características específicas: tipo de dato y longitud, restricciones, etc. Clustered Un cluester proporciona un método opcional de almacenar datos de tabla. Un cluster está compuesto de un grupo de tablas que comparten los mismos bloques de datos. Las tablas son agrupadas mediante columnas comunes. Index Aquí una tabla es almacenada en la estructura de un índice. Esto impone orden físico a las filas por si mismas. A diferencia de un heap, donde los datos son almacenados en donde caben, en una tabla IOT (Tabla Organizada por Indices) los datos son almacenados en el orden de la clave primaria. Particionadas Es un esquema de organización de los datos con el cual podemos dividirla en múltiples objetos de almacenamientos llamados particiones de datos o rangos, dependiendo los valores puede ser dividido en uno o más columnas de la tabla. Cada particiones de datos es almacenado separadamente. Estos objetos almacenados pueden estar en diferentes tablespaces, en el mismo o en una combinación de ambos. Temporales Son tablas cuyos datos permanecerán en el sistema sólo durante el tiempo que dure la transacción o sesión involucrada.
  • 4. Tipo Tabla Descripción No obstante, al igual que para las tablas permanentes, la definición de las tablas temporales se almacena en las tablas del sistema. La sintaxis del comando que permite crear un tabla es la siguiente: Del examen de la sintaxis de la sentencia Create Table se pueden concluir que necesitamos conocer los distintos tipos de columna y las distintas restricciones que se pueden imponer al contenido de las columnas. Existen varios tipos de datos en SQL. De esta manera, cada columna puede albergar una información de naturaleza distinta. Los tipos de datos más comunes y sus características en Oracle Express (10 Y 11g) se resumen en la siguiente tabla. Las versiones de Oracle comercial soportan una gama mucho más amplia de tipos de datos. Tipo de Dato Descripción BLOB Contiene datos binarios con un tamaño máximo de 4 gigabytes. Los datos binarios nos van a permitir guardar en la base de datos archivos, imagenes, sonidos, etc ... Casi siempre es preferible guardar la ruta del archivo en la base de datos en lugar del propio archivo en modo binario, pero existen ciertas circunstancias en las que no nos queda
  • 5. otra solución. BINARY_DOUBL E Presición doble BINARY_FLOAT Presición simple CLOB Un tipo de datos CLOB de Oracle contiene datos de caracteres basados en el juego de caracteres predeterminados del servidor. Su tamaño máximo es de 4 gigabytes. Se asigna a cadena. Use la siguiente expresión para una consulta de un campo CLOB SELECT DBMS_LOB.substr(campo, DBMS_LOB.getlength(c ampo),1) FROM tablaprueba; CHAR Almacena datos de tipo carácter alfanumérico de longitud fija, con un tamaño máximo de 2000. caracteres DATE Almacena fechas desde el 1-Ene-4712 AC hasta el 31-Dic- 4712 DC. NUMBER(dig [, dec]) Datos numéricos de n dígitos, de los cuales dec son decimales. El tamaño máximo es de 38 dígitos. NVARCHAR2 Almacena un valor alfanumérico de longitud variable en caracteres Unicode con las mismas restricciones de varchar. TIMESTAMP Fecha y hora (incluidos los segundos), con un tamaño que abarca desde 7 a 11 bytes. VARCHAR2(tama ño) Guarda datos de tipo carácter alfanumérico de longitud variable, con un tamaño máximo de 4,000 caracteres. Ejemplo: Considere la siguiente tabla de datos correspondientes a los campeones de Formula 1 (1950 - 2012) y sus escuderias. Y su traducción a sentencias Oracle. Año Campeón Escudería 2012 - - 2011 Sebastian Vettel Red Bull Racing
  • 6. Año Campeón Escudería 2010 Sebastian Vettel Red Bull Racing 2009 Jenson Button Brawn GP 2008 Lewis Hamilton McLaren 2007 Kimi Raikkonen Ferrari 2006 Fernando Alonso Renault 2005 Fernando Alonso Renault 2004 Michael Schumacher Ferrari 2003 Michael Schumacher Ferrari 2002 Michael Schumacher Ferrari 2001 Michael Schumacher Ferrari 2000 Michael Schumacher Ferrari CREATE TABLE f1 ( yearINTEGER PRIMARY KEY, campeonCHAR(30), escuderiaCHAR(20) ); Ejemplo: Estados, capitales, densidad de población y superficie de la Republica Mexicana CREATE TABLE estados ( idEstadoINTEGER PRIMARY KEY, nombreEstadoCHAR(25) NOT NULL, capitalCHAR(25) NOT NULL, densidadINTEGER NOT NULL, poblacionINTEGER NOT NULL ); Tablas Temporales Oracle permite la creación de tablas temporales para mantener datos propios y exclusivos a una sesión Oracle determinada. Estos datos permanecerán en el sistema sólo durante el tiempo que dure la transacción o sesión involucrada. No
  • 7. obstante, al igual que para las tablas permanentes, la definición de las tablas temporales se almacena en las tablas del sistema. La siguiente sintaxis permite crear una tabla temporal personal para cada sesion. Eso significa que los datos no se comparten entre sesiones y se eliminan al final de la misma. CREATEGLOBAL TEMPORARYTABLE[ schema. ]table ( nombreColumna tipoDato [DEFAULT expresión] [NOT NULL], [,nombre_columna tipo_dato [DEFAULT expresión] [restricción_columna] ... |restricción_tabla]; ON COMMIT{ DELETE| PRESERVE } ROWS ] [ physical_properties ] Con la opcion ON COMMIT DELETE ROWS se borran los datos cada vez que se hace COMMIT en la sesion. Con la opcion ON PRESERVE DELETE ROWS los datos no se borran hasta el final de la sesion. Sus ventajas son varias, la información contenida en ella esta solo disponible para la sesión actual, cualquier inserción, borrado, actualizaciónsolo se refleja en la sesión activa. Muchas funcionalidades de cualquier tabla normal se mantienen en ella, como triggers a nivel tabla, vistas, indices, exportar e importar (claro solo la definición de la tabla). No es posible declarar llaves foraneas en una tabla temporal.
  • 8. (DROP) Eliminación Cuando una tabla ya no es útil y no vamos a volver a necesitarla debe ser borrada. Esta operación se puede realizar con el comando DROPTABLE. DROP TABLE nombre_tabla [CASCADE CONSTRAINTS][PURGE] Se borra la tabla de la base de datos, borrando toda la información contenida en la tabla, es decir, todas las filas. También se borrará toda la información que sobre la tabla existiera en el diccionario. Si alguna columna de la tabla a borrar sirve como clave ajena de alguna tabla detalle, impide la eliminación de la tabla, ya que existe una restricción que requiere de la existencia de la tabla maestra. Esto se puede areglar colocando la sentencia CASCADE CONSTRAINTS. Esto produce que las restricciones de la tabla detalle se borren antes de borrar la tabla maestra. PURGE evita que los objetos borrados se vayan a la papelera La siguiente sentencia produce la eliminación de la tabla BORRAME.
  • 9. Modificación Oracle permite modificar las restricciones definidas para una tabla. Esto puede llevar a “inconsistencia” de los datos ya introducidos en la base de datos. Por ello, Oracle tiene definidos mecanismos para modificación de los datos ya existentes. Esta operación se puede realizar con el comando ALTER TABLE. ALTER TABLE [esquema.]tabla clausula_constraint [,…] [ENABLE clausula_activa | DISABLE clausula_disable] [{ENABLE|DISABLE} TABLE LOCK] [{ENABLE|DISABLE} ALL TRIGGERS]; Hay que tener en cuenta varios puntos: No es posible disminuir el tamaño de una columna, si esta contiene datos. En las modificaciones, los tipos anterior y nuevo deben ser compatibles, o la tabla debe esta La opción ADD ... NOT NULL sólo será posible si la tabla está vacía. La opción MODIFY ... NOT NULL sólo podrá realizarse cuando la tabla no contenga ning cuestión.
  • 10. Considere el ejemplo Propietario - Automóvil, bajo el criterio de hacienda del Gobierno del Estado de Veracruz, México. Modificaremos el ejemplo para añadir el atributo color. ALTER TABLE automovil ADD(color CHAR(15) NOT NULL); Descargar Es factible modificar una tabla añadiendo o eliminando restricciones, en este caso para el ejemplo anterior el comando a utilizar será ALTER TABLE tabla {ADD | DROP} CONSTRAINT restricción; ALTER TABLE automovil DROP CONSTRAINT FK_Propietario; ALTER TABLE automovil ADD CONSTRAINT FK_Propietario FOREIGN KEY (idPropietario) REFERENCES propietario (idPropietario) ON DELETE CASCADE; El cual permitira el borrado en cascada.
  • 11. MySQL MySQL soporta varios motores de almacenamiento que tratan con distintos tipos de tabla. Los motores de almacenamiento de MySQL incluyen algunos que tratan con tablas transaccionales y otros que no lo hacen: MyISAM trata tablas no transaccionales. Proporciona almacenamiento y recuperación de datos rápida, así como posibilidad de búsquedas fulltext.MyISAM se soporta en todas las configuraciones MySQL, y es el motor de almacenamiento por defecto a no ser que tenga una configuración distinta a la que viene por defecto con MySQL. El motor de almacenamiento MEMORY proporciona tablas en memoria.El motor de almacenamiento MERGE permite una colección de tablasMyISAM idénticas ser tratadas como una simple tabla. Como MyISAM, los motores de almacenamiento MEMORY y MERGE tratan tablas no transaccionales y ambos se incluyen en MySQL por defecto. Nota: El motor de almacenamiento MEMORY anteriormente se conocía como HEAP. Los motores de almacenamiento InnoDB y BDB proporcionan tablas transaccionales. BDB se incluye en la distribución binaria MySQL-Max en aquellos sistemas operativos que la soportan. InnoDB también se incluye por defecto en todas las distribuciones binarias de MySQL 5.0 . En distribuciones fuente, puede activar o desactivar estos motores de almacenamiento configurando MySQL a su gusto. El motor de almacenamiento EXAMPLE es un motor de almacenamiento 'tonto' que no hace nada. Puede crear tablas con este motor, pero no puede almacenar datos ni recuperarlos. El objetivo es que sirva como ejemplo en el código MySQL para ilustrar cómo escribir un motor de almacenamiento. Como tal, su interés primario es para desarrolladores. NDB Cluster es el motor de almacenamiento usado por MySQL Cluster para implementar tablas que se particionan en varias máquinas. Está disponible en distribuciones binarias MySQL-Max 5.0. Este motor de almacenamiento está disponible para linux, Solaris, y Mac OS X. Los autores mencionan que se añnadirá soporte para este motor de almacenamiento en otras plataformas, incluyendo Windows en próximas versiones. El motor de almacenamiento ARCHIVE se usa para guardar grandes cantidades de datos sin índices con una huella muy pequeña. El motor de almacenamiento CSV guarda datos en archivos de texto usando formato de valores separados por comas.
  • 12. El motor de almacenamiento FEDERATED se añadió en MySQL 5.0.3. Este motor guarda datos en una base de datos remota. En esta versión sólo funciona con MySQL a través de la API MySQL C Client. En futuras versiones, será capaz de conectar con otras fuentes de datos usando otros drivers o métodos de conexión clientes. La versión 5 de MySQL crea por defecto tablas innoDB que permiten el manejo de integridad referencial, transacciones. Al igual que las tablas regulares de oracle. Para saber si el gestor de base de datos de MySQL que tenemos las soporta es necesario ejecutar la siguiente sentencia. SHOW VARIABLES liKE '%innodb%'; Ejecutar Si nuestro gestor soporta por defecto las tablas innodb las sentencias para crear las tablas previamente mostradas serán exactamente igual a las de oracle. En caso contrario se muestra la sintaxis correspondiente CREATE TABLE f1 ( yearINTEGER PRIMARY KEY, campeonCHAR(30), escuderiaCHAR(20) ) ENGINE = InnoDB; Ejemplo: Estados, capitales, densidad de población y superficie de la Republica Mexicana CREATE TABLE estados ( idEstadoINTEGER PRIMARY KEY, nombreEstadoCHAR(25) NOT NULL, capitalCHAR(25) NOT NULL, densidadINTEGER NOT NULL, poblacionINTEGER NOT NULL ) ENGINE = InnoDB; Comando Describe
  • 13. MySQL proporciona este comando que resulta útil para conocer la estructura de una tabla, las columnas que la forman y su tipo y restricciones. La sintásis es la siguiente DESCRIBE nombreTabla. DESCRIBE f1; Ejecutar Comando SHOW TABLES y SHOW CREATE TABLE El comando SHOW TABLES muestra las tablas dentro de una base de datos y SHOW CREATE TABLES muestra la estructura de creación de la tabla. Descargar Ejecutar Tablas temporales Las tablas temporales solo existen mientras la sesión está viva . Si se corre este código en un script de PHP ( Cualquier otro lenguaje), la tabla temporal se destruirá automáticamente al termino de la ejecución de la página. Si no específica MEMORY, la tabla se guardará por defecto en el disco. CREATE TEMPORARY TABLE temporal ( ifeINTEGER(13) PRIMARY KEY, nombreCHAR(30) NOT NULL UNIQUE ); Este tipo de tabla solo puede ser usada por el usuario que la crea. Si creamos una tabla que tiene el mismo nombre que una existente en la base de datos, la que existe quedará oculta y trabajaremos sobre la temporal. Tablas Memory ( Head )
  • 14. Se almacenan en memoria Una tabla head no puede tener más de 1600 campos Las tablas MEMORY usan una longitud de registro fija. MEMORY no soporta columnas BLOB o TEXT. MEMORY en MySQL 5.0 incluye soporte para columnas AUTO_INCREMENT e índices en columnas que contengan valores NULL. Las tablas MEMORY se comparten entre todos los clientes (como cualquier otra tabla no-TEMPORARY). CREATE TEMPORARY TABLE temporal ( ifeINTEGER(13) PRIMARY KEY, nombreCHAR(30) NOT NULL UNIQUE ) ENGINE = MEMORY; Modificación Esta operación se puede realizar con el comando ALTER TABLE. Para usar ALTER TABLE, necesita permisos ALTER, INSERT y CREATEpara la tabla. La sintaxis para MySQL es ALTER [IGNORE] TABLE tbl_name alter_specification [, alter_specification] ...; alter_specification: ADD [COLUMN] column_definition [FIRST | AFTER col_name ] | ADD [COLUMN] (column_definition,...) | ADD INDEX [index_name] [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] UNIQUE [index_name] [index_type] (index_col_name,...) | ADD [FULLTEXT|SPATIAL] [index_name] (index_col_name,...) | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition]
  • 15. | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} | CHANGE [COLUMN] old_col_name column_definition [FIRST|AFTER col_name] | MODIFY [COLUMN] column_definition [FIRST | AFTER col_name] | DROP [COLUMN] col_name | DROP PRIMARY KEY | DROP INDEX index_name | DROP FOREIGN KEY fk_symbol | DISABLE KEYS | ENABLE KEYS | RENAME [TO] new_tbl_name | ORDER BY col_name | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name] | [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name] | DISCARD TABLESPACE | IMPORT TABLESPACE | table_options Considere el ejemplo Propietario - Automóvil, bajo el criterio de hacienda del Gobierno del Estado de Veracruz, México. Modificaremos el ejemplo para añadir el atributo color según la sintaxis MySQL ALTER TABLE automovil ADD(color CHAR(15) NOT NULL);
  • 16. Descargar Ejemplo: Eliminar una llave foranea ALTER TABLE automovil DROP FOREIGN KEY FK_Propietario; Ejemplo: Agregar una llave foranea con borrado en cascada ALTER TABLE automovil ADD CONSTRAINT FK_Propietario FOREIGN KEY (idPropietario) REFERENCES propietario (idPropietario) ON DELETE CASCADE; Puede ejecutar múltiples cláusulas ADD, ALTER, DROP, y CHANGE en un único comando ALTER TABLE. Esta es una extensión MySQL al estándar SQL, que permite sólo una de cada cláusula por comando ALTER TABLE. 2.3. Integridad referencial Una vez definida la estructura de datos del modelo relacional, pasamos a estudiar las reglas de integridad, es decir que los datos almacenados en dicha estructura deben cumplir ciertas características para garantizar que son correctos. Al definir cada atributo sobre un dominio se impone una restricción sobre el conjunto de valores permitidos para cada atributo. A este tipo de restricciones se les denomina restricciones de dominios. Hay además dos reglas de integridad muy importantes que se deben cumplir en todas las bases de datos relacionales y en todos sus estados o instancias (las reglas se deben cumplir todo el tiempo). Estas reglas son la regla de integridad de entidades y la regla de integridad referencial. Antes de definirlas, es preciso conocer el concepto de nulo. Restricciones de dominios Imponen una limitación al conjunto de valores permitidos para los atributos en las relaciones. Permitiendo restringir los valores que puede tomar un atributo respecto a su dominio, por ejemplo EDAD >= 18. Nulos
  • 17. Cuando en una tupla un atributo es desconocido, se dice que es nulo. Un nulo no representa el valor cero ni la cadena vacía, éstos son valores que tienen significado. El nulo implica ausencia de información, bien porque al insertar la tupla se desconocía el valor del atributo, o bien porque para dicha tupla el atributo no tiene sentido. Ya que los nulos no son valores, deben tratarse de modo diferente, lo que causa problemas de implementación en los SGBD relacionales. NULL|NOT NULL. Determina si se permiten valores NULL en la columna. ORACLE: El optimizador necesita saber que una columna no es NOT NULL, y sin este conocimiento, se limita a elegir un plan de ejecución inferior al óptimo. SQL SERVER: NULL no es estrictamente una restricción, pero se puede especificar de la misma forma que NOT NULL. La restricción se puede usar para las columnas calculadas sólo si se especifica también PERSISTED. MySQL 5.02 Si la columna puede tener NULL como valor, la columna se define con una cláusula DEFAULT NULL explícita. En caso contrario no define DEFAULT explícito. Restricción UNIQUE En un índice UNIQUE todos los valores en el índice deben ser distintos. Ocurre un error si intenta añadir un nuevo registro con una clave que coincida con un registro existente. La excepción es que una columna en el índice puede contener valores NULL múltiples Cláusula check Un constraint check específica una condición en cada renglón de la tabla. Un constraint check no puede ser definida en una vista. Un constraint check puede usar solamente columnas en las misma tabla. Un constraint check no puede ser incluida en una subconsulta. Ejemplo: Se presentan 4 reglas de integridad de dominio. En el primer caso la no nulidad del campo nombreProveedor La no nulidad de forma ímplícíta del campo idProveedor al ser declarado llave primaria (pkProveedor) La tercera regla obliga que el idProveedor este en el rango de 1,000 a 9,999 (check_id)
  • 18. El constraint dom_nombreProveedor obliga a que el nombre del proveedor se escriba en mayúscula CREATE TABLE proveedores ( idProveedorINTEGER(4), nombreProveedorCHAR(50) NOT NULL, CONSTRAINT pkProveedores PRIMARY KEY (idProveedor), CONSTRAINT check_id CHECK (idProveedor BETWEEN 1000 AND 9999), CONSTRAINT dom_nombreProveedor CHECK (nombreProveedor =UPPER(nombreProveedor)) ) ENGINE = InnoDB; CREATE TABLE proveedores ( idProveedorNUMBER(4), nombreProveedorCHAR(50) NOT NULL, CONSTRAINT pkProveedores PRIMARY KEY (idProveedor), CONSTRAINT check_id CHECK (idProveedor BETWEEN 1000 AND 9999) CONSTRAINT dom_nombreProveedor CHECK (nombreProveedor = UPPER(nombreProveedor)) ); Descargar Ejemplo: ALTER TABLE Mediante esté constraint se restrige el nombre de los proveedores validos ALTER TABLE proveedores ADD CONSTRAINT dom_nombreProveedor CHECK (nombreProveedor IN ('DELL', 'HP','IBM', 'MICROSOFT', 'SONY')); Regla de integridad de entidades Una PRIMARY KEY es una llave única donde todas las columnas de la clave deben definirse como NOT NULL. Si no se declaran explícitamentecomo NOT NULL, el gestor las declara implícitamente. Una tabla puede tener sólo una PRIMARY KEY
  • 19. La primera regla de integridad se aplica a las claves primarias de las relaciones base: ninguno de los atributos que componen la clave primaria puede ser nulo. Por definición, una clave primaria es un identificador irreducible que se utiliza para identificar de modo único las tuplas. Irreducible significa que ningún subconjunto de la clave primaria sirve para identificar otra tupla. Los campos que conforman una llave primaria son por defecto no nulas. Nótese que esta regla sólo se aplica a las relaciones base y a las claves primarias, no a las claves alternativas. Regla de integridad referencial La segunda regla de integridad se aplica a las claves ajenas o foraneas: si en una relación hay alguna clave ajena, sus valores deben coincidir con valores de la clave primaria a la que hace referencia, o bien, deben ser completamente nulos. La regla de integridad referencial se enmarca en términos de estados de la base de datos: indica lo que es un estado ilegal, pero no dice cómo puede evitarse. La cuestión es ¿qué hacer si estando en un estado legal, llega una petición para realizar una operación que conduce a un estado ilegal? Existen dos opciones: rechazar la operación, o bien aceptar la operación y realizar operaciones adicionales compensatorias que conduzcan a un estado legal. Por lo tanto, para cada clave ajena de la base de datos habrá que contestar a tres preguntas: Regla de los nulos: Los campos involucrados en llaves primarias son por definición no nulos. Regla de borrado: ¿Qué ocurre si se intenta borrar la tupla referenciada por la clave ajena? o Restringir: no se permite borrar la tupla referenciada. o Propagar: se borra la tupla referenciada y se propaga el borrado a las tuplas que la referencian mediante la clave ajena - borrado en cascada-. o Anular: se borra la tupla referenciada y las tuplas que la referenciaban ponen a nulo la clave ajena (sólo si acepta nulos) - SET NULL-. Regla de modificación: ¿Qué ocurre si se intenta modificar el valor de la clave primaria de la tupla referenciada por la clave ajena? o Restringir: no se permite modificar el valor de la clave primaria de la tupla referenciada. o Propagar: se modifica el valor de la clave primaria de la tupla referenciada y se propaga la modificación a las tuplas que la referencian mediante la clave ajena. Oracle no permite la modificación en cascada.
  • 20. o Anular: se modifica la tupla referenciada y las tuplas que la referenciaban ponen a nulo la clave ajena (sólo si acepta nulos). En Oracle y MySQL la clausula ON DELETE dice como comportarse si se borra el registro “padre”: 1. Si no se especifica nada, por defecto saltará un error 2. CASCADE. Borrará los registros hijos. Ejemplo: Considere la relación departamentos y empleados. Es posible modificar el CONSTRAINT para que acepte el borrado en cascada. DROP TABLE IF EXISTS empleado, departamento CREATE TABLE departamento ( idDepartamentoINTEGER(3), nombreCHAR(15) NOT NULL, ciudadCHAR(10) NOT NULL, CONSTRAINT DOM_Ciudad CHECK (ciudad IN ('Veracruz', 'Xalapa', 'Orizaba', 'Regional')), CONSTRAINT PK_Departamento PRIMARY KEY (idDepartamento) ) ENGINE = InnoDB;
  • 21. CREATE TABLE empleado( idEmpleadoINTEGER, rfcCHAR(14), nombreEmpleadoCHAR(40) NOT NULL, oficioCHAR(11) NOT NULL, cargoCHAR( 9) NOT NULL, jefeINTEGER, ingreso DATE NOT NULL, salarioDECIMAL(10,2), comisionDECIMAL(10,2), idDepartamento INTEGER(3) NOT NULL, CONSTRAINT PK_Empleado PRIMARY KEY (idEmpleado), CONSTRAINT AK_Empleado UNIQUE (rfc), CONSTRAINT FK_EmpJefe FOREIGN KEY (jefe) REFERENCES empleado (idEmpleado), CONSTRAINT FK_Empleado FOREIGN KEY (idDepartamento) REFERENCES departamento (idDepartamento), CONSTRAINT D_Salario CHECK( salario> 0 ), CONSTRAINT D_NombreEmpleado CHECK (nombreEmpleado = UPPER(nombreEmpleado)) ) ENGINE = InnoDB; Descarga El código para implementar el borrado es cascada si borramos un departamento borrar los empleados que laboran en el es: ALTER TABLE empleado DROP CONSTRAINT FK_Empleado; ALTER TABLE empleado ADD CONSTRAINT FK_Empleado FOREIGN KEY (idDepartamento) REFERENCES departamento (idDepartamento) ON DELETE CASCADE; Versión Oracle DROP TABLE empleado CASCADE CONSTRAINTS; DROP TABLE departamento CASCADE CONSTRAINTS; CREATE TABLE departamento ( idDepartamento NUMBER(3),
  • 22. nombreCHAR(15) NOT NULL, ciudadCHAR(10) NOT NULL, CONSTRAINT DOM_Ciudad CHECK (ciudad IN ('Veracruz', 'Xalapa', 'Orizaba', 'Regional')), CONSTRAINT PK_Departamento PRIMARY KEY (idDepartamento) ); CREATE TABLE empleado( idEmpleadoNUMBER(3), rfcCHAR(14), nombreEmpleado CHAR(40) NOT NULL, oficioCHAR(11) NOT NULL, cargoCHAR(9) NOT NULL, jefeNUMBER(3), ingresoDATE NOT NULL, salarioNUMBER(10,2), comisionNUMBER(10,2), idDepartamento NUMBER(3) NOT NULL, CONSTRAINT PK_Empleado PRIMARY KEY (idEmpleado), CONSTRAINT AK_Empleado UNIQUE (rfc), CONSTRAINT FK_Empleado_Jefe FOREIGN KEY (jefe) REFERENCES Empleado, CONSTRAINT FK_Empleado FOREIGN KEY (idDepartamento) REFERENCES Departamento, CONSTRAINT D_Empleado_Salario CHECK ( salario > 0 ), CONSTRAINT D_Empleado_NombreEmpleado CHECK (nombreEmpleado = UPPER(nombreEmpleado)) ); Descargar 3. SET NULL. Pondrá los campos del registro hijo a null. Note que la clave ajena debe permitir el valor nulo. Sintaxis CONSTRAINT FK_columna FOREIGN KEY (columna1, columna2, ... columna_n) REFERENCES TablaReferenciada (columna1, columna2, ... columna_n) ON DELETE SET NULL Ejemplo: Proveedor - Producto
  • 23. CREATE TABLE IF NOT EXISTS proveedor ( idProveedorINTEGER, nombreProveedorCHAR(50) NOT NULL, contactoCHAR(50), CONSTRAINT PK_Proveedor PRIMARY KEY (idProveedor) ) ENGINE = InnoDB; CREATE TABLE IF NOT EXISTS productos ( idProductoINTEGER, idProveedorINTEGER, nombreProductoCHAR(50), precioProducto DECIMAL(8,2), CONSTRAINT PK_Productos PRIMARY KEY (idProducto), CONSTRAINT FK_Proveedor FOREIGN KEY (idProveedor) REFERENCESproveedor(idProveedor) ON DELETE SET NULL ) ENGINE = InnoDB; Descargar DROP TABLE productos CASCADE CONSTRAINT; DROP TABLE proveedor CASCADE CONSTRAINT; CREATE TABLE proveedor ( idProveedorNUMBER(3), nombreProveedorCHAR(50) NOT NULL, contactoCHAR(50), CONSTRAINT PK_Proveedor PRIMARY KEY (idProveedor) ); CREATE TABLE productos ( idProductoNUMBER(5), idProveedorNUMBER(3), nombreProducto CHAR(50),
  • 24. precioProducto NUMBER(8,2), CONSTRAINT PK_Productos PRIMARY KEY (idProducto), CONSTRAINT FK_Proveedor FOREIGN KEY (idProveedor) REFERENCES proveedor (idProveedor) ON DELETE SET NULL ); Descargar Reglas de negocio Toda aplicación trata de reflejar parte del funcionamiento del mundo real, para automatizar tareas que de otro modo serían llevadas a cabo de modo más ineficiente, o bien no podrían realizarse. Para ello, es necesario que cada aplicación refleje las restricciones que existen en el negocio dado, de modo que nunca sea posible llevar a cabo acciones no válidas. A las reglas que debe seguir la aplicación para garantizar se les denominareglas de negocio. Ejemplos de tales reglas son: No permitir crear facturas pertenecientes a clientes inexistentes Controlar que el saldo negativo de un cliente nunca sobrepase cierta cantidad, No emitir facturas sin RFC (Registro Federal de Causante) Limitar o cancelar los números de celular no registrados Limitar el servicio telefónico por falta de pago En realidad, la información puede ser manipulada por muchos programas distintos: así, una empresa puede tener un departamento de contabilidad que controle todo lo relacionado con compras, cobros, etc., y otro departamento técnico, que esté interesado en relacionar diversos parámetros de producción con los costes. La visión que ambos departamentos tendrán de la información y sus necesidades serán distintas, pero en cualquier caso siempre se deberán respetar las reglas de negocio. El hecho de que la información sea manipulada por diversos programas hace más difícil garantizar que todos respetan las reglas, especialmente si las aplicaciones corren en diversas máquinas, bajo distintos sistemas operativos, y están desarrolladas con distintos lenguajes y herramientas. Ejemplo: Considere el diagrama entidad relación que a continuación se expone y su correspondiente traducción a sentencias MySQL y Oracle. El cual involucra artistas, sus discos y las canciones que contiene dicho disco.
  • 25. CREATE TABLE artista ( idArtistaINTEGER, nombreArtistaCHAR(35) NOT NULL, CONSTRAINT pk_Artista PRIMARY KEY (idArtista), CONSTRAINT ak_nombreArtista UNIQUE( nombreArtista ) ) ENGINE = InnoDB; CREATE TABLE disco ( asinCHAR(12), idArtistaINTEGER NOT NULL, nombreAlbumCHAR(20) NOT NULL, yearLanzamientoINTEGER(4), marcaCHAR(20), CONSTRAINT pk_disco PRIMARY KEY (asin), CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista (idArtista) ) ENGINE = InnoDB; CREATE TABLE canciones ( idCancionINTEGER, asinCHAR(12) NOT NULL, nombreCancionCHAR(30) NOT NULL, duracionCHAR(6), estiloCHAR(15), CONSTRAINT pk_canciones PRIMARY KEY (idCancion), CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin) ) ENGINE = InnoDB; Descargar
  • 26. CREATE TABLE artista ( idArtistaNUMBER, nombreArtistaCHAR(35) NOT NULL, CONSTRAINT pk_Artista PRIMARY KEY (idArtista), CONSTRAINT ak_nombreArtista UNIQUE( nombreArtista ) ); CREATE TABLE disco ( asinCHAR(12), idArtistaNUMBER NOT NULL, nombreAlbumCHAR(20) NOT NULL, yearLanzamiento NUMBER(4), marcaCHAR(20), CONSTRAINT pk_disco PRIMARY KEY (asin), CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista (idArtista) ); CREATE TABLE canciones ( idCancionNUMBER, asinCHAR(12) NOT NULL, nombreCancionCHAR(30) NOT NULL, duracionCHAR(6), estiloCHAR(15), CONSTRAINT pk_canciones PRIMARY KEY (idCancion), CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin) ); Descargar Integridad referencial declativa La integridad de los datos es la propiedad que asegura que información dada es correcta, al cumplir ciertas aserciones. Las restricciones de integridad aseguran que la información contenida en una base de datos es correcta. Las restricciones de integridad son propiedades de la base de datos que se deben satisfacer en cualquier momento.
  • 27. Tanto Oracle y MySql son sistemas de gestión de base de datos (SGBD) relacional que permite la definición de restricciones de integridad dentro del diseño de su base de datos al ser creada. Las restricciones de integridad aseguran que la información contenida en la base de datos cumple ciertas normas o reglas para los diferentes estados. Existen dos tipos de restricciones: Estáticas: limitan los estados permitidos de la Base de Datos. Dinámicas: restringen las posibles transiciones de estados de la base datos. Para incorporar el tratamiento de las restricciones de integridad en el sistema pueden realizarse: Añadiendo código adicional para verificar y asegurar que se cumplen las restricciones (Mecanismos declarativos: Procedure o Trigger Declarando las restricciones como parte del esquema de la base de datos. La definición en la fase de diseño de las restricciones de integridad proporciona mayor número de ventajas, ya que: Reduce el costo de desarrollo de software. Es más confiable al ser centralizado y uniforme. Mantenimiento más fácil. De acuerdo con la forma de especificación del comando CREATE TABLE dada anteriormente, la cláusula CONSTRAINT puede entonces tener las siguientes formas: CONSTRAINT <constraint_name> PRIMARY KEY (<column_name >[,<column_name>]) CONSTRAINT <constraint_name> UNIQUE (<column_name>[,<column_name>]) CONSTRAINT <constraint_name> FOREIGN KEY (<column_name>[,<column_name>]) REFERENCES <table_name> CONSTRAINT <constraint_name> CHECK (<condición>)
  • 28. Donde: <constraint_name> es el nombre con el que se designará al CONSTRAINT en el esquema donde se crea la tabla que lo incluye. <column_name> es el nombre de una columna de la tabla en la que se define el CONSTRAINT <table_name> es el nombre de una tabla definida en el esquema donde existe la tabla que incluye el CONSTRAINT. <condición> es una expresión lógica en SQL. En el manual de referencia de SQL usted podrá encontrar información sobre las reglas de formación de expresiones lógicas de SQL. Un punto importantísimo a destacar es el de garantizar que los nombres de los CONSTRAINT sean nemónicos. Toda vez que un CONSTRAINTsea violado, el SGBD generará un mensaje de error indicando el CONSTRAINT que ha fallado. Asignar nombres nemónicos permitirá hacer la depuración de programas y la carga de datos mucho más sencilla, además de garantizar una perfecta cohesión entre el esquema de implantación y la documentación del esquema lógico. Es así como se sugiere utilizar el siguiente estándar de nomenclatura: Para restricciones de no-nulidad se recomienda no crear CONSTRAINT sino declarar la no-nulidad al momento de crear la tabla y para cada columna. Para asociar un CONSTRAINT de clave primaria a una tabla <table_name> se recomienda designar el “constraint" con el nombre PK_<table_name>. Para asociar un CONSTRAINT de unicidad relacionado con una clave alterna de la tabla<table_name>, se recomienda designar el CONSTRAINT con el nombre AK_<table_name> Para asociar un CONSTRAINT de clave foránea a una tabla <table_name1> que referencia a una tabla <table_name2> designe el CONSTRAINT con el nombre FK_<table_name1>_<table_name2>. Asociar un CONSTRAINT que represente una restricción de dominio sobre una columna <column_name> de una tabla <table_name>, se sugiere utilizar D_<table_name>__<column_name> como nombre del CONSTRAINT Para asociar un CONSTRAINT que represente una restricción explícita, descrita a través de una restricciôn de tipo CHECK, de una tabla <table_name> use EXP_<table_name>__R<constraint_number> como nombre del “constraint constraint_number> representará el número de restricción explícita asociado en la documentación del esquema relacional que se implanta.
  • 29. Los CONSTRAINT pueden ser agregados a una tabla previamente creada, o eliminados de una tabla existente. Para tal fin se pueden utilizar dos variaciones del comando ALTER TABLE, cuya sintaxis a continuación se indica: ALTER TABLE <table_name> ADD (<table_constraint> [,<table_constraint>]); Permitirá agregar una o más CONSTRAINT a la tabla existente en la base de datos. Cada uno de los CONSTRAINT que se añaden a la tabla seguirán las convenciones sintácticas de la cláusula <table_constraint>. ALTER TABLE <table_name> DROP CONSTRAINT <constraint_name> [CASCADE]; Eliminará de la tabla la restricción <constraint_name>. Si se utiliza la cláusula CASCADE, la eliminación del CONSTRAINT tendrá como efecto eliminar cualquier otro CONSTRAINT relacionado con elCONSTRAINT que se elimina. Por ejemplo, si se elimina un CONSTRAINT de clave primaria de una tabla A bajo modalidad CONSTRAINT entonces se eliminarán losCONSTRAINT de clave foránea que referencien a A. SOBRE LÍMITES ORACLE impone los siguientes límites en lo que respecta a los objetos descritos en esta sección: La longitud de cualquier identificador (nombre de tabla, nombre de columna, nombre de "constraints", entre otros) se limita a un máximo de 30 caracteres. El número máximo de columnas que puede tener una tabla es de 1000. El número máximo de columnas que pueden constituir una clave primaria, una clavealterna o una clave foránea es de 16. Ejemplo: Torneo Primera División Federación Mexicana de Futbol
  • 30. CREATE TABLE posicion ( idPosicionNUMBER(1), nombrePosicionCHAR(20) NOT NULL, CONSTRAINT PK_Posicion PRIMARY KEY (idPosicion) ); CREATE TABLE nacionalidad ( idNacionalidadNUMBER(3), nombreNacionalidadCHAR(20) NOT NULL, CONSTRAINT PK_Nacionalidad PRIMARY KEY (idNacionalidad) ); CREATE TABLE estadio ( idEstadioNUMBER(3), nombreEstadioCHAR(25) NOT NULL, direccionCHAR(35) NOT NULL, codigoPostalNUMBER(5), ciudadCHAR(30) NOT NULL, fechaInaguracionDATE,
  • 31. capacidadNUMBER NOT NULL, fotoCHAR(30), CONSTRAINT PK_Estadio PRIMARY KEY (idEstadio) ); CREATE TABLE equipo ( idEquipo NUMBER, nombreEquipoCHAR(25) NOT NULL, seudonimoCHAR(25) NOT NULL, nombre_oficialCHAR(60) NOT NULL, direccionCHAR(35) NOT NULL, codigoPostalNUMBER(5), ciudadCHAR(30) NOT NULL, escudoCHAR(50), fechaFundacionDATE, paginaWebCHAR(50) NOT NULL, CONSTRAINT PK_Equipo PRIMARY KEY (idEquipo) ); CREATE TABLE jugador ( idJugadorNUMBER, nombreJugadorCHAR(40), idEquipo NUMBER, idPosicionNUMBER NOT NULL, jjNUMBER DEFAULT 0, jcNUMBER DEFAULT 0, jtNUMBER DEFAULT 0, ecNUMBER DEFAULT 0, scNUMBER DEFAULT 0, minutosNUMBER DEFAULT 0, golesNUMBERDEFAULT 0, taNUMBER DEFAULT 0, trNUMBER DEFAULT 0, numeroNUMBER NOT NULL, fechaNacimientoDATENOT NULL, estatura NUMBER, pesoNUMBER, idNacionalidad NUMBERDEFAULT 1, CONSTRAINT PK_Jugador PRIMARY KEY (idJugador), CONSTRAINT FK_Juega_En FOREIGN KEY (idEquipo) REFERENCES equipo (idEquipo), CONSTRAINT FK_Juega_Como FOREIGN KEY (idPosicion) REFERENCES posicion (idPosicion), CONSTRAINT FK_Origen FOREIGN KEY (idNacionalidad) REFERENCES nacionalidad (idNacionalidad) );
  • 32. CREATE TABLE partido ( idPartidoNUMBER, jornadaNUMBER(2) NOT NULL, fechaDATE NOT NULL, horaCHAR(5) NOT NULL, idLocalNUMBER(3) NOT NULL, golLocalNUMBER(2) DEFAULT 0, idVisitanteNUMBER(3) NOT NULL, golVisitanteNUMBER(3) DEFAULT 0, idEstadioNUMBER(3) NOT NULL, arbitroCHAR(50) NOT NULL, asistente1CHAR(50) NOT NULL, asistentente2CHAR(50) NOT NULL, cJuezCHAR(50), idEquipoLocalNUMBER(3) NOT NULL, idEquipoVisitante NUMBER(3) NOT NULL, CONSTRAINT PK_Partido PRIMARY KEY (idPartido), CONSTRAINT FK_Partidos_En FOREIGN KEY (idEstadio) REFERENCES estadio (idEstadio), CONSTRAINT FK_Local FOREIGN KEY (idLocal) REFERENCES equipo (idEquipo), CONSTRAINT FK_Visitante FOREIGN KEY (idVisitante) REFERENCES equipo (idEquipo) ); Descargar CREATE TABLE posicion ( idPosicionINTEGER(1), nombrePosicionCHAR(20) NOT NULL, CONSTRAINT PK_Posicion PRIMARY KEY (idPosicion) ); CREATE TABLE nacionalidad ( idNacionalidadINTEGER(3), nombreNacionalidadCHAR(20) NOT NULL, CONSTRAINT PK_Nacionalidad PRIMARY KEY (idNacionalidad) ); CREATE TABLE estadio ( idEstadioINTEGER(3), nombreEstadioCHAR(25) NOT NULL, direccionCHAR(35) NOT NULL, codigoPostalINTEGER(5), ciudadCHAR(30) NOT NULL, fechaInaguracionDATE,
  • 33. capacidadINTEGER NOT NULL, fotoCHAR(30), CONSTRAINT PK_Estadio PRIMARY KEY (idEstadio) ); CREATE TABLE equipo ( idEquipoINTEGER, nombreEquipoCHAR(25) NOT NULL, seudonimoCHAR(25) NOT NULL, nombre_oficial CHAR(60) NOT NULL, direccionCHAR(35) NOT NULL, codigoPostalINTEGER(5), ciudad CHAR(30) NOT NULL, escudo CHAR(50), fechaFundacionDATE, paginaWebCHAR(50) NOT NULL, CONSTRAINT PK_Equipo PRIMARY KEY (idEquipo) ); CREATE TABLE jugador ( idJugador INTEGER, nombreJugadorCHAR(40), idEquipoINTEGER, idPosicionINTEGER NOT NULL, jjINTEGER DEFAULT 0, jcINTEGER DEFAULT 0, jtINTEGER DEFAULT 0, ecINTEGER DEFAULT 0, scINTEGER DEFAULT 0, minutosINTEGER DEFAULT 0, golesINTEGER DEFAULT 0, taINTEGER DEFAULT 0, trINTEGER DEFAULT 0, numeroINTEGER NOT NULL, fechaNacimientoDATE NOT NULL, estaturaINTEGER, pesoINTEGER, idNacionalidadINTEGER, CONSTRAINT PK_Jugador PRIMARY KEY (idJugador), CONSTRAINT FK_Juega_En FOREIGN KEY (idEquipo) REFERENCES equipo (idEquipo), CONSTRAINT FK_Juega_Como FOREIGN KEY (idPosicion) REFERENCES posicion (idPosicion),
  • 34. CONSTRAINT FK_Origen FOREIGN KEY (idNacionalidad) REFERENCES nacionalidad (idNacionalidad) ); CREATE TABLE partido ( idPartidoINTEGER(5) NOT NULL, jornadaINTEGER(2) NOT NULL, fechaDATE NOT NULL, horaCHAR(5) NOT NULL, idLocalINTEGER(3) NOT NULL, golLocalINTEGER(2) DEFAULT 0, idVisitanteINTEGER(3) NOT NULL, golVisitanteINTEGER(3) DEFAULT 0, idEstadioINTEGER(3) NOT NULL, arbitroCHAR(50) NOT NULL, asistente1CHAR(50) NOT NULL, asistente2CHAR(50) NOT NULL, cJuezCHAR(50), idEquipoLocalINTEGER(3) NOT NULL, idEquipoVisitante INTEGER(3) NOT NULL, CONSTRAINT PK_Partido PRIMARY KEY (idPartido), CONSTRAINT FK_Partidos_En FOREIGN KEY (idEstadio) REFERENCES estadio (idEstadio), CONSTRAINT FK_Local FOREIGN KEY (idLocal) REFERENCES equipo (idEquipo), CONSTRAINT FK_Visitante FOREIGN KEY (idVisitante) REFERENCES equipo (idEquipo) ); Descargar Ejemplo: El departamento de Postgrado e investigación del Tecnológico Virtual ha diseñado una base de datos (BD) para la gestión de losproyectos de investigación en los que participan sus investigadores. Se presenta a continuación el diagrama Entidad Relación propuesto mismo que es perfectible. Si lo hace justique sus cambios.
  • 35. DROP TABLE asignado CASCADE CONSTRAINTS; DROP TABLE proyecto CASCADE CONSTRAINTS; DROP TABLE linea CASCADE CONSTRAINTS; DROP TABLE investigador CASCADE CONSTRAINTS; DROP TABLE depAcademico CASCADE CONSTRAINTS; CREATE TABLE linea ( idLinea CHAR(20), nombreLinea CHAR(100) NOT NULL, financiadoPor CHAR(30) NOT NULL, CONSTRAINT PK_Linea PRIMARY KEY (idLinea) ); CREATE TABLE proyecto ( idProyecto CHAR(20), idLinea CHAR(20) NOT NULL, nombreProyecto CHAR(100) NOT NULL, F_Inicio DATE NOT NULL, F_Terminacion DATE NOT NULL, Presupuesto NUMBER(10,0) NOT NULL, CONSTRAINT PK_Proyecto PRIMARY KEY (idProyecto),
  • 36. CONSTRAINT FK_Linea FOREIGN KEY (idLinea) REFERENCES linea (idLinea) ); CREATE TABLE depAcademico ( idDepartamento NUMBER, Departamento CHAR(30) NOT NULL, CONSTRAINT PK_DepAcademico PRIMARY KEY (idDepartamento) ); CREATE TABLE investigador ( ife CHAR(13), nombreInvestigador CHAR(50) NOT NULL, telefono CHAR(10) NOT NULL, email CHAR(50) NOT NULL, idDepartamento NUMBER NOT NULL, CONSTRAINT PK_Investigador PRIMARY KEY (ife), CONSTRAINT FK_DepAcademico FOREIGN KEY (idDepartamento) REFERENCES depAcademico (idDepartamento) ); CREATE TABLE asignado ( ife CHAR(13) NOT NULL, idProyecto CHAR(20) NOT NULL, F_Inicio DATE NOT NULL, F_Termino DATE, tipoParticipacion CHAR(20) NOT NULL, CONSTRAINT FK_Investigador FOREIGN KEY (ife) REFERENCES investigador (ife), CONSTRAINT FK_Proyecto FOREIGN KEY (idProyecto) REFERENCES proyecto (idProyecto) ); DROP TABLE IF EXISTS asignado, proyecto, linea, investigador, depAcademico; CREATE TABLE linea ( idLinea CHAR(20), nombreLinea CHAR(100) NOT NULL, financiadoPor CHAR(30) NOT NULL, CONSTRAINT PK_Linea PRIMARY KEY (idLinea) );
  • 37. CREATE TABLE proyecto ( idProyecto CHAR(20), idLinea CHAR(20) NOT NULL, nombreProyecto CHAR(100) NOT NULL, F_Inicio DATE NOT NULL, F_Terminacion DATE NOT NULL, Presupuesto DECIMAL(10,0) NOT NULL, CONSTRAINT PK_Proyecto PRIMARY KEY (idProyecto), CONSTRAINT FK_Linea FOREIGN KEY (idLinea) REFERENCES LINEA (idLinea) ); CREATE TABLE depAcademico ( idDepartamento INTEGER, Departamento CHAR(30) NOT NULL, CONSTRAINT PK_DepAcademico PRIMARY KEY (idDepartamento) ); CREATE TABLE investigador ( ife CHAR(13), nombreInvestigador CHAR(50) NOT NULL, telefono CHAR(10) NOT NULL, email CHAR(50) NOT NULL, idDepartamento INTEGER NOT NULL, CONSTRAINT PK_Investigador PRIMARY KEY (ife), CONSTRAINT FK_DepAcademico FOREIGN KEY (idDepartamento) REFERENCES depAcademico (idDepartamento) ); CREATE TABLE asignado ( ife CHAR(13) NOT NULL, idProyecto CHAR(20) NOT NULL, F_Inicio DATE NOT NULL, F_Termino DATE, tipoParticipacion CHAR(20) NOT NULL, CONSTRAINT FK_Investigador FOREIGN KEY (ife) REFERENCES investigador (ife), CONSTRAINT FK_Proyecto FOREIGN KEY (idProyecto) REFERENCES proyecto (idProyecto) );
  • 38. 3.1. INSERT La sentencia INSERT permite agregar nuevas filas de datos a las tablas existentes. Está sentencia tiene como sintaxis genérica. INSERT INTO tabla_o_vista [(lista_de_columnas)] VALUES (lista_de_valores_de_datos) Para insertar datos en una relación, se específica la tupla que se desea insertar o se formula una consulta cuyo resultado sea el conjunto de tuplas que se desea insertar. Obviamente, los valores de los atributos de las tuplas que se inserten deben pertenecer al dominio de los atributos. De igual modo, las tuplas insertadas deben ser de la aridad -número de atributos- correcta. Considere el siguiente Diagrama Entidad Relación y su correspondiente script Oracle ? 1 2 3 4 5 CREATETABLEdepartamento ( idDepartamento NUMBER(3), nombre CHAR(15) NOTNULL, ciudad CHAR(10) NOTNULL, CONSTRAINTDOM_Ciudad CHECK(ciudad IN('Veracruz', 'Xalapa', 'Orizaba', 'Regional')),
  • 39. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 CONSTRAINTPK_Departamento PRIMARYKEY(idDepartamento) ); CREATETABLEempleado( idEmpleado NUMBER(3), rfc CHAR(14), nombreEmpleado CHAR(40) NOTNULL, oficio CHAR(11) NOTNULL, cargo CHAR(15) NOTNULL, jefe NUMBER(3), ingreso DATENOTNULL, salario NUMBER(10,2), comision NUMBER(10,2), idDepartamento NUMBER(3) NOTNULL, CONSTRAINT DOM_Empleado_Salario CHECK( salario > 0 ), CONSTRAINT PK_Empleado PRIMARYKEY(idEmpleado), CONSTRAINT AK_Empleado UNIQUE(rfc), CONSTRAINT FK_Empleado_Jefe FOREIGNKEY(jefe) REFERENCES Empleado, CONSTRAINT FK_Empleado FOREIGNKEY(idDepartamento) REFERENCESDepartamento, CONSTRAINT DOM_Empleado_NombreEmpleado CHECK(nombreEmpleado = NLS_UPPER(nombreEmpleado)) ); Descargar Considere los siguientes datos Tabla: Departamento idDepartamento Departamento Ciudad 1 Ventas Veracruz 2 Ventas Xalapa 3 Cobranza Veracruz 4 Cobranza Xalapa 5 Credito Orizaba 6 Credito Veracruz
  • 40. 7 Credito Xalapa Un formato posible es: INSERT INTO nombre-tabla VALUES (serie de valores); El orden en el que se asignen los valores en la cláusula VALUES tiene que coincidir con el orden en que se definieron las columnas en la creación del objeto tabla, dado que los valores se asignan por posicionamiento relativo. Por ejemplo: INSERT INTO departamento VALUES (1,'Ventas','Veracruz'); INSERT INTO departamento VALUES (2,'Ventas','Xalapa'); INSERT INTO departamento VALUES (3,'Cobranza','Veracruz'); INSERT INTO departamento VALUES (4,'Cobranza','Xalapa'); INSERT INTO departamento VALUES (5,'Credito','Orizaba'); INSERT INTO departamento VALUES (6,'Credito','Veracruz'); INSERT INTO departamento VALUES (7,'Credito','Xalapa'); Otra forma de usar la sentecia INSERT es: INSERT INTO nombre-tabla (columna1, columna2...) VALUES (valor1, valor2...); En este caso los valores se asignarán a cada una de las columnas mencionadas por posicionamiento relativo. Es necesario que por lo menos se asignen valores a todas aquellas columnas que no admiten valores nulos en la tabla (NOT NULL). Por ejemplo: INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo, jefe, ingreso, salario, comision, idDepartamento)
  • 41. VALUES (12, 'ROTL790411FRT', 'ROMERO TERRENOS, LUIS', 'Ingeniero', 'Director', NULL, '01/01/2006', 7000, 0.2, 4); Insertar mediante un SELECT CREATE GLOBAL TEMPORARY TABLE detalle ( rfc CHAR(14) PRIMARY KEY, nombreEmpleado CHAR(40) NOT NULL, salarioNeto NUMBER(10,2) ) ON COMMIT PRESERVE ROWS; INSERT INTO detalle SELECT rfc, nombreEmpleado, salario + salario*comision FROM empleado WHERE comision > 0; Inserción por selección Sentencia WHEN Ejemplo: Usaremos la cotización del dolar para solventar obligaciones el archivo original contiene valores de 1995 al 18 de enero de 2011. Separemos esta tabla en cotizaciones mayores de 14 pesos, entre 13 a 14 y otras CREATE TABLE dolar ( fecha DATE, precio NUMBER(8,4) ); CREATE TABLE dolar13 ( fecha DATE, precio NUMBER(8,4) ); CREATE TABLE dolar12 ( fecha DATE, precio NUMBER(8,4) ); CREATE TABLE dolarOtros ( fecha DATE, precio NUMBER(8,4) ); INSERT WHEN (precio >= 13) THEN INTO dolar13 VALUES (fecha, precio)
  • 42. WHEN (precio >= 12 AND precio < 13) THEN INTO dolar12 VALUES (fecha, precio) ELSE INTO dolarOtros VALUES (fecha, precio) SELECT * FROM dolar Descargar 3.1. UPDATE En determinadas situaciones puede ser deseable cambiar un valor dentro de una tupla, sin cambiar todos los valores de la misma. Para ello se utiliza el comando UPDATE cuya sintaxis se muestra a continuación. UPDATE tabla SET {columna = expresión,} + [WHERE condición;] Se especificará en la cláusula SET las columnas que se actualizarán y con qué valores. La cláusula WHERE indica las filas con las que se va a trabajar, sin la cláusula WHERE la actualización afectará a todas las filas de la tabla. Si se desea actualizar a nulos, se asignará el valor NULL. UPDATE cliente SET observaciones = NULL; Por ejemplo, cambie el nombre del departamento Credito por Crédito. UPDATE Departamento SET nombre = 'Crédito' WHERE nombre = 'Credito'; La clausula WHERE permite SELECT anidados como en el caso del INSERT o el DELETE. SQL ofrece el constructor CASE, que puede usarse para formular actualizaciones dependientes. Por ejemplo;
  • 43. CREATE TABLEmoreliaC2012( numeroNUMBER(3), nombreJugadorCHAR(40), posicionCHAR(4), jjNUMBER(2), jcNUMBER(2), jtNUMBER(2), ecNUMBER(2), scNUMBER(2), minutosNUMBER(6), golNUMBER(4), ppgNUMBER(2), trNUMBER(2), taNUMBER(2) ); CREATE TABLE juegoLimpio ( nombreCHAR(45), juegaCHAR(15) ); INSERT INTO juegoLimpio (nombre,juega) SELECT nombreJugador,(ta+tr) FROM moreliaC2012; UPDATE juegoLimpio SET juega = CASE WHEN juega = '0' THEN 'Limpio' ELSE 'Sucio' END; SELECT * FROM juegoLimpio; Descargar CREATE TABLEmoreliaC2012( numeroINTEGER(3), nombreJugadorCHAR(40), posicionCHAR(4), jjINTEGER(2), jcINTEGER(2), jtINTEGER(2), ecINTEGER(2), scINTEGERER(2), minutosINTEGER(6),
  • 44. golINTEGER(4), ppgINTEGER(2), trINTEGER(2), taINTEGER(2) ); CREATE TABLE juegoLimpio ( nombreCHAR(45), juegaCHAR(15) ); INSERT INTO juegoLimpio (nombre,juega) SELECT nombreJugador,(ta+tr) FROM moreliaC2012; UPDATE juegoLimpio SET juega = CASE WHEN juega = '0' THEN 'Limpio' ELSE 'Sucio' END; SELECT * FROM juegoLimpio; Descargar 3.1. DELETE (Oracle y MySQL) Borrará todas las filas que cumplan la condición especificada en la cláusula WHERE. Si esta cláusula se omite, se borrarán todas las filas de la tabla. DELETE borra todas las filas de una tabla, pero no la definición de la tabla del diccionario. Esta es una diferencia con la sentencia DROPTABLE, que elimina el contenido de la tabla y la definición de la misma. La sintaxis es la que sigue: DELETE FROM tabla [WHERE condición]; Obsérvese que cada comando DELETE sólo opera sobre una relación. Si se desea borrar tuplas de varias relaciones es necesario utilizar una orden DELETE por cada relación.
  • 45. La consulta DELETE FROM empleados; Borra todas las tuplas de la tabla empleados La consulta DELETE FROM empleados WHERE cargo = 'Chofer'; Borra los empleados con cargo de chofer Cuando trabajemos con la sentencia DELETE debemos tener en cuenta las siguientes consideraciones: Solo podemos borrar datos de una única tabla. Cuando borramos datos de una vista, los estamos borrando también de la tabla. Las vistas son solo una forma de ver los datos, no una copia. Si intentamos borrar un registro de una tabla referenciada por una FOREING KEY como tabla maestra, si la tabla dependiente tiene registros relacionados la sentencia DELETE fallará a no ser que la tabla hija contenga la sentencia ON DELETE CASCADE.. TRUNCATE TRUNCATE es una mejor alternativa a DELETE cuando se desea borrar todo el contenido de la tabla. La sintaxis es:
  • 46. TRUNCATE TABLE nombre_tabla; Eliminar registros con la sentencia TRUNCATE es más rápido que con la sentencia DELETE, especialmente cuando la tabla tiene numerosos disparadores, índices y otras dependencias como por ejemplo integridad referencial. La sentencia TRUNCATE no es transaccional. No se puede deshacer (ROLL BACK) y ocurre un error en casos de bloqueo de tabla. la tabla puede recrearse como una vacía con TRUNCATE TABLE, incluso si los archivos de datos o de índice se han corrompido En MySQL el manejador de tablas reinicia el valor AUTO_INCREMENT usado. Esto es cierto incluso para MyISAM y InnoDB 3.2.1 SELECT La recuperación de los datos en el lenguaje SQL se realiza mediante la sentencia SELECT, seleccionar. Esta sentencia permite indicar al SGBD la información que se quiere recuperar. Esta es la sentencia SQL, más habitual. La sentencia SELECT consta de cuatro partes básicas: La cláusula SELECT seguida de la descripción de lo que se desea ver, los nombres de las columnas a seleccionar. Esta parte es obligatoria. La cláusula FROM seguida de la especificación de las tablas de las que se han de obtener los datos. Esta parte es obligatoria. La cláusula WHERE seguida por un criterio de selección, una condición. Esta parte es opcional. La cláusula ORDER BY seguida por el criterio de ordenación. Esta parte es opcional. Una primera aproximación a la sintaxis de la sentencia SELECT puede mostrarnos la siguiente expresión: SELECT {* | {columna,}+} FROM {tabla,}+ [WHERE condición] [ORDER BY {expresiónColumna [ASC | DESC],}+]; Selección de columnas
  • 47. Las columnas a seleccionar se enumeran sin más en la cláusula SELECT. Para seleccionar todas las columnas use el carácter asterisco ' *'. Cuando se consulta una base de datos, los nombres de las columnas se usan como cabeceras de presentación. Si éste resulta demasiado largo, corto o críptico, puede cambiarse con la misma sentencia SQL de consulta, creando un alias de columna Cláusula FROM La cláusula FROM define las tablas de las que se van a seleccionar las columnas. Se puede añadir al nombre de las tablas el usuario propietario de las mismas de la forma usuario.tabla. De esta manera podemos distinguir entre las tablas de un usuario y otro. Oracle siempre considera como prefijo el nombre del propietario de las tablas, aunque no se lo indiquemos. De esta forma dos o más usuarios pueden tener tablas que se llamen igual sin que surjan conflictos. Si quisiéramos acceder a las filas de la tabla departamento del usuario epacheco, (ademas de tener privilegios de lectura sobre esa tabla) deberíamos escribir la siguiente sentencia SQL:
  • 48. También se puede asociar un alias a las tablas para abreviar los nombres de las tablas. Un ejemplo se puede ver en la sentencia SQL siguiente: SELECT d.nombre "Nombre Departamento", d.ciudad "Ubicado en" FROM departamento d Un campo calculado o campo derivado es una expresión numérica y que deberá ser referenciada mediante un alias mediante el uso de la cláusulaAS, en Oracle y MySQL está sentencia es opcional. Por ejemplo calcular el sueldo diario de un empleado. SELECT nombreEmpleado "Nombre Empleado", TO_CHAR(salario/30,'999,999.99') "Salario Diario" FROM empleado SELECT nombreEmpleado "Nombre Empleado", FORMAT(salario/30,2) "Salario Diario" FROM empleado Ejemplo: Valores distintos y limitados SELECT DISTINCT nombreJugador FROM femexfut LIMIT 20
  • 49. Ejecutar 3.2.2 Retricción y ordenación de datos La sentencia SELECT recupera todas las columnas o un subconjunto de ellas de una tabla. Esto afecta a todas las filas de la tabla, a menos que especifiquemos una condición en la cláusula WHERE. Esta condición regresa todas las filas que cumplen dicha condicional. La complejidad del criterio de búsqueda es prácticamente ilimitada, y en él se pueden combinar operadores de diversos tipos con funciones de columnas, componiendo expresiones más o menos complejas. Condición de búsqueda basada en una comparación compuesta En este ejemplo, se utiliza el operador lógico OR en la cláusula WHERE para localizar los empleados que son chofer o secretaria. La consulta y la tabla resultados se muestra a continuación. SELECT nombreEmpleado "Nombre Empleado", oficio FROM empleado WHERE (oficio = 'Chofer') OR (oficio = 'Secretaria') Ejecutar Condición de búsqueda basada en rango La condición BETWEEN indica los puntos extremos del rango, por lo cual el resultado incluirá tambien a todos los empleados cuyo salario esté entre 2,500 y 5,000 pesos. SELECT nombreEmpleado "Nombre Empleado", oficio, TO_CHAR(salario,'999,999') Salario FROM empleado WHERE salario BETWEEN 2500 AND 5000; SELECT nombreEmpleado "Nombre Empleado",
  • 50. oficio, FORMAT(salario,0) Salario FROM empleado WHERE salario BETWEEN 2500 AND 5000; Ejecutar La condición de pertenencia de un conjunto (IN) comprueba si un valor de los datos se corresponde con uno de los valores especificados en una determinada lista, que en este caso está compuesta por sólo dos opciones 'Chofer' y 'Secretaria'. La consulta y la tabla resultado se muestra a continuación. SELECT nombreEmpleado "Nombre Empleado", oficio, TO_CHAR(salario,'999,999') Salario FROM Empleado WHERE oficio IN ('Chofer', 'Secretaria'); SELECT nombreEmpleado "Nombre Empleado", oficio, FORMAT(salario, 0) Salario FROM Empleado WHERE oficio IN ('Chofer', 'Secretaria'); Ejecutar La operación más utilizada sobre las cadenas de caracteres es la comparación de patrones, para la que se usa el operador LIKE. Para la descripción de los patrones se utilizan dos caracteres especiales: % El carácter % coincide con cualquier subcadena de caracteres _ El carácter _ coincide con cualquier carácter Considere la consulta: Determinar que empleados se apellidan o se llaman 'OLIVEROS' SELECT nombreEmpleado "Nombre Empleado", oficio, TO_CHAR(salario,'999,999') Salario FROM Empleado WHERE nombreEmpleado LIKE '%OLIVEROS%'; SELECT nombreEmpleado "Nombre Empleado", oficio,
  • 51. FORMAT(salario,2) Salario FROM Empleado WHERE nombreEmpleado LIKE '%OLIVEROS%'; Ejecutar Cláusula ORDER BY En general, las filas de la tabla resultados de una consulta SQL, no están ordenadas por ningún criterio particular. Sin embargo podemos garantizar que los resultados de la consulta queden ordenados utilizando la cláusula ORDER BY en la instrucción SELECT. La cláusula ORDER BY está compuesta por una lista de identificadores de columna según los cuales hay que ordenar los resultados, separados por comas. ORDER BY se usa para especificar el criterio de ordenación de la respuesta a la consulta. Por defecto la ordenación es ascendente, aunque se puede especificar un orden descendente (DESC). La ordenación se puede establecer sobre el contenido de columnas o sobre expresiones con columnas. Ejemplo: Consulta de los empleados ordenado de manera descendente por su salario y en caso de igualdad de salario, ordenado ascendentemente por su nombre. SELECT nombreEmpleado "Nombre Empleado", oficio, TO_CHAR(salario,'999,999') Salario FROM empleado ORDER BY Salario DESC, nombreEmpleado; SELECT nombreEmpleado "Nombre Empleado", oficio, FORMAT(salario,0) Salario FROM empleado ORDER BY Salario DESC, nombreEmpleado; Ejecutar Ejemplo MySQL: Se presentan los campeones NBA ordenados por temporada.
  • 52. SELECT temporada, campeon, ganador, perdedor, subcampeon FROM campeonesNBA ORDER BY temporada DESC Descargar Ejecutar Cláusula DISTINCT Cuando se realiza una consulta sobre una tabla en la que se extrae información de varias columnas, puede ocurrir que, si no incluimos la/s columna/s que forman la clave principal, obtengamos filas repetidas en la respuesta. Si este comportamiento es no satisfactorio podemos utilizar la cláusula DISTINCT para eliminar las filas duplicadas obtenidas como respuesta a una consulta. Ejemplo: Obtener los campeones NBA SELECT DISTINCT campeon FROM campeonesNBA ORDER BY campeon Ejecutar Ejemplo: Antiguedad de los empleados en la empresa SELECT nombreEmpleado, TRUNC(MONTHS_BETWEEN(SYSDATE, ingreso)/12) AS antiguedad FROM empleado ORDER BY antiguedad DESC, nombreEmpleado;
  • 53. SELECT nombreEmpleado, (YEAR(CURDATE()) - YEAR(ingreso)) - (RIGHT(CURDATE(), 5) < RIGHT(ingreso,5)) AS antiguedad FROM empleado ORDER BY antiguedad DESC, nombreEmpleado; Ejecutar Expresión CASE La expresión CASE permite utilizar la lógica IF-THEN-ELSE en sentencias SQL sin tener que invocar procedimientos. Esta expresión se incluye a partir de la versión Oracle9i Server y MySQL 5. La siguiente es la sintaxis que presenta la expresión CASE: SELECT campos, CASE expresión WHEN Comparación_1 THEN return_expresión_1 [ WHENComparación_2 THEN return_expresión_2 WHEN Comparación_n THEN return_expresión_n ELSE else_expresión] END FROM tabla Expresión es opcional. (ie: Comparación_1, Comparación_2, ... Comparación_n) deben ser del mismo tipo y son evaluadas en el orden que se listan y regresara return_expresión de la primera Comparación que regresa TRUE, si ninguna expresión es evaluada como TRUE se regresa el valor declarado en el ELSE. Si la clausula ELSE es omitida y ninguna condición es evaluda TRUE. La sentencia CASE regresa NULL. Es posible declarar un máximo de 255 comparaciones en la sentencia CASE. Cada clausula WHEN ... THEN es considerada como 2 comparaciones.
  • 54. Ejemplo: Se requiere saber si un empleado tiene derecho al estimulo por antiguedad de 10 o 6 años SELECT nombreEmpleado, CASE WHEN TRUNC(MONTHS_BETWEEN(SYSDATE, ingreso)/12) = 10 THEN 'Estimulo 10 años' WHEN TRUNC(MONTHS_BETWEEN(SYSDATE, ingreso)/12) = 6 THEN 'Estimulo 6 años' ELSE '' END AS Estimulo FROM empleado ORDER BY nombreEmpleado SELECT nombreEmpleado, CASE WHEN (YEAR(CURDATE()) - YEAR(ingreso)) - (RIGHT(CURDATE(), 5) < RIGHT(ingreso,5)) = 10 THEN 'Estimulo 10 años' WHEN (YEAR(CURDATE()) - YEAR(ingreso)) - (RIGHT(CURDATE(), 5) <RIGHT(ingreso,5)) = 6 THEN 'Estimulo 6 años' ELSE '' END AS Estimulo FROM empleado ORDER BY nombreEmpleado Ejecutar 3.2.3. GROUP BY La cláusula GROUP BY combina los registros con valores idénticos en la lista de campos especificada en un único registro. Para cada registro se puede crear un valor agregado si se incluye una función SQL agregada como por ejemplo SUM o COUNT, en la instrucción SELECT. Su sintaxis es: SELECT [ALL | DISTINCT ] <nombre_campo> [{,<nombre_campo>}] [{,<funcion_agregación>}] FROM <nombre_tabla>|<nombre_vista>
  • 55. [{,<nombre_tabla>|<nombre_vista>}] [WHERE <condición> [{ AND|OR <condición>}]] [GROUP BY <nombre_campo> [{,<nombre_campo >}]] [HAVING <condición>[{ AND|OR <condición>}]] [ORDER BY <nombre_campo>|<campo_índice> [ASC | DESC] [{,<nombre_campo>|<campo_índice> [ASC | DESC ]}]] En la cláusula GROUP BY se colocan las columnas por las que vamos a agrupar. Y en la cláusula HAVING filtra los registros una vez agrupados. La evaluación de las diferentes cláusulas en tiempo de ejecución, se efectúa en el siguiente orden: Cláusula Descripción WHERE Filtra las filas GROUP BY Crea una tabla de grupo nueva HAVING Filtra los grupos ORDER BY Clasifica la salida Los valores NULL en los campos de GROUP BY se agrupan y no se omiten. Sin embargo, los valores NULL no se calculan en ninguna función de agregado SQL. Un ejemplo de SELECT de grupos es consultar los empleados agrupados por su oficio. Un primer intento de consulta es el siguiente: SELECT oficio, nombreEmpleado FROM empleado GROUP BY oficio
  • 56. Se presenta un error debido a que cuando se utiliza GROUP BY, las columnas implicadas en el SELECT y que no aparezcan en la cláusulaGROUP BY deben tener una función de agrupamiento. En otras palabras, la columna nombreEmpleado debe tener una función de agrupamiento que actue sobre ella (MAX, MIN, SUM, COUNT, AVG). De no ser posible, deberá aparecer dicha columna a la cláusulaGROUP BY. La consulta correcta quedaria así; SELECT oficio, COUNT(nombreEmpleado) Elementos FROM empleado GROUP BY oficio ORDER BY oficio Ejecutar Ejemplo: Considere los alumnos inscritos en las materias que imparto durante Enero Junio 2011 en el ITV. La siguiente consulta obtiene el número de alumnos por género y materia. SELECT Genero, COUNT(*) Alumnos FROM alumnosITV GROUP BY Genero Descargar Ejecutar Ejemplo: Para ser campeón de la NBA hay que ganar cuatro partidos de siete. El ejemplo muestra el número de juegos necesarios para ser campeón de 1946 a 2011. SELECT ganador, perdedor, COUNT(*) ocurrencias FROM campeonesNBA GROUP BY ganador, perdedor ORDER BY ganador, perdedor Descargar Ejecutar
  • 57. Ejemplo: Número de jugadores registrados por equipo en primera división de la primera división del Futbol Mexicano. SELECT equipo, COUNT(*) registrados FROM femexfut WHERE torneo = 'Bicentenario 2010' GROUP BY equipo Ejecutar Ejemplo: Número de jugadores por equipo que no participaron ni un minuto en primera división en el torneo Bicentenario 2010 de la primera división del Futbol Mexicano. SELECT equipo, COUNT(*) jugadores FROM femexfut WHERE torneo = 'Apertura 2010' AND minutos = 0 GROUP BY equipo ORDER BY jugadores DESC, equipo Ejecutar HAVING La cláusula HAVING se utiliza para especificar una condición, se comporta como WHERE, con la diferencia que HAVING se aplica a grupos y no a tuplas (registros). Es decir HAVING filtra los registros agrupados.
  • 58. Ejemplo: Considere la siguiente información relativa a automoviles, modelos y precios MODELO AÑO PRECIO SABLE 2001 50,000 AUDI-A4 2007 420,000 BMW-323 2000 115,000 PORSCHE BOXSTER-987 2002 310,000 MALIBU 1998 32,000 STRATUS-RT 2005 97,500 CHRYSLER 300-C 2005 185,000 FUSION 2006 150,000 CUTLASS EUROSPORT 1992 25,000 CIVIC COUPE 2006 135,000 CIVIC LS-4L 2004 89,000 ACCORD EXR-L4 1998 53,000 PLATINA 2005 65,000 PLATINA 2004 60,000 ALTIMA 2003 92,000 ALTIMA 2007 179,000 ALTIMA 2005 105,000 PEUGEOT 206 XR 2006 65,000 TOYOTA COROLLA XRS 2009 190,000 VW SEDAN 1998 25,000 Calcule el promedio por año para todas las marcas a partir del 2003.
  • 59. CREATE TABLE carros ( modelo CHAR(25), yearCHAR(4), precio NUMBER ); SELECT year, TO_CHAR(AVG(precio),'999,999.22') media FROM carros GROUP BY year HAVING year > 2002 ORDER BY year; CREATE TABLE carros ( modelo CHAR(25), yearCHAR(4), precio INTEGER ) ENGINE = innoDB; SELECT year, FORMAT(AVG(precio),2) media FROM carros GROUP BY year HAVING year > 2002 ORDER BY year; Descargar Ejecutar 3.2.4. Consultas sobre múltiples tablas Todos los ejemplos ejecutados hasta ahora tienen una limitación significativa, es decir todas las columnas incluidas en la tabla resultados provienen de una misma tabla. La verdadera potencia del SQL se alcanza cuando combinamos el contenido de más de una tabla. Suponga que desea conseguir una lista con los empleados y los departamentos para los que trabajan. Esta información está repartida en las dos tablas empleado y departamento.
  • 60. Si necesitamos obtener información de más de una tabla, tendremos la opción de utilizar subconsultas o combinaciones. Si la tabla de resultados final debe contener columnas de tablas diferentes, entonces deberemos utilizar obligatoriamente una combinación. Para realizar una combinación, basta incluir más de un nombre en la cláusula FROM, utilizando una coma como separador y, normalmente, incluyendo una clâusulaWHERE para especificar la columna o columnas con las que hay que realizar la combinación. Así, podríamos intentar una consulta que seleccionara el campo nombre de la tabla empleado y el nombre del departamento. Y aquí surge el primer problema, ¿cómo distinguimos entre dos columnas que llamándose igual, pertenecen a tablas distintas? El uso de alias para las tablas incluidas en el FROM o en las columnas del SELECT permite evitar la ambigüedad, el alias se separa por un espacio. Considere el siguiente modelo físico relacional y su correspondiente código SQL en MySQL y Oracle La traducción a SQL es CREATE TABLE artista ( idArtistaNUMBER, nombreArtistaCHAR(35) NOT NULL,
  • 61. CONSTRAINT pk_Artista PRIMARY KEY (idArtista), CONSTRAINT ak_nombreArtista UNIQUE( nombreArtista ) ); CREATE TABLE disco ( asinCHAR(12), idArtistaNUMBER NOT NULL, nombreAlbumCHAR(20) NOT NULL, yearLanzamiento NUMBER(4), marcaCHAR(20), CONSTRAINT pk_disco PRIMARY KEY (asin), CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista (idArtista) ); CREATE TABLE canciones ( idCancionNUMBER, posicionNUMBER NOT NULL, asinCHAR(12) NOT NULL, nombreCancionCHAR(30) NOT NULL, duracionCHAR(6), estiloCHAR(15), CONSTRAINT pk_canciones PRIMARY KEY (idCancion), CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin) ); DROP TABLE IF EXISTS canciones, disco, artista; CREATE TABLE artista ( idArtistaINTEGER, nombreArtistaCHAR(35) NOT NULL, CONSTRAINT pk_Artista PRIMARY KEY (idArtista), CONSTRAINT ak_nombreArtista UNIQUE( nombreArtista ) ) ENGINE = innoDB; CREATE TABLE disco ( asinCHAR(12), idArtistaINTEGER NOT NULL, nombreAlbumCHAR(20) NOT NULL, yearLanzamientoINTEGER(4), marcaCHAR(20), CONSTRAINT pk_disco PRIMARY KEY (asin), CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista (idArtista) ) ENGINE = innoDB;
  • 62. CREATE TABLE canciones ( idCancionINTEGER AUTO_INCREMENT, posicionINTEGER NOT NULL, asinCHAR(12) NOT NULL, nombreCancionCHAR(30) NOT NULL, duracionCHAR(6), estiloCHAR(15), CONSTRAINT pk_canciones PRIMARY KEY (idCancion), CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin) ) ENGINE = innoDB; SELECT * FROM artista, disco Descargar Ejecutar El resultado es incorrecto, ya que obtenemos es el producto cartesiano de todos los artistas por todos los discos. SQL tomo cada fila de la tabladisco y le ha asociado todos los idArtista de la tabla artista. Reglas de Combinación: Pueden combinarse tantas tablas como se desee. El criterio de combinación puede estar formado por más de una pareja de columnas. En la cláusula SELECT pueden citarse columnas de ambas tablas, condicionen o no la combinación. Si hay columnas con el mismo nombre en las distintas tablas, deben identificarse especificando la tabla de procedencia o utilizando un alias de tabla. Es necesario incluir una clasula WHERE que asocie las tablas mediante las correspondientes llaves Para lograr el resultado correcto necesitamos asociar un disco con el nombre del artista que lo interpreta. Y esto se puede hacer si añadimos la condición en la cual idArtista el mismo valor en la fila de la tabla disco que en la fila correspondiente de la tabla artista.
  • 63. SELECT * FROM artista A, disco D WHERE A.idArtista = D.idArtista Ejecutar Ejemplo: Considere el siguiente Modelo físico relacional. Que descibe las relaciones existentes para el torneo apertura 2009 del futbol Mexicano de 1era división. Para crear la estructura y los datos, es necesario realizar el siguiente Procedimiento Ejemplo: Generar un listado con los nombres de todos los jugadores del América que jugaron como porteros durante el torneo Apertura 2009. SELECT E.nombreEquipo, J.nombre Nombre, P.nombrePosicion Posicion FROM equipo E, posicion P, jugador J WHERE (J.idEquipo = E.idEquipo) AND( J.idEquipo = 1) AND (J.idPosicion = 1) AND (P.idPosicion = J.idPosicion) AND (J.jj >0 ) ORDER BY J.nombre
  • 64. Descargar Ejecutar 3.2.5. Subconsultas Una subconsulta es una instrucción SELECT anidada dentro de una sentencia SELECT, SELECT...INTO, INSERT...INTO, DELETE, o UPDATEo dentro de otra subconsulta. Una subconsulta, a su vez, puede contener otra subconsulta y así hasta un máximo de 16 niveles. Las particularidades de las subconsultas son: 1. Su resultado no se visualiza, sino que se pasa a la consulta principal para su comprobación. 2. Puede devolver un valor único o una lista de valores y en dependencia de esto se debe usar el operador del tipo correspondiente. 3. No puede usar el operador BETWEEN, ni contener la setencia ORDER BY. 4. Puede contener una sola columna, que es lo más común, o varias columnas.Este último caso se llama subconsulta con columnas múltiples. Cuando dos o más columnas serán comprobadas al mismo tiempo, deben encerrarse entre paréntesis. Ejemplo: Nombres de los jugadores que han participado más que el promedio, equipo y posición durante un torneo SELECT equipo, nombreJugador, posicion, minutos FROM femexfut WHERE minutos >(SELECT AVG(minutos) FROM femexfut WHERE torneo = 'Bicentenario 2010' AND jj > 0) AND torneo = 'Bicentenario 2010' ORDER BY equipo, posicion, nombreJugador Descargar
  • 65. Ejecutar La consulta más interna calcula el promedio de minutos jugados, y la consulta más externa lo utiliza para seleccionar los nombres de los jugadores que participan más del promedio. El valor de comparación puede ser un valor simple, como en el ejemplo anterior, o un conjunto de valores. Hay que tener en cuenta este detalle ya que el tipo de operador a utilizar varía. En el primer caso se puede utilizar un operador de comparación de carácter aritmético (<, >, etc.). Y en el segundo uno de tipo lógico (IN). Las subconsultas pueden devolver más de una columna, y se habrán de comparar de manera consecuente: Las columnas de la clausula WHERE de la consulta principal deben estar agrupadas por paréntesis. Las columnas encerradas entre paréntesis deben coincidir en número y tipo de datos con los datos que devuelve la subconsulta. Se puede utilizar una subconsulta para insertar valores en una tabla en el momento de la creación de la misma. Ejemplo: Crear una tabla con los datos de los jugadores que participan más que el promedio y su desviación: CREATE TABLE borrame SELECT minutos, nombreJugador FROM femexfut WHERE minutos > ( SELECT AVG(minutos) + STDDEV(minutos) FROM femexfut WHEREjj> 0 AND torneo = 'Bicentenario 2010') AND torneo = 'Bicentenario 2010'
  • 66. ORDER BY minutos DESC, nombreJugador Ejecutar No es necesario especificar tipos ni tamaños de las columnas, ya que vienen determinados por los tipos y tamaños de las columnas recuperadas en la subconsulta. Ejemplo: Valor más reciente del dólar en la base de datos SELECT fecha, precio FROM dolar WHERE fecha =( SELECT MAX(fecha) FROM dolar) Ejecutar 3.2.6. Operadores Join Las consultas multitabla o JOINS. también denominadas combinaciones o composiciones, permiten recuperar datos de dos tablas o más según las relaciones lógicas entre ellas. Las combinaciones indican cómo debería utilizar el SGBD los datos de una tabla para seleccionar los datos de otra tabla. Una condición de combinación (o composición) define la forma en la que dos tablas se relacionan en una consulta al: Especificar la columna de cada tabla que debe usarse para la combinación. Una condición de combinación específica una clave externa de una tabla y su clave asociada en otra tabla. Relación padre - hija. Especificar un operador lógico (=, <>, etc.) para usarlo en los valores de comparación de las columnas Es una operación que combina registros de dos tablas en una base de datos relacional que resulta en una nueva tabla (temporal) llamada tabla de JOIN. En el lenguaje de consulta SQL hay dos tipos de JOIN: INNER y OUTER.
  • 67. Como caso especial, una tabla (tabla base, vista o una tabla JOIN) puede realizar la operación JOIN sobre ella misma. Esto se conoce como self-JOIN. Ejemplo: Jugadores que participaron con el Cruz Azul durante el torneo Apertura 2011, minutos jugados y partidos en los que participo (JJ) SELECT J.nombre, J.jj, J.minutos FROM jugadores_Clausura2011 J, equipos E WHERE (J.idEquipo = E.idEquipo) AND (E.idEquipo = 5) ORDER BY J.jj DESC, J.minutos DESC, J.nombre Descargar Ejecutar Ejemplo: Jugadores por posición del Cruz Azul que participaron al menos un minuto en el Apertura 2011 SELECT J.nombre, J.jj, J.minutos, P.nombrePosicion FROM jugadores_Clausura2011 J, equipos E, posicion P WHERE (J.idEquipo = E.idEquipo) AND (E.idEquipo = 5) AND (J.minutos >0 ) AND (J.idPosicion = P.idPosicion) ORDER BY J.jj DESC, J.minutos DESC, J.nombre Ejecutar Left outer join produce el conjunto completo de registros de la tabla Equipos, con los registros coincidentes (si están disponibles) en la tablaJugadores. Si no hay coincidencia, el lado derecho contendrá NULL. Note que la integridad referencial de la tabla Jugadores, no permite que los deportistas no esten asignados a un Equipo. SELECT E.equipo, J.nombre, J.jj FROM equipos E
  • 68. LEFT OUTER JOIN jugadores_Clausura2011 J ON E.idEquipo = J.idEquipo ORDER BY E.equipo, J.nombre, J.jj Ejecutar SELECT E.equipo, J.nombre, J.jj FROM equipos E, jugadores_Clausura2011 J WHERE E.idEquipo = J.idEquipo(+) ORDER BY E.equipo, J.nombre, J.jj Para producir el conjunto de registros en la tabla Equipos, pero no en la tabla Participa, usamos la sentencia Left Outer Join, y luegoexcluimos los registros que no queremos del lado derecho mediante una cláusula where. El resultado de la consulta son todos aquellos equipos que no participan en el torneo Clasura 2012. SELECT * FROM equipos E, participa P WHERE E.idEquipo = P.idEquipo(+) AND P.idEquipo IS NULL SELECT E.Equipo FROM equipos E LEFT OUTER JOIN (SELECT idEquipo FROM participa WHERE idTorneo = 88) P ON E.idEquipo = P.idEquipo WHERE P.idEquipo IS NULL Ejecutar Para producir el conjunto de registros únicos de la tabla Departamento y la tabla Empleado, usamos el mismo Full Outer Join, y luego excluimos los registros que no queremos de los dos lados mediante una cláusula Where SELECT * FROM departamento d FULL OUTER JOIN empleado e ON d.idDepartamento = e.idDepartamento WHERE e.idDepartamento IS NULL OR d.idDepartamento IS NULL SELECT * FROM departamento d, empleado e
  • 69. WHERE d.idDepartamento = e.idDepartamento(+) AND (e.idDepartamento IS NULL OR d.idDepartamento IS NULL) Full outer join produce el conjunto de todos los registros en las tablas Departamento y Empleado, con registros coincidentes en ambos lados cuando sea posible. Si no hay coincidencia, el lado que falta contendrá null. SELECT * FROM departamento d FULL OUTER JOIN empleado e ON d.idDepartamento = e.idDepartamento http://www.prograweb.com.mx/tallerBD/index.html