UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLOGICOS ESCUELA DE COMPUTACION GUIA DE LABORATORIO # 4 CICLO: 01-2012 Nombre de la Practica: Continuación de Instrucciones Fundamentales de T-SQL, Creación y modificaciones de tablas. Lugar de ejecución: Centro de Computo Tiempo estimado: 2 horas con 30 minutos MATERIA: Base de Datos I I. OBJETIVOS ESPECIFICOS Qué el estudiante: Utilicen otras sentencias básicas de T-SQL Identifique las instrucciones que se utilizan para la creación y modificación de las tablas. II. INTRODUCCION TEORICA ¿Qué es Transact-SQL? Transact-SQL es un lenguaje que sirve para la definición, tratamiento y control de datos. Un script de Transact SQL es un conjunto de sentencias de Transact SQL en formato de texto plano que se ejecutan en un servidor de SQL Server. Un script está compuesto por uno o varios lotes. Un lote delimita el alcance de las variables y sentencias del script. Dentro de un mismo script se diferencian los diferentes lotes a través de la instrucción GO. En la guía anterior se hizo una introducción a algunas instrucciones fundamentales de T-SQL, ahora en esta guía terminaremos de examinar los elementos que pueden ir en una instrucción SELECT así como las instrucciones que nos ayudan a definir una estructura de una base de datos y las instrucciones para poder hacer modificaciones a los objetos de la base de datos. Pagina 1 de 23 OPERADORES QUE PODEMOS USAR CON LA CLAUSULA WHERE Pagina 2 de 23 CLAUSULA: ORDER BY En las consultas que hemos ejecutado hasta el momento, la mayoría han proporcionado el resultado en un orden alfabético. ¿Es por accidente? Probablemente le asombre, pero la respuesta es que sí. Si no indicamos que deseamos ordenar los resultados de una consulta de una forma específica, obtendremos los datos en el orden en el que decida proporcionarlos SQL Server, que siempre se basará, bien en el orden físico de una tabla, o bien en uno de los índices de SQL Server utilizados para buscar los datos. Piense en la cláusula ORDER BY como en una oportunidad para “ordenar elementos por”. Esta cláusula nos ofrece la oportunidad de definir el orden en que deseamos obtener los datos. Podemos utilizar cualquier combinación de columnas en nuestra cláusula ORDER BY, siempre que sean columnas (o derivaciones de columnas) que se encuentren en las tablas de la cláusula FROM. Ejemplo: SELECT IDProducto, NombreProducto, PrecioUnitario FROM Productos WHERE PrecioUnitario > $40 ORDER BY PrecioUnitario ASC Pagina 3 de 23 Los resultados de la consulta se pueden ordenar de varias maneras: Puede organizar filas en orden ascendente o descendente De forma predeterminada, SQL utiliza el orden por columnas para organizar las filas en orden ascendente. Por ejemplo, para organizar los títulos de libros por precio ascendente, sólo tiene que ordenar las filas por la columna price. El código SQL resultante puede presentar el siguiente aspecto: Use pubs Go SELECT * FROM titles ORDER BY price GO ¿Anote que observa? ____________________________ SELECT * FROM titles ORDER BY price DESC GO ¿Anote que observa? ___________________________ Puede ordenar por varias columnas Por ejemplo, puede crear un conjunto de resultados con una fila para cada autor, que se ordene primero por estado y, a continuación, por ciudad. El código SQL resultante puede presentar el siguiente aspecto: SELECT * FROM authors ORDER BY state, city Puede ordenar por columnas que no aparezcan en el conjunto de resultados Por ejemplo, puede crear un conjunto de resultados con los títulos más caros primero, aunque no aparezcan los precios. El código SQL resultante puede presentar el siguiente aspecto: SELECT title_id, title FROM titles ORDER BY price DESC CLAUSULA: GROUP BY Con ORDER BY, hemos desordenado un poco los pasos a seguir con relación a la explicación de la instrucción SELECT del principio de la Guía de laboratorio. Vamos a recordar la estructura global de la instrucción SELECT: SELECT <lista de columnas> [FROM <tabla(s) de origen >] [WHERE <condición restrictiva >] [GROUP BY <nombre de columna o expresión que utiliza una columna en la lista de selección>] [HAVING <condición restrictiva basadas en los resultados de GROUP BY>] [ORDER BY <listas de columna>] [ [FOR XML {RAW|AUTO|EXPLICIT|PATH [ (<elemento>) ] } Pagina 4 de 23 [, XMLDATA] [, ELEMENTS] [, BINARY base 64]] [OPTION (<sugerencia de consulta>, [,…n)] ¿Por qué hemos analizado antes ORDER BY que GROUP BY si la cláusula ORDER BY se escribe antes de GROUP BY dentro de la instrucción SELECT? Existen dos razones: 1. ORDER BY se utiliza con más frecuencia que GROUP BY, por lo que se pretende que usted practicara más con dicha instrucción. 2. Queríamos asegurarnos de que sabe que puede combinar y corresponder todas las cláusulas que se encuentran tras la cláusula FROM, siempre que las ordene en el orden esperado por SQL Server (tal como se define en la sintaxis). La cláusula GROUP BY se utiliza para agregar información. . Vamos a examinar una simple consulta sin GROUP BY. Supongamos que desea saber cuantos artículos se han pedido en un determinado conjunto de pedidos: Ejemplo SELECT OrderID, Quantity As [Sin nombre de columna] FROM [Order Details] WHERE OrderID BETWEEN 11000 AND 11002 Nota: Observe el uso de corchetes en esta consulta. Se debe de utilizar corchetes si el nombre de un objeto (en este caso una tabla) tiene espacios de por medio en él, tenemos que delimitar el nombre utilizando corchetes o comillas simples, lo que permite a SQL Server saber dónde empieza y dónde termina el nombre. Resultado de la consulta anterior es el siguiente: Pagina 5 de 23 Aunque se ha solicitado sólo tres pedidos, se viendo cada línea individual de detalle d el pedido. Podríamos utilizar una calculadora o podríamos utilizar la cláusula GROUP BY con un agregado (en este caso vamos a utilizar SUM ( ) ) para obtener el total deseado. SELECT OrderID, SUM (Quantity) As [Sin nombre de columna] FROM [Order Details] WHERE OrderID BETWEEN 11000 AND 11002 GROUP BY OrderID Así obtiene lo que se esta buscando: TIPS: Puedo agregarle un titulo a la columna sin nombre con AS Como es de suponer, la función SUM devuelve totales; ¿pero totales de qué? Si no hubiésemos suministrado la cláusula GROUP BY, la función SUM habría sumado todos los valores de todas las filas para la columna con nombre. Sin embargo, en este caso hemos suministrado una cláusula GROUP BY y, por tanto, el total proporcionado por la función SUM es el total de cada grupo. También podemos agrupar basándonos en múltiples columnas. Para ello, sólo tenemos que añadir una coma y el nombre de la siguiente columna. Funciones de agregado Las funciones de agregado realizan un un cálculo sobre un conjunto de valores y devuelven un solo valor. Con la excepción de COUNT, las funciones de agregado omiten los valores NULL. Las funciones de agregado se suelen utilizar con la cláusula GROUP BY de la instrucción SELECT. COUNT Devuelve el número de elementos de un grupo (conjunto de resultados ). SELECT COUNT(*)FROM Employees AVG Devuelve la media de los valores de un grupo. Los valores nulos se pasan por alto. a probar a ejecutar la misma consulta que ejecutamos anteriormente, pero ahora vamos a modificarla para que devuelva el promedio de la cantidad por pedido en lugar del total de cada pedido: Pagina 6 de 23 SELECT OrderID, AVG (Quantity) AS promedio FROM [Order Details] WHERE OrderID BETWEEN 11000 AND 11002 GROUP BY OrderID El resultado es: MAX / MIN MAX devuelve el valor máximo de la expresión o del valor de una columna y MIN lo contrario. SELECT OrderID, MIN(Quantity) AS promedio FROM [Order Details] WHERE OrderID BETWEEN 11000 AND 11002 GROUP BY OrderID NOTA: En realidad excepto COUNT (*). todas las funciones de agregado ignoran los valores NULL Agrupar condiciones con la cláusula HAVING Hasta el momento, hemos aplicado todas nuestras condiciones a filas específicas. Si una determinada columna en una fila no tiene un valor especifico o no se encuentra dentro de un rango de valores, se omitirá toda la fila, y todo ello antes de pensar siquiera en las agrupaciones. ¿Qué pasaría si deseáramos agrupar condiciones? Es decir, ¿Qué pasaría si deseáramos que todas las filas se agregasen a un grupo pero sólo cuando los grupos se hubiesen acumulado completamente estaríamos preparados para aplicar la condición? Bueno, aquí es donde entra en acción la cláusula HAVING. La cláusula HAVING sólo se utiliza si también existe una cláusula GROUP BY en la consulta. Mientras la cláusula WHERE se aplica a todas las filas antes incluso de tener la oportunidad de convertirse en parte de un grupo, la cláusula HAVING se aplica al valor agregado de dicho grupo. Ejemplo Primero vamos a realizar un ejemplo que no lleve la cláusula HAVING y después vamos a utilizar el mismo ejemplo, pero ahora con la cláusula HAVING. Sin HAVING SELECT OrderID, SUM(Quantity) AS TOTAL FROM [Order Details] GROUP BY OrderID El resultado es: Pagina 7 de 23 (830 filas afectadas) Lamentablemente, es bastante difícil analizar una lista tan larga. Por tanto, vamos a dejar que SQL Server reduzca est a lista para ayudarnos a realizar nuestro análisis. Supongamos que sólo estamos interesados en cantidades de pedidos más grandes. ¿Podemos modificar la consulta para que devuelva la misma información pero limitándose a los pedidos cuya cantidad total esté por encima de 300? La respuesta es sí, y es tan fácil como añadir la cláusula HAVING. Con HAVING SELECT OrderID, SUM(Quantity) AS TOTAL FROM [Order Details] GROUP BY OrderID HAVING SUM(Quantity) > 300 El resultado es: Como puede comprobar, podemos reducir rápidamente la lista hasta los elementos que nos interesan. Instrucciones para Crear y modificar bases de datos y tablas Antes de profundizar en las instrucciones reales que crean tablas y otros objetos, vamos a analizar el convenio para un nombre totalmente cualificado y, hasta cierto punto, la propiedad de los objetos. Pagina 8 de 23 Nombres de objetos en SQL Server En todas las consultas que hemos ejecutado hasta ahora hemos visto cómo funciona la denominación. Le hemos pedido que cambie la base de datos activa (Instrucción USE) en el Analizador de consultas antes de ejecutar cualquier consulta que nos ha ayudado a que funcionen nuestras consultas. ¿Cómo? Bueno, SQL Server se centra en un ámbito muy estrecho cuando intenta identificar y localizar los objetos que hemos denominado en nuestras consultas y en otras instrucciones. Por ejemplo, sólo hemos estado proporcionando los nombres de las tablas sin ninguna información adicional, pero en realidad existen cuatro niveles en los convenios de denominación para cualquier tabla SQL Server (y otros objetos de SQL Server). Un nombre totalmente calificado es como sigue: [Nombre-de-Servido. [Nombre-de-Base-de-Datos. [Nombre-de-Esquema.] ]] Nombre-de-Objeto Tenemos que proporcionar un nombre de objeto siempre que ejecutemos una operación sobre dicho objeto, pero todos los elementos del nombre que se encuentran a la izquierda del nombre del objeto son opcionales. De hecho la mayoría de las veces no son necesarios y, por consiguiente, podemos omitirlos. Aún así, antes de empezar a crear objetos, vamos a obtener un control sólido sobre cada elemento del nombre. Posteriormente llegaremos al nombre del objeto sólo. Nombre del ESQUEMA (También conocido como Propiedad) Si está utilizando esquemas (las bases de datos más antiguas no utilizan esquemas, pero parece que en el futuro serán más importantes), tendrá que indicar el esquema en el que se encuentra su objeto. Es posible tener dos objetos con el mismo nombre pero que residan en esquemas diferentes. Si desea acceder a un objeto que no se encuentra en el esquema predeterminado (establecido basándose en el inicio de sesión), tendrá que establecer específicamente el nombre del esquema de su objeto. Si va a utilizar opciones de esquema, se recomienda que utilice una combinada de dos partes (esquema y nombre de tabla) en todas sus consultas denominación ¿Qué es un Esquema y como funciona? En versiones anteriores a SQL Server 2005, la propiedad (tal como se conocía en su momento) era el reconocimiento, dentro del nombre totalmente calificado, de “quien” era el propietario del objeto. Normalmente era la persona que creaba el objeto o el propietario de la base de datos (conocido normalmente como dbo). En SQL Server 2005, las cosas funcionan de una manera similar, pero el objeto se asigna al esquema en lugar de a un propietario. Mientras un propietario se relaciona a un inicio de sesión particular, un esquema ahora se puede compartir entre múltiples inicios de sesión, y un inicio de sesión puede tener derechos para múltiples esquemas. De forma predeterminada, sólo los usuarios que son miembros de la función del sistema sysadmin o de las funciones de bases de datos db_owner o db_ddladmin, pueden crear objetos en una base de datos. Nota: las funciones que mencionamos aquí son sólo algunas de las muchas funciones del sistema y de base de datos disponibles en SQL Server 2005. las funciones tienen un conjunto lógico de permisos concedidos según cómo se tenga que utilizar la función. Al asignar una función determinada a alguien, le está proporcionando a dicha persona la capacidad de tener todos los permisos que tiene la función. Los usuarios individuales pueden tener privilegios para crear tipos de objetos de base de datos y del sistema. Si dichos individuos crean un objeto, de forma predeterminada, Pagina 9 de 23 dicho objeto se asignará a cualquier esquema que aparezca como predeterminado para ese inicio de sesión. TIPS: mantenga el acceso a CREATE limitado a las cuentas y a los miembros de las funciones de seguridad sysadmin o db_owner. No es recomendable permitirles a todos los usuarios permisos de CREATE. El Esquema predeterminado: dbo El usuario que crea la base de datos se considera el “Propietario de la base de datos” o “dbo”. Cualquier objeto creado dentro de dicha base de datos aparecerá listado con un esquema dbo en lugar de con su nombre de usuario individual. Por ejemplo, supongamos que soy usuario diario de una base de datos, mi nombre de inicio de sesión es EsquemaUDB y me han concedido privilegios para utilizar CREATE TABLE en una determinada base de datos. Si crease una tabla denominada tabla, el nombre del objeto calificado del propietario sería EsquemaUDB.MiTabla. Sin embargo, tenga en cuenta que como la tabla me tiene a mí como propietario específico; ningún otro usuario (recuerde que aquí soy EsquemaUDB) de EsquemaUDB.MiTabla tendría que proporcionar el nombre calificado del propietario para que SQL Server resolviese el nombre de la tabla. Ahora supongamos que existe otro usuario con un nombre de inicio de sesión de Administrador, el es el propietario de la base de datos (en lugar de sólo un miembro de db_owner). Si Administrador crea una tabla denominada MiTabla utilizando una instrucción CREATE idéntica a la utilizada por EsquemaUDB, el nombre de la tabla cualificado del propietario sería dbo.MiTabla. Asimismo, como dbo también es él propietario predeterminado, cualquier usuario sólo podrá hacer referencia a la tabla MiTabla. El nombre de la base de datos El siguiente elemento en el convenio de denominación totalmente calificada es el nombre de la base de datos. Algunas veces desearemos recuperar datos de una base de datos distinta a la predeterminada o a la actual. De hecho, puede que deseemos unir datos de distintas bases de datos con la cláusula JOIN (será vista en la guía 3 de laboratorio). Un nombre de base de datos calificado nos proporciona dicha capacidad. Por ejemplo, si se estuviese conectado a la base de datos AdventureWorks como base de datos actual y desease hacer referencia a la tabla Orders de la base de datos Northwind, podría hacerlo utilizando Northwind.dbo.Orders. Como dbo es el esquema predeterminado, también podría utilizar Northwind..Orders. Si un esquema denominado MiEsquema es propietario de una tabla denominada MiTabla en MiBasedeDatos, entonces podría hacer referencia a dicha tabla utilizando MiBasedeDatos.MiEsquema.MiTabla. Recuerde que la base de datos actual (tal como se determine con el comando USE o en el cuadro de lista desplegable de la consola de administración de SQL Server) es siempre la predeterminada, por lo que si desea sólo datos de la base de datos actual, no tendrá que incluir el nombre de la misma en el nombre totalmente calificado. Instrucción CREATE Vamos a examinar la estructura completa de la sentencia CREATE empezando con la más general. Descubrirá que las instrucciones CREATE empiezan de la misma forma y después dan paso a sus especificaciones. La primera parte de CREATE será siempre igual: CREATE <tipo de objeto> <nombre del objeto> A esta parte le seguirán los detalles, que variarán según la naturaleza del objeto que estemos creando. A continuación se presenta un listado de sintaxis más completa de CREATE: CREATE DATABASE Pagina 10 de 23 CREATE DATABASE <nombre de base de datos> [ON [PRIMARY] ([NAME = <nombre lógico del archivo>,] FILENAME = <‟nombre del archivo‟> [, SIZE = <tamaño en Kilobytes, megabytes, gigabytes, o terabytes>] [, MAXSIZE = <tamaño en Kilobytes, megabytes, gigabytes, o terabytes>] [, FILEGROWTH = <tamaño en Kilobytes, megabytes, gigabytes, o terabytes| porcentaje>] ) ] [LOG ON ([NAME = <nombre lógico del archivo>,] FILENAME = <‟nombre del archivo‟> [, SIZE = <tamaño en Kilobytes, megabytes, gigabytes, o terabytes>] [, MAXSIZE = <tamaño en Kilobytes, megabytes, gigabytes, o terabytes>] [, FILEGROWTH = <tamaño en Kilobytes, megabytes, gigabytes, o terabytes| porcentaje>] ) ] [ COLLATE <nombre de intercalación> ] [FOR ATTACH [WITH <agente de servicio>] | FOR ATTACH_REBUILD_LOG | WITH DB_CHAINING ON | OFF | TRUSTWORTHY ON | OFF] [AS SNAPSHOT OF <nombre de base de datos de origen> [;] Tenga en cuenta que algunas de las opciones anteriores son mutuamente excluyentes (por ejemplo, si está creando para anexar, la mayoría de las opciones que no sean ubicaciones de archivo no serán válidas). En esta sintaxis ha y mucho que explicar, por lo que vamos a desglosarla en sus elementos. ON ON se utiliza en dos sitios para definir la ubicación del archivo donde se almacenan los datos (Archivo .MDF) y para definir la misma información para el lugar donde se guarda el registro (Log de transacciones, archivo .LDF). Advertirá aquí la inclusión de la palabra clave PRIMARY, que indica que lo que sigue es un grupo de archivos primarios (o principales) en el que se guardan físicamente los datos. También podemos guardar datos en los denominados grupos de archivos secundarios. NAME Éste es el nombre del archivo que estamos definiendo, pero sólo es un nombre lógico, es decir, el nombre que va a utilizar SQL Server internamente para hacer referencia a dicho archivo. FILENAME Éste es el nombre físico del disco del archivo del sistema operativo real en el que se van a guardar los datos y el registro (Log de transacciones). El valor predeterminado dependerá de si estamos tratando con la propia base de datos o con el Log de transacciones. De forma predeterminada, el archivo se ubicará en el siguiente subdirectorio \ Data dentro del directorio C:\ Archivos de programa \ Microsoft SQLServer \ MSSQL.1 \ MSSQL (o el directorio que ha ya establecido como principal para SQL Server en la instalación). Si estuviésemos utilizando el archivo de base de datos físico, se denominaría igual que nuestra base de datos con una extensión .mdf y si estuviésemos utilizando el registro, tendría el mismo nombre que el archivo de base de datos, pero con un sufijo _log y una extensión .ldf. SIZE Pagina 11 de 23 Aquí no hay ningún misterio: es el tamaño de la base de datos. De forma predeterminada, el tamaño se proporciona en megabytes, pero también podemos hacer que se proporcione en kilobytes utilizando KB en lugar de MB tras el valor numérico del tamaño; también podemos usar un tamaño mucho mayor con GB (gigabytes) o incluso TB (terabytes). Tenga en cuenta que este valor debe ser, al menos, tan alto como el de la base de datos model y debe ser un número entero (sin decimales); en caso contrario recibiremos un error. Si no suministramos un valor para SIZE, la base de datos tendrá inicialmente el mismo tamaño que el de la base de datos model. MAXSIZE Este parámetro es una pequeña variante del parámetro SIZE. SQL Server tiene un mecanismo que permite a nuestra base de datos asignar automáticamente un espacio en disco adicional (para crecer) cuando sea necesario. MAXSIZE es el tamaño máximo al que puede crecer la base de datos. Una vez más, de forma predeterminada se proporciona en megabytes, como SIZE, podemos utilizar KB, GB o TB para emplear cantidades de incremento diferentes. La pequeña variante es que no existe un valor predeterminado firme. Si nuestra base de datos (el archivo .mdf) llega al valor establecido en el parámetro MAXSIZE, nuestros usuarios empezarán a recibir errores indicando que sus inserciones no se pueden ejecutar. Si nuestro registro (Log de transacciones .ldf) llega a su tamaño máximo, no podremos ejecutar ninguna actividad de inicio de sesión en la base de datos. FILEGROWTH Mientras SIZE establece el tamaño inicial de la base de datos y MAXSIZE determina exactamente el tamaño máximo que puede llegar a tener el archivo de la base de datos, FILEGROWTH determina básicamente el incremento del crecimiento con que se puede llegar a dicho máximo. Para ello, proporcionamos un valor indicando por cuantos bytes (en KB, MB, GB, o TB) a la vez deseamos aumentar el archivo. Por ejemplo, si establecemos un archivo de base de datos para que cuando llegue a 1GB incremente en un valor FILEGROWTH de un 20%, la primera vez que se expanda, aumentará has a 1.2GB, la segunda vez hasta 1.44GB y así sucesivamente. LOG ON La opción LOG ON nos permite establecer que deseamos que nuestro registro (Log de transacciones) se dirija a un conjunto específico de archivos y dónde se deben ubicar exactamente dichos archivos. Si no proporcionamos esta opción, SQL Server creará el registro (Log de transacciones) en un solo archivo y lo predeterminará para que tenga un tamaño igual al 25% del tamaño del archivo de datos. TIPS: es muy recomendable que guarde sus archivos de registro ( .ldf) en una unidad de disco diferente a la de sus archivos de datos principales (.mdf). Al hacerlo, evitará que los archivos de datos principal y de registro compitan por la E/S del disco además de proporcionar una seguridad adicional si falla una unidad. COLLATE Esta opción tiene que ver con el problema de la ordenación, las mayúsculas y minúsculas y los acentos. Al instalar su SQL Server, habrá decidido sobre cuál es la intercalación predeterminada, pero puede sobrescribir este parámetro a nivel de base de datos y a nivel de columna. FOR ATTACH Podemos utilizar esta opción para agregar un conjunto de archivos de base de datos existente en el servidor actual. Los archivos en cuestión tienen que formar parte de una base de datos que, en algún momento, se haya separado correctamente utilizando sp_detach_db. Pagina 12 de 23 WITH DB CHAINING ON | OFF Este es un tema difícil para un principiante, así que será visto en una asignatura superior. TRUSTWORTHY Este modificador es nuevo y añade una capa de seguridad adicional alrededor del acceso a los recursos y archivos del sistema fuera del contexto de SQL Server. Por ejemplo, podemos ejecutar un montaje .NET que toque archivos que se encuentran en nuestra red; en este caso, tenemos que identificar la base de datos que forma parte del montaje como si fuese de total confianza. De forma predeterminada, este modificador está desactivado; asegúrese de saber exactamente lo que está haciendo antes de activarlo. III. REQUERIMIENTOS O MATERIAL Y EQUIPO Nº 1 2 Cantidad 1 1 Descripción Guía de Laboratorio #3 de BD Memoria USB IV. PROCEDIMIENTO CREACION DE UNA BASE DE DATOS 1. Crear una carpeta con su número de carnet 2. En este momento ya estamos preparados para crear nuestra base de datos. A continuación vamos a crear una base de datos denominada Conta_NumeroCarne que también utilizaremos cuando empecemos a crear tablas. CREATE DATABASE Conta_NumeroCarne ON ( NAME = 'Conta_NumeroCarne', FILENAME = 'C:\Archivos de programa\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Conta_NumeroCarneData.mdf', SIZE = 10, MAXSIZE = 50, FILEGROWTH = 5 ) LOG ON ( NAME = 'Conta_NumeroCarnelog', FILENAME = 'C:\Archivos de programa\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Conta_NumeroCarneLog.ldf', SIZE = 5MB, MAXSIZE = 25MB, FILEGROWTH = 5MB ) GO 3. Ahora ya es un buen momento para conocer algunas utilidades de información disponibles en SQL Server. Vamos a ejecutar un comando denominado sp_helpdb. Este comando está hecho a la medida para la información de la estructura de una base de datos y normalmente proporciona mejor información si estamos interesados en la propia Pagina 13 de 23 base de datos que en los objetos que contiene. El comando sp_helpdb acepta un parámetro: “el nombre de la base de datos”. EXEC sp_helpdb Conta_NumeroCarne Este comando nos devuelve dos conjuntos de resultados independientes. El primero se basa en la información combinada (datos y registro) de nuestra base de datos y el segundo conjunto de resultados son especificaciones sobre los diversos archivos que forman nuestra base de datos (incluidos su tamaño actual y sus parámetros de crecimiento). Ahora bien, tras crear las tablas e insertar datos, la base de datos empezará a crecer automáticamente a medida que se necesite y los resultados obtenidos por el comando anterior se irán modificando con la adición de tablas y datos. CREATE TABLE Vamos a examinar la sintaxis más ampliada: CREATE TABLE [nombre_de_base_de_datos. [Esquema]. ] nombre_de_tabla ( <nombre_de_columna> <tipo_de_datos> [[DEFAULT <expresión_constante>] | [IDENTITY [ (inicialización, incremento) [NOT FOR REPLICATION] ] ] ] [ROWGUIDCOL] [COLLATE <nombre de intercalación>] [NULL | NOT NULL] [<restricciones de columnas>] | [nombre de columna AS expresión_de_columna_calculada] | [<restricción_de_tabla>] [,…n] ) [ON {<grupo de archivos> | DEFAULT} ] [TEXTIMAGE_ON {<grupo_de_archivos> | DEFAULT} ] Es una sintaxis muy útil y tiene más secciones que se han omitido por brevedad. Ahora vamos a analizar las cláusulas más importantes: Nombres de tablas y columnas Existen muchos “estándares” diferentes para la denominación de los objetos de una base de datos, particularmente para las tablas y las columnas. Nuestras reglas en concreto son muy simples: Escriba en mayúsculas la primera letra de cada palabra y utilice letras minúsculas en el resto. Utilice nombre cortos, pero lo suficientemente largos como para ser descriptivos. Cuando hay dos palabras en un nombre, no utilice ningún separador (escriba ambas palabras juntas): utilice el hecho de escribir en mayúsculas la primera letra de cada palabra para imaginar cómo puede dividir las palabras. Tipos de datos Aquí no hay mucho que decir: los tipos de datos los hemos descrito en la guía anterior. Sólo tendrá que proporcionar inmediatamente un tipo de datos tras el nombre de la columna: no existe ningún tipo de datos predeterminado. Pagina 14 de 23 DEFAULT Es el valor que tendrá que utilizar para cualquier fila insertada sin un valor suministrado por el usuario para esta columna en concreto. El valor predeterminado, si lo utiliza, debe seguir inmediatamente al tipo de datos. IDENTITY El concepto de valor de identidad es muy importante en el diseño de una base de datos. ¿Qué es una columna de identidad? Bueno, cuando creamos una columna de identidad, SQL Server asigna automáticamente un número de serie a esta columna en cada fila que insertemos. El número desde el que empieza a contar SQL Server se denomina valor de inicialización y la cantidad en que aumenta o disminuye el valor por cada fila se denomina incremento. El valor predeterminado para un valor de inicialización es 1 y el valor de incremento también es uno y la mayoría de diseños piden que se dejen como están. Una columna de identidad tiene que ser numérica y, en la práctica, casi siempre se implanta con un tipo de datos entero o bigint (tipos de datos numéricos exactos que utilizan datos enteros). NOT FOR REPLICATION Este parámetro determina si se ha asignado un nuevo valor de identidad para la nueva base de datos cuando se ha publicado la columna en otra base de datos o si conserva su valor existente (vía REPLICA). Nota: Brevemente, la réplica es el proceso que realiza automáticamente lo que, en un sentido muy amplio, equivale a copiar parte o toda la información de nuestra base de datos en otra base de datos. La otra base de datos puede estar en la misma máquina física que la original o puede encontrarse ubicada en un sitio remoto. ROWGUIDCOL Esta es también una réplica relacionada y, muchas veces, tiene el mismo propósito para una columna de identidad, pero se diferencia en que ROWGUIDCOL nos ayuda a mantener la identidad en entornos distribuidos. COLLATE Este parámetro funciona igual que el comando CREATE DATABASE, estando su diferencia principal en el ámbito (aquí definimos a nivel de columna en lugar de a nivel de base de datos). NULL / NOT NULL Este parámetro es muy sencillo: establece si la columna en cuestión acepta o no valores NULL. El valor predeterminado, cuando instalamos SQL Server por primera vez, es establecer una columna en NOT NULL si no especificamos la aceptación de valores NULL. Restricciones de columnas Se trata de restricciones y reglas que incluimos en columnas individuales sobre los datos que se pueden insertar en dichas columnas. Columnas calculadas También podemos crear columnas que no tengan datos por sí mismas sino que su valor derive instantáneamente de otras columnas de la tabla. Si piensa en ello, parece algo extraño ya que simplemente podríamos calcular dichos valores en el momento de la consulta, pero realmente es de gran ayuda para muchas aplicaciones. Pagina 15 de 23 Restricciones de tabla Las restricciones de tabla son muy similares a las de columna ya que incluyen restricciones en los datos que se pueden insertar en la tabla. Su pequeña diferencia reside en que se pueden basar en más de una columna. La siguiente guía de laboratorio, analizaremos con más detalle estas restricciones; pero los ejemplos de restricciones a nivel de tabla incluyen las restricciones PRIMARY KEY y FOREIGN KEY así como las restricciones CHECK. ON ¿Recuerda cuando hablábamos de la creación de una base de datos y decíamos que podíamos crear distintos grupos de archivos? Pues bien, la cláusula ON en una definición de tabla es la forma de establecer específicamente en qué grupo de archivos (y, por consiguiente, físicos (discos duros o servidores) ) deseamos que se ubique la tabla o podemos simplemente omitir la cláusula ON para colocar la tabla en cualquier sitio en el que se encuentre el grupo de archivos predeterminado (que será PRIMARY a no ser que establezcamos algo diferente). TEXTIMAGE_ON Esta cláusula es básicamente igual a ON pero nos permite mover una parte muy específica de la tabla a un grupo de archivos diferente. Esta cláusula sólo es válida si nuestra definición de tabla incluye una columna (o columnas) text, ntext o image. Cree las siguientes tablas en base de datos que acaba de crear: Pagina 16 de 23 ALTER DATABASE Vamos a examinar directamente un cambio en nuestra base de datos. En realidad realizaremos sólo algunos cambios para comprobar los efectos de los distintos elementos y cómo varía su sintaxis. Quizá lo más complicado de la instrucción ALTER sea recordar lo que realmente tenemos. Teniéndolo en cuenta, vamos a examinar de nuevo lo que ya hemos creado: EXEC sp_helpdb Conta_NumeroCarne Los resultados obtenidos deben ser los mismos que cuando creamos la base de datos. Ahora bien, supongamos que deseamos cambiar un poco las cosas. Por ejemplo, vamos a realizar un cambio en el tamaño de la base de datos, aumentando su tamaño a 20MB. ALTER DATABASE Conta_NumeroCarne MODIFY FILE (NAME = Conta_NumeroCarne, SIZE = 20MB) Observe que, al contrario que cuando creamos nuestra base de datos, no obtenemos ninguna información sobre la asignación del espacio; en su lugar obtenemos un mensaje poco detallado: Comandos completados correctamente Pero esto, es muy poca información. Así que es mejor que comprobemos las cosas por nuestra cuenta: EXEC sp_helpdb Conta_NumeroCarne ALTER TABLE La necesidad más común es cuando tenemos que cambiar la estructura de nuestra tabla, que puede varias desde cosas sencillas, como añadir una nueva columna, hasta temas más complejos, como cambiar un tipo de datos. Por tanto, vamos a empezar con un ejemplo de uso de este código volviendo a nuestra tabla Empleados de la base de datos Conta_NumeroCarne ; para ello, analizaremos la estructura de la tabla Empleados por medio del comando SP_HELP. EXEC sp_help Empleados Pagina 17 de 23 Ahora que hemos recordado como cuales son los campos que posee la tabla empleados, vamos a proceder a agregar una nueva columna a dicha tabla: ALTER TABLE Empleados ADD EmpleoAnterior varchar(30) NULL Como podemos ver, no es “cosa del otro mundo”. De hecho, podemos añadir varias columnas a la vez. Por ejemplo, ahora queremos guardar en la tabla la fecha de cumpleaños del empleado y su color favorito. ALTER TABLE Empleados ADD FechaCumpleaños datetime NOT NULL, ColorFavorito char(8) NOT NULL DEFAULT 'AZUL' Observe que hemos incluido DEAFULT (predeterminado). Este valor es de gran utilidad cuando por ejemplo un usuario no introduce un valor en un campo de un formulario de inscripción y entonces tenemos que agregarle un valor por DEFAULT para que el campo no quede vacío. RECUPERANDO DATOS CON UNA CONDICIÓN A continuación hay que poner en uso la base de datos Northwind que utilizaremos como ejemplo para aprender a recuperar datos. Escriba el siguiente comando use Northwind seleccione la consulta y presione F5 para ejecutar la sentencia, recibirá un mensaje de : “command(s) completed successfully” Utilizaremos la tabla Customers para seleccionar los clientes que procedan de la ciudad de Madrid. Para ello ejecutaremos la siguiente consulta: select * from customers where City='Madrid' Cuando necesitemos seleccionar filas que cumplan con cierto patrón, utilizaremos el operador % sirve para especificar que el patrón a buscar puede contener cualquier cadena de caracteres de caracteres en la posición que se ha colocado. _ Especifica que en la posición que se ha colocado puede haber cualquier carácter. Si queremos seleccionar los clientes cuyo ContactName empiece con „Ant‟, la consulta sería la siguiente: select * from customers where ContactName like 'Ant%' Like, este operador cuenta con 2 caracteres auxiliares % y _ Si queremos verificar seleccionar los clientes cuyo CompanyName empieza con cualquier carácter, luego el segundo carácter es la letra „n‟, la consulta sería la siguiente: select * from customers where CompanyName like '_n%' Pagina 18 de 23 Utilizaremos la tabla products para el siguiente ejemplo. Si deseamos seleccionar las filas cuya UnitsInStock sea mayor a cero, la consulta sería la siguiente. select * from Products where UnitsInStock >0 Si deseamos filtrar las filas por el valor de más de un campo se utilizan los operadores lógicos. Si se quiere listar todas las filas de la tabla Products en las que el campo UnitPrice sea menor que 12 y UnitsInStock sea mayor que 10. La consulta sería: select * from Products where UnitsInStock >10 and UnitPrice<12 Note que se utiliza el operador AND pues se quiere verificar que las dos condiciones se cumplan. Cuando tengamos un rango de valores para compara se puede utilizar el operador Between. Por ejemplo si quisiéramos seleccionar las órdenes de compra que se han realizado entre 01/01/1996 al 31/07/1996. La consulta sería la siguiente: select * from orders where OrderDate between '01/01/1996' and '07/31/1996' order by OrderDate Cuando tengamos una lista de valores para comparar un campo se utiliza el operador in, por ejemplo si queremos listas los empleados con los códigos: BONAP, AROUT, BOLID y FISSA. La consulta sería: select * from Customers where CustomerID in ('BONAP', 'AROUT', 'BOLID', 'FISSA') También podemos utilizar el operador in para verificar si el valor de un campo se encuentra en otra tabla. Por ejemplo si quisiéramos listar todos los productos que se encuentre en la tabla Order Details. La consulta sería la siguiente: select * from Products where ProductID in (select ProductID from [Order Details]) USO DE RESTRICCIONES Inicie una nueva ventana de consulta y cree una base de datos llamada “Administración#carne”. Antes de generar consultas en su base de datos, cree las tablas que se muestran a continuación: Tablas de trabajo Tabla: alumno La definición de esta tabla, contiene los siguientes ‘constraints’ o restricciones que buscan verificar tres cosas principalmente: El formato del carnet debe ser 2 caracteres no numéricos al inicio y 6 caracteres numéricos al final. Pagina 19 de 23 Las dos primeras letras del carnet deben ser la combinación de las primeras dos iniciales del primer y segundo apellido respectivamente y en caso de que el segundo apellido se desconozca (tenga un valor NULL), se utilizará la primera inicial del primer apellido nuevamente. El sexo de una persona debe de ser de un carácter, M=masculino o F=femenino. create table alumno ( carnet char(8) not null, nombre1 char(15) not null, nombre2 char(15) null, apellido1 char(15) not null, apellido2 char(15) null, sexo char(1) not null, constraint pk_carnet primary key clustered (carnet), constraint ck_carnet check ( carnet like '[A-Z][A-Z][0-9][0-9][0-9][0-9][0-9][0-9]' and substring(carnet,1,2)= left(apellido1,1) + left(isnull(apellido2,apellido1),1) ), constraint ck_sexo check (sexo like '[MF]') ) Las funciones utilizadas en los “constraints” se definen a continuación: SUBSTRING Devuelve parte de una expresión de caracteres, binaria, de texto o de imagen. Sintaxis: SUBSTRING (expression, start, length) Donde: Expresión: Es una cadena de caracteres, cadena binaria, texto, imagen, columna o expresión que incluye una columna. No deben usarse expresiones que incluyan funciones de agregado. Start : Es un entero que especifica el punto en que comienza la subcadena.length Es un entero que especifica la longitud de la subcadena (el número de caracteres o bytes que se devuelven). LEFT Devuelve la parte de una cadena de caracteres que comienza en un número de caracteres especificado a partir de la izquierda. Sintaxis: LEFT (character_expression, integer_expression) Donde: character_expression Es una expresión de caracteres o de datos binarios. character_expression puede ser una constante, una variable o una columna, y debe tener un tipo de datos que se pueda convertir implícitamente a varchar. integer_expression Es un número entero positivo. Si integer_expression es negativo, se devuelve una cadena NULL. ISNULL Reemplaza NULL con el valor de reemplazo especificado. Pagina 20 de 23 Sintaxis: ISNULL (check_expression, replacement_value ) Donde: check_expression Es la expresión donde se va a comprobar la existencia de NULL; check_expression puede ser de cualquier tipo de datos. replacement_value Es la expresión que se va a devolver si check_expression es NULL; replacement_value debe tener el mismo tipo de datos que check_expresssion. Ingrese los siguientes datos a la tabla: insert into alumno values (upper('mb960240'),'Juan',null,'Martínez','Blanco','m') insert into alumno values (upper('om960201'),'Ethel',null,'Osegueda','Martínez','f') insert into alumno values (upper('mm960213'),'Oscar',null,'Melara',null,'m') insert into alumno values (upper('mm960217'),'Karen','María','Melara','Morán','f') Tabla: grupo create table grupo ( id_grupo char(4) not null, descripcion char(60) not null, constraint pk_id_grupo primary key clustered (id_grupo) ) Ingrese los siguientes datos: insert into grupo values ('BDD1','Grupo 01, Base de datos') insert into grupo values ('BDD2','Grupo 02, Base de datos') insert into grupo values ('BDD3','Grupo 03, Base de datos') Tabla: evaluacion Contiene todas las evaluaciones posibles que se le pueden hacer al estudiante; de esta forma el número de las evaluaciones se maneja de forma lógica y no de forma física como lo sería el crear una tabla donde cada campo correspondería a una evaluación. create table evaluacion ( id_evaluacion int not null, descripcion char(60) not null, constraint pk_id_evaluacion primary key clustered (id_evaluacion) ) Ingrese los siguientes datos: insert into evaluacion values (1, 'Parcial práctico 1') insert into evaluacion values (2, 'Parcial práctico 2') insert into evaluacion values (3, 'Parcial práctico 3') Pagina 21 de 23 Tabla: inscripcion Contiene los datos de donde se encuentra inscrito cada alumno, en que grupo de laboratorio. create table inscripcion ( id_grupo char(4) not null, carnet char(8) not null, constraint pk_inscripcion primary key nonclustered (id_grupo,carnet), constraint fk_id_grupo foreign key (id_grupo) references grupo(id_grupo), constraint fk_carnet foreign key (carnet) references alumno(carnet) ) Ingrese los siguientes datos: insert insert insert insert into into into into inscripcion inscripcion inscripcion inscripcion values values values values ('BDD1',upper('mb960240')) ('BDD2',upper('mm960213')) ('BDD3',upper('mm960217')) ('BDD1',upper('om960201')) Tabla: nota Contiene el detalle de las notas de cada alumno obtenidas en las respectivas evaluaciones, observe que existe una foreign key relacionada con la tabla inscripción lo que obliga a que un estudiante tenga una nota solo si está inscrito. create table nota ( id_grupo char(4) not null, carnet char(8) not null, id_evaluacion int not null, nota decimal null, constraint fk_nota foreign key (id_grupo,carnet) references inscripcion(id_grupo,carnet), constraint u_nota unique (id_grupo,carnet,id_evaluacion), constraint fk_id_evaluacion foreign key (id_evaluacion) references evaluacion(id_evaluacion) ) Ingrese los siguientes datos: -- las insert insert insert notas del into nota into nota into nota alumno values values values carnet mb960240 ('BDD1',upper('mb960240'),1,5) ('BDD1',upper('mb960240'),2,6) ('BDD1',upper('mb960240'),3,4) -- las insert insert insert notas del into nota into nota into nota alumno values values values carnet om960201 ('BDD1',upper('om960201'),1,10) ('BDD1',upper('om960201'),2,9.5) ('BDD1',upper('om960201'),3,9) -- las notas del alumno carnet mm960213 insert into nota values ('BDD2',upper('mm960213'),1,7) insert into nota values ('BDD2',upper('mm960213'),2,9) Pagina 22 de 23 insert into nota values ('BDD2',upper('mm960213'),3,null) -- las insert insert insert notas del into nota into nota into nota alumno values values values carnet mm960217 ('BDD3',upper('mm960217'),1,9) ('BDD3',upper('mm960217'),2,5) ('BDD3',upper('mm960217'),2,6) V. EJERCICIO COMPLEMENTARIO Utilizando la base de datos Administración#carne A continuación deberá realizar diferentes consultas utilizando la sentencia SELECT: 1. Se desea un listado de todos los datos de cada una de las tablas 2. Se desea un listado de los alumnos inscritos ordenados ascendentemente por el código del grupo. 3. Mostrar un listado de todos los alumnos en donde su primer nombre empiece con la letra k 4. Mostrar un listado de todos las notas que se encuentren entre 6 y 10 5. Mostrar un listado de las notas de los alumnos que tienen el carnet mb960240 y el carnet mm960217 V. ANALISIS DE RESULTADOS Base de datos a utilizar: Northwind 1. Crear las consulta con la sentencia select que cumpla con los siguientes condiciones de búsqueda: a) Liste todos los productos cuya categoría es „Beverages‟ b) Liste todos los empleados cuyo nombre empiece con „a‟ el apellido contenga una „a‟ c) Liste todos los detalles de orden cuya cantidad este entre 5 y 25. d) Muestre todas las ordenes de los cliente de México e) Muestre todas las ordenes que han realizado los empleados cuyo país de procedencia es USA y el campo HireDate está entre 01/01/1992 al 30/06/1992 2. Investigue las funciones de fecha y string que se pueden utilizar en SQL Server 2008 y cite 3 ejemplos de cada uno. VI. BIBLIOGRAFIA Microsoft SQL Server 2008, Guía Práctica, Francisco Charte Ojeda; Anaya Multimedia. Pagina 23 de 23