Breve Introducción al SQL
|
|
|
- Ángeles Belmonte Ortega
- hace 9 años
- Vistas:
Transcripción
1 Breve Introducción al SQL 1. Introducción 1.1 Componentes del SQL 1.2 Comandos 1.3 Cláusulas 1.4 Operadores Lógicos 1.5 Operadores de Comparación 1.6 Funciones de Agregado 2. Consultas de Selección 2.1 Consultas Básicas 2.2 Ordenar los Registros 2.3 Consultas con Predicado 2.4 Alias 2.5 Bases de Datos Externas 3. Criterios de Selección 3.1 Operadores Lógicos 3.2 Intervalos de Valores 3.3 El Operrador Like 3.4 El Operador In 3.5 La cláusula WHERE 4. Agrupamiento de Registros y Funciones Agregadas 4.1 El cláusula GROUP BY 4.2 AVG (Media Aritmética) 4.3 Count (Contar Registros) 4.4 Max y Min (Valores Máximos y Mínimos) 4.5 StDev y StDevP (Desviación Estándar) 4.6 Sum (Sumar Valores) 4.7 Var y VarP (Varianza) 5. Consultas de Actualización 5.1 Consultas de Eliminación 5.2 Consultas de Datos Añadidos 5.3 Consultas de Actualización 6. Tipos de Datos 7. SubConsultas 8. Consultas de Referencias Cruzadas 9. Consultas de Unión Internas
2 10. Consultas de Unión Externas 11. Estructuras de las Tablas 11.1 Creación de Tablas 11.2 La cláusula CONSTRAINT 11.3 Creación de Indices 11.4 Eliminar y Añadir Campos e Indices 12. Consultas con Parámetros 13. Acceso a Bases de Datos Externas 14. Omitir los Permisos de Ejecución 15. La cláusula Procedure 16. Anexos 16.1 Resolución de Problemas Información Duplicada Registros no Relacionados 16.2 Utilizar SQL desde Visual Basic 16.3 Funciones utilizables 16.4 La función iif 16.5 Manual de Estilo
3 Breve Historia del SQL La historia de SQL (que se pronuncia deletreando en inglés las letras que lo componen, es decir "esecu-ele" y no "siquel" como se oye a menudo) empieza en 1974 con la definición, por parte de Donald Chamberlin y de otras personas que trabajaban en los laboratorios de investigación de IBM, de un lenguaje para la especificación de las características de las bases de datos que adoptaban el modelo relacional. Este lenguaje se llamaba SEQUEL (Structured English Query Language) y se implementó en un prototipo llamado SEQUEL-XRM entre 1974 y Las experimentaciones con ese prototipo condujeron, entre 1976 y 1977, a una revisión del lenguaje (SEQUEL/2), que a partir de ese momento cambió de nombre por motivos legales, convirtiéndose en SQL. El prototipo (System R), basado en este lenguaje, se adoptó y utilizó internamente en IBM y lo adoptaron algunos de sus clientes elegidos. Gracias al éxito de este sistema, que no estaba todavía comercializado, tmabién otras compañías empezaron a desarrollar sus productos relacionales basados en SQL. A partir de 1981, IBM comenzó a entregar sus productos relacionales y en 1983 empezó a vender DB2. En el curso de los años ochenta, numerosas compañías (por ejemplo Oracle y Sybase, sólo por citar algunos) comercializaron productos basados en SQL, que se convierte en el Estándar industrial de hecho por lo que respecta a las bases de datos relacionales. En 1986, el ANSI adoptó SQL (sustancialmente adoptó el dialecto SQL de IBM) como Estándar para los lenguajes relacionales y en 1987 se transfomó en Estándar ISO. Esta versión del Estándar va con el nombre de SQL/86. En los años siguientes, éste ha sufrido diversas revisiones que han conducido primero a la versión SQL/89 y, posteriormente, a la actual SQL/92. El hecho de tener un Estándar definido por un lenguaje para bases de datos relacionales abre potencialmente el camino a la intercomunicabilidad entre todos los productos que se basan en él. Desde el punto de vista práctico, por desgracia las cosas fueron de otro modo. Efectivamente, en general cada productor adopta e implementa en la propia base de datos sólo el corazón del lenguaje SQL (el así llamado Entry level o al máximo el Intermediate level), extendiéndolo de manera individual según la propia visión que cada cual tenga del mundo de las bases de datos. Actualmente, está en marcha un proceso de revisión del lenguaje por parte de los comités ANSI e ISO, que debería terminar en la definición de lo que en este momento se conoce como SQL3. Las características principales de esta nueva encarnación de SQL deberían ser su transformación en un lenguaje stand-alone (mientras ahora se usa como lenguaje hospedado en otros lenguajes) y la introducción de nuevos tipos de datos más complejos que permitan, por ejemplo, el tratamiento de datos multimediales.
4 INTRODUCCIÓN Cuenta de administrador "postgres" La cuenta de administrador es la más importante de su sistema y se merece una atención especial para evitarnos problemas de seguridad. Un fallo en la configuración de la misma pone la integridad de nuestro sistema en peligro. Por defecto PostgreSQL instala una cuenta de administrador llamada 'postgres'. La información de esta cuenta y lo que puede hacer se puede acceder en los catálogos de sistema, pg_authid, pg_roles, pg_shadow y pg_users. Más información sobre estos catálogos se encuentra disponible en el Capítulo 44. System Catalogs de la documentación oficial. Por defecto, después de instalar postgresql, la cuenta "postgres" no tiene definida ninguna clave de acceso y cualquier usuario que tenga acceso a la máquina que este ejecutando PostgreSQL, podrá acceder a todas las bases de datos como usuario "postgres" via sockets. Esto lo comprueba viendo la información definida en pg_shadow y en pg_hba.conf (Más información sobre pg_hba.conf y postgresql.conf en Configuración básica de PostgreSQL) [postgres@server]~$ psql Welcome to psql 8.3.7, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit postgres=# SELECT * from pg_shadow; usename usesysid usecreatedb usesuper usecatupd passwd valuntil useconfig postgres 10 t t t (1 rows) postgres=# \q [postgres@server]~$ grep postgres /var/pgsql/data/pg_hba.conf local all postgres trust Esta configuración por defecto puede ser un gran problema de seguridad en una máquina en la que muchos usuarios tengan acceso y se tengan bases de datos en producción o con datos confidenciales. Cualquier usuario con acceso a la máquina en cuestión podría acceder a PostgreSQL como usuario "postgres" y tener privilegios de administrador para hacer lo que quiera con las bases de datos: usuario@server:~$ psql -U postgres Welcome to psql 8.3.7, the PostgreSQL interactive terminal.
5 Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit Existen diferentes maneras de asegurar nuestra cuenta de administrador en PostgreSQL y nuestras bases de datos. A continuación, se presenta una manera de hacerlo que según experiencia es una de las mejores y más seguras. Implementaremos las siguientes medidas: 1. Tener una cuenta de sistema (postgres) en el sistema operativo sin clave definida. Habrá que ser root y utilizar su - postgres para convertirse en el usuario "postgres". No será posible acceder directamente al sistema como "postgres" via tcp/ip 2. El acceso mediante sockets será usado solamente por la cuenta de administrador "postgres". El resto de usuarios utilizarán el protocolo tcp/ip. 3. Cambiar los permisos del socket utilizado por PostgreSQL 4. Utilizar el método de autentificación 'ident' para la cuenta "postgres" en nuestro gestor de base de datos. De esta manera solamente el usuario postgres del sistema operativo podrá acceder a PostgreSQL como el usuario "postgres" de la base de datos Para implementar estas medidas tendremos que cambiar la configuración por defecto siguiendo estos pasos: 1. Para convertir la cuenta postgres del sistema operativo en una cuenta sin clave definida ejecutar como root: passwd -d postgres 2. Comprobar que no tiene una definición en pg_hba.conf para usuarios normales usando sockets (local) en el tipo de conexión. Si tiene usuarios usando sockets, cambiar el tipo de conexión a host y usar / (localhost) como IP de acceso. Con psql tiene que utilizar psql -h localhost -U usuario para acceder al sistema. 3. Cambiar en el fichero de configuración postgresql.conf las siguientes lineas: listen_addresses = 'localhost' unix_socket_permissions = 0700 Si las bases de datos van a ser accedidas desde otras máquinas externas, tiene que definir también en listen_addresses la IP del servidor postgresql. 4. Actualizar el fichero pg_ident.conf con la siguiente linea: administrador postgres postgres Y comprobar que la única linea en pg_hba.conf con información sobre el usuario "postgres" es la siguiente: local all postgres ident administrador No olvidar ejecutar un restart de PostgreSQL para que los cambios se instalen. Como se ve en el siguiente ejemplo, ni siendo administrador root en su sistema operativo podra acceder como usuario "postgres" a su sistema de bases de datos PostgreSQL. Primero tiene que convertirse en usuario postgres en su sistema operativo.
6 $ psql -U postgres psql: could not connect to server: Permission denied Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.pgsql.5432"? [usuario@server:~] $ psql -h localhost -U postgres psql: FATAL: no pg_hba.conf entry for host " ", user "postgres", database "postgres", SSL off [root@server:~] # psql psql: FATAL: no pg_hba.conf entry for host "[local]", user "root", database "root", SSL off [root@server:~] # psql -U postgres psql: FATAL: Ident authentication failed for user "postgres" [root@server:~] # su - postgres [postgres@server:~] $ psql Welcome to psql 8.3.7, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit postgres=# Sólo queda comentar que en sistemas en producción y con datos importantes, debe restringir a un mínimo el número de personas con acceso a la cuenta "postgres" del sistema. Solamente los administradores, que sepan que es lo que están haciendo, deben tener este acceso. Para crear usuarios, usar el comando CREATE USER, que tiene la siguiente sintaxis: CREATE USER username [ WITH [ SYSID uid ] [ PASSWORD 'password' ] ] [ CREATEDB NOCREATEDB ] [ CREATEUSER NOCREATEUSER ] [ IN GROUP groupname [,...] ] [ VALID UNTIL 'abstime' ] Entonces, crear un usuario llamado david: postgres=# CREATE USER david postgres-# WITH PASSWORD 'd3st0' postgres-# NOCREATEDB postgres-# NOCREATEUSER postgres-# ; CREATE USER postgres=# Ya tiene a david en su base de datos. Ahora, para borrar a david, utilizar el comando:
7 postgres=# DROP USER david; DROP USER Crear el usuario vendedor y su clave mediante la sentencia: CREATE USER vendedor WITH PASSWORD 'patito'; Crear el usuario vendedor, su clave y fecha de expiración de cuenta; CREATE USER vendedor WITH PASSWORD 'patito' VALID UNTIL '2011/31/12'; Crear un usuario como super usuario, CREATE USER vendedor CREATEUSER CREATEDB; En PostgreSQL, al igual que en otros gestores de base de datos, puede gestionar usuario utilizando la primera letra de la opción correspondiente, como: CREATEUSER -U vendedor -D -A nuevousuario; Incluso, puede utilizar el formato interactivo: CREATEUSER Enter name of user to add: Shall the new user be allowed to create new database(y/n)? Shall the new user be allowed to create more new user(y/n)? para resetear la clave del usuario vendedor, utilizar: ALTER USER vendedor WITH PASSWORD 'PO123!_1'; Privilegios Cuando se crea un objeto en PostgreSQL, se le asigna un dueño. Por defecto, será el mismo usuario que lo ha creado. Para cambiar el dueño de una tabla, índice, secuencia, etc., debe usar el comando alter table. El dueño del objeto es el único que puede hacer cambios sobre él, si quiere cambiar este comportamiento, debe asignar privilegios a otros usuarios. Los privilegios se asignan y eliminan mediante las sentencias grant y revoke. PostgreSQL define los siguientes tipos de operaciones para dar privilegios: select, insert, update, delete, rule, references, trigger, create, temporary, execute, usage, y all privileges. Se presentan algunas sentencias de trabajo con privilegios, que siguen el estándar SQL: grant all privileges on proveedores to marc;
8 grant select on precios to manuel; grant update on precios to group migrupo; revoke all privileges on precios to manuel; grant select on ganacias from public; Lenguaje SQL El lenguaje de consulta estructurado (SQL) es un lenguaje de base de datos normalizado, utilizado por el motor de base de datos de Microsoft Jet. SQL se utiliza para crear objetos QueryDef, como el argumento de origen del método OpenRecordSet y como la propiedad RecordSource del control de datos. también se puede utilizar con el método Execute para crear y manipular directamente las bases de datos Jet y crear consultas SQL de paso a través para manipular bases de datos remotas cliente - servidor. Componentes del SQL El lenguaje SQL está compuesto por comandos, cláusulas, operadores y funciones de agregado. Estos elementos se combinan en las instrucciones para crear, actualizar y manipular las bases de datos. Comandos Existen dos tipos de comandos SQL: Los DLL que permiten crear y definir nuevas bases de datos, campos e índices. Los DML que permiten generar consultas para ordenar, filtrar y extraer datos de la base de datos. Comandos DLL Comando Descripción CREATE Utilizado para crear nuevas tablas, campos e índices DROP Empleado para eliminar tablas e índices ALTER Utilizado para modificar las tablas agregando campos o cambiando la definición de los campos. Comandos DML Comando Descripción SELECT Utilizado para consultar registros de la base de datos que satisfagan un criterio determinado INSERT Utilizado para cargar lotes de datos en la base de datos en una única operación. UPDATE Utilizado para modificar los valores de los campos y registros especificados DELETE Utilizado para eliminar registros de una tabla de una base de datos Cláusulas Las cláusulas son condiciones de modificación utilizadas para definir los datos que desea seleccionar o manipular. cláusula Descripción FROM Utilizada para especificar la tabla de la cual se van a seleccionar los registros WHERE Utilizada para especificar las condiciones que deben reunir los registros que se van a seleccionar GROUP BY Utilizada para separar los registros seleccionados en grupos específicos HAVING Utilizada para expresar la condición que debe satisfacer cada grupo ORDER BY Utilizada para ordenar los registros seleccionados de acuerdo con un orden específico Operadores Lógicos
9 Operador Uso AND "y" lógico. Evalúa dos condiciones y devuelve un valor de verdad sólo si ambas son ciertas. OR "o" lógico. Evalúa dos condiciones y devuelve un valor de verdad si alguna de las dos es cierta. NOT Negación lógica. Devuelve el valor contrario de la expresión. Operadores de Comparación Operador Uso < Menor que > Mayor que <> Distinto de <= Menor o Igual que >= Mayor o Igual que = Igual que BETWEEN Especifica un intervalo de valores. LIKE Utilizado en la comparación de un modelo In Selecciona registros de una base de datos Funciones de Agregado Las funciones de agregado se usan dentro de una cláusula SELECT en grupos de registros para devolver un único valor que se aplica a un grupo de registros. Función Descripción AVG Calcula el promedio de los valores de un campo determinado COUNT Cuenta el número de registros de la selección SUM Suma todos los valores de un campo determinado MAX Devuelve el valor más alto de un campo especificado MIN Devuelve el valor más bajo de un campo especificado
10 Consultas de Selección Las consultas de selección se utilizan para indicar al motor de datos que devuelva información de las bases de datos, esta información es devuelta en forma de conjunto de registros que se pueden almacenar en un objeto recordset. Este conjunto de registros es modificable. Consultas básicas La sintaxis básica de una consulta de selección es la siguiente: SELECT Campos FROM Tabla; En donde campos es la lista de campos que se deseen recuperar y tabla es el origen de los mismos, por ejemplo: SELECT Nombre, Telefono FROM Clientes; Esta consulta devuelve un recordset con el campo nombre y teléfono de la tabla clientes. Ordenando los registros Adicionalmente se puede especificar el orden en que se desean recuperar los registros de las tablas mediante la cláusula ORDER BY Lista de Campos. En donde Lista de campos representa los campos a ordenar. Ejemplo: SELECT CodigoPostal, Nombre, Telefono FROM Clientes ORDER BY Nombre; Esta consulta devuelve los campos CodigoPostal, Nombre, Telefono de la tabla Clientes ordenados por el campo Nombre. Se pueden ordenar los registros por mas de un campo, como por ejemplo: SELECT CodigoPostal, Nombre, Telefono FROM Clientes ORDER BY CodigoPostal, Nombre; Incluso se puede especificar el orden de los registros: ascendente mediante la cláusula (ASC - se toma este valor por defecto) o descendente (DESC) SELECT CodigoPostal, Nombre, Telefono FROM Clientes ORDER BY CodigoPostal DESC, Nombre ASC; Consultas con Predicado El predicado se incluye entre la cláusula y el primer nombre del campo a recuperar, los posibles predicados son: Predicado Descripción ALL Devuelve todos los campos de la tabla TOP Devuelve un determinado número de registros de la tabla DISTINCT Omite los registros cuyos campos seleccionados coincidan totalmente DISTINCTROW Omite los registros duplicados basándose en la totalidad del registro y no
11 sólo en los campos seleccionados. ALL Sí no se incluye ninguno de los predicados se asume ALL. El Motor de base de datos selecciona todos los registros que cumplen las condiciones de la instrucción SQL. No se conveniente abusar de este predicado ya que obligamos al motor de la base de datos a analizar la estructura de la tabla para averiguar los campos que contiene, es mucho más rápido indicar el listado de campos deseados. SELECT ALL FROM Empleados; SELECT * FROM Empleados; TOP Devuelve un cierto número de registros que entran entre al principio o al final de un rango especificado por una cláusula ORDER BY. Supongamos que queremos recuperar los nombres de los 25 primeros estudiantes del curso 1994: SELECT TOP 25 Nombre, Apellido FROM Estudiantes ORDER BY Nota DESC; Si no se incluye la cláusula ORDER BY, la consulta devolverá un conjunto arbitrario de 25 registros de la tabla Estudiantes. El predicado TOP no elige entre valores iguales. En el ejemplo anterior, si la nota media número 25 y la 26 son iguales, la consulta devolverá 26 registros. Se puede utilizar la palabra reservada PERCENT para devolver un cierto porcentaje de registros que caen al principio o al final de un rango especificado por la cláusula ORDER BY. Supongamos que en lugar de los 25 primeros estudiantes deseamos el 10 por ciento del curso: SELECT TOP 10 PERCENT Nombre, Apellido FROM Estudiantes ORDER BY Nota DESC; El valor que va a continuación de TOP debe ser un Integer sin signo. TOP no afecta a la posible actualización de la consulta. DISTINCT Omite los registros que contienen datos duplicados en los campos seleccionados. Para que los valores de cada campo listado en la instrucción SELECT se incluyan en la consulta deben ser únicos. Por ejemplo, varios empleados listados en la tabla Empleados pueden tener el mismo apellido. Si dos registros contienen López en el campo Apellido, la siguiente instrucción SQL devuelve un único registro: SELECT DISTINCT Apellido FROM Empleados; Con otras palabras el predicado DISTINCT devuelve aquellos registros cuyos campos indicados en la cláusula SELECT posean un contenido diferente. El resultado de una consulta que utiliza DISTINCT no es puede actualizar y no refleja los cambios subsiguientes realizados por otros usuarios. DISTINCTROW
12 Devuelve los registros diferentes de una tabla; a diferencia del predicado anterior que sólo se fijaba en el contenido de los campos seleccionados, éste lo hace en el contenido del registro completo independientemente de los campos indicados en la cláusula SELECT. SELECT DISTINCTROW Apellido FROM Empleados; Si la tabla empleados contiene dos registros: Antonio López y Marta López el ejemplo del predicado DISTINCT devuelve un único registro con el valor López en el campo Apellido ya que busca no duplicados en dicho campo. Este último ejemplo devuelve dos registros con el valor López en el apellido ya que se buscan no duplicados en el registro completo. Alias En determinadas circunstancias es necesario asignar un nombre a alguna columna determinada de un conjunto devuelto, otras veces por simple capricho o por otras circunstancias. Para resolver todas ellas tenemos la palabra reservada AS que se encarga de asignar el nombre que deseamos a la columna deseada. Tomado como referencia el ejemplo anterior podemos hacer que la columna devuelta por la consulta, en lugar de llamarse apellido (igual que el campo devuelto) se llame Empleado. En este caso procederíamos de la siguiente forma: SELECT DISTINCTROW Apellido AS Empleado FROM Empleados; Recuperando información de una base de datos externa Para concluir este capítulo se debe hacer referencia a la recuperación de registros de bases de datos externa. Es ocasiones es necesaria la recuperación de información que se encuentra contenida en una tabla que no se encuentra en la base de datos que ejecutará la consulta o que en ese momento no se encuentra abierta, esta situación la podemos resolver con la palabra reservada IN de la siguiente forma: SELECT DISTINCTROW Apellido AS Empleado FROM Empleados IN 'c:\databases\gestion.mdb'; En donde c:\databases\gestion.mdb es la base de datos que contiene la tabla Empleados.
13 Criterios de Selección En el capítulo anterior vimos la forma de recuperar los registros de las tablas, las formas empleadas devolvían todos los registros de la mencionada tabla. A lo largo de este capítulo se estudiarán las posibilidades de filtrar los registros con el fin de recuperar solamente aquellos que cumplan con ciertas condiciones preestablecidas. Antes de comenzar el desarrollo de este capítulo hay que recalcar tres detalles de vital importancia. El primero de ellos es que cada vez que se desee establecer una condición referida a un campo de texto la condición de búsqueda debe ir encerrada entre comillas simples; la segunda es que no es posible establecer condiciones de búsqueda en los campos memo y; la tercera y última hace referencia a las fechas. Las fechas se deben escribir siempre en formato mm-dd-aa en donde mm representa el mes, dd el día y aa el año, hay que prestar atención a los separadores - no sirve la separación habitual de la barra (/), hay que utilizar el guión (-) y además la fecha debe ir encerrada entre almohadillas (#). Por ejemplo si deseamos referirnos al día 3 de Septiembre de 1995 deberemos hacerlo de la siguiente forma; # # o #9-3-95#. Operadores Lógicos Los operadores Lógicos soportados por SQL son: AND, OR, XOR, Eqv, Imp, Is y Not. A excepción de los dos últimos todos poseen la siguiente sintaxis: <expresión1> operador <expresión2> En donde expresión1 y expresión2 son las condiciones a evaluar, el resultado de la operación varía en función del operador lógico. La tabla adjunta muestra los diferentes posibles resultados: <expresión1> Operador <expresión2> Resultado Verdad AND Falso Falso Verdad AND Verdad Verdad Falso AND Verdad Falso Falso AND Falso Falso Verdad OR Falso Verdad Verdad OR Verdad Verdad Falso OR Verdad Verdad Falso OR Falso Falso Verdad XOR Verdad Falso Verdad XOR Falso Verdad Falso XOR Verdad Verdad Falso XOR Falso Falso Verdad Eqv Verdad Verdad Verdad Eqv Falso Falso Falso Eqv Verdad Falso Falso Eqv Falso Verdad Verdad Imp Verdad Verdad Verdad Imp Falso Falso Verdad Imp Null Null Falso Imp Verdad Verdad Falso Imp Falso Verdad Falso Imp Null Verdad Null Imp Verdad Verdad Null Imp Falso Null Null Imp Null Null Si a cualquiera de las anteriores condiciones le anteponemos el operador NOT el resultado de la operación será el contrario al devuelto sin el operador NOT. El último operador denominado Is se emplea para comparar dos variables de tipo objeto <Objeto1> Is <Objeto2>. este operador devuelve verdad si los dos objetos son iguales SELECT * FROM Empleados WHERE Edad > 25 AND Edad < 50; SELECT * FROM Empleados WHERE (Edad > 25 AND Edad < 50) OR Sueldo = 100; SELECT * FROM Empleados WHERE NOT Estado = 'Soltero'; SELECT * FROM Empleados WHERE (Sueldo > 100 AND Sueldo < 500) OR (Estado = 'Aragua' AND Estado = 'Casado'
14 Intervalos de Valores Para indicar que deseamos recuperar los registros según el intervalo de valores de un campo emplearemos el operador Between cuya sintaxis es: campo [Not] Between valor1 And valor2 (la condición Not es opcional) En este caso la consulta devolveráa los registros que contengan en "campo" un valor incluido en el intervalo valor1, valor2 (ambos inclusive). Si anteponemos la condición Not devolverá aquellos valores no incluidos en el intervalo. SELECT * FROM Pedidos WHERE CodPostal Between And 28999; (Devuelve los pedidos realizados en el Estado Carabobo) SELECT IIf(CodPostal Between And 28999, 'El UNiversal', 'El Nacional') FROM Editores; (Devuelve el valor 'El Universal' si el código postal se encuentra en el intervalo, 'El Nacional' en caso contrario) El Operador Like Se utiliza para comparar una expresión de cadena con un modelo en una expresión SQL. Su sintaxis es: expresión Like modelo En donde expresión es una cadena modelo o campo contra el que se compara expresión. Se puede utilizar el operador Like para encontrar valores en los campos que coincidan con el modelo especificado. Por modelo puede especificar un valor completo (Ana María), o se puede utilizar caracteres comodín como los reconocidos por el sistema operativo para encontrar un rango de valores (Like An*). El operador Like se puede utilizar en una expresión para comparar un valor de un campo con una expresión de cadena. Por ejemplo, si introduce Like C* en una consulta SQL, la consulta devuelve todos los valores de campo que comiencen por la letra C. En una consulta con Parámetros, puede hacer que el usuario escriba el modelo que se va a utilizar. El ejemplo siguiente devuelve los datos que comienzan con la letra P seguido de cualquier letra entre A y F y de tres dígitos: Like 'P[A-F]###' Este ejemplo devuelve los campos cuyo contenido empiece con una letra de la A a la D seguidas de cualquier cadena. Like '[A-D]*' En la tabla siguiente se muestra cómo utilizar el operador Like para comprobar expresiones con diferentes modelos.
15 Tipo de coincidencia Modelo Planteado Coincide No coincide Varios caracteres 'a*a' 'aa', 'aba', 'abbba' 'abc' carácter especial 'a[*]a' 'a*a' 'aaa' Varios caracteres 'ab*' 'abcdefg', 'abc' 'cab', 'aab' Un solo carácter 'a?a' 'aaa', 'a3a', 'aba' 'abbba' Un solo dígito 'a#a', a0a', 'a1a', 'a2a' 'aaa', 'a10a' Rango de caracteres '[a-z]' 'f', 'p', 'j' '2', '&' Fuera de un rango '[!a-z]' '9', '&', '%' 'b', 'a' Distinto de un dígito '[!0-9]' 'A', 'a', '&', '~' '0', '1', '9' Combinada 'a[!b-m]#' 'An9', 'az0', 'a99' 'abc', 'aj0' El Operador In Este operador devuelve aquellos registros cuyo campo indicado coincide con alguno de los en una lista. Su sintaxis es: expresión [Not] In(valor1, valor2,...) SELECT * FROM Pedidos WHERE Provincia In ('Caracas', 'Maracay', 'Turmero' La cláusula WHERE La cláusula WHERE puede usarse para determinar qué registros de las tablas enumeradas en la cláusula FROM aparecerán en los resultados de la instrucción SELECT. Después de escribir esta cláusula se deben especificar las condiciones expuestas en los apartados 3.1 y 3.2. Sí no se emplea esta cláusula, la consulta devolverá todas las filas de la tabla. WHERE es opcional, pero cuando aparece debe ir a continuación de FROM. SELECT Apellidos, Salario FROM Empleados WHERE Salario > 21000; SELECT Id_Producto, Existencias FROM Productos WHERE Existencias <= Nuevo_Pedido; SELECT * FROM Pedidos WHERE Fecha_Envio = #5/10/94#; SELECT Apellidos, Nombre FROM Empleados WHERE Apellidos = 'King'; SELECT Apellidos, Nombre FROM Empleados WHERE Apellidos Like 'S*'; SELECT Apellidos, Salario FROM Empleados WHERE Salario Between 200 And 300; SELECT Apellidos, Salario FROM Empl WHERE Apellidos Between 'Lon' And 'Tol'; SELECT Id_Pedido, Fecha_Pedido FROM Pedidos WHERE Fecha_Pedido Between #1-1-94# And # #; SELECT Apellidos, Nombre, Ciudad FROM Empleados WHERE Ciudad In ('Maturín', 'Anaco', 'Barcelona'
16 Agrupamiento de Registros GROUP BY Combina los registros con valores idénticos, en la lista de campos especificados, en un único registro. Para cada registro se crea un valor sumario si se incluye una función SQL agregada, como por ejemplo Sum o Count, en la instrucción SELECT. Su sintaxis es: SELECT campos FROM tabla WHERE criterio GROUP BY campos del grupo GROUP BY es opcional. Los valores de resumen se omiten si no existe una función SQL agregada en la instrucción SELECT. Los valores Null en los campos GROUP BY se agrupan y no se omiten. No obstante, los valores Null no se Evalúan en ninguna de las funciones SQL agregadas. Se utiliza la cláusula WHERE para excluir aquellas filas que no desea agrupar; mientras que la cláusula HAVING se utiliza para filtrar los registros una vez agrupados. A menos que contenga un dato Memo u Objeto OLE, un campo de la lista de campos GROUP BY puede referirse a cualquier campo de las tablas que aparecen en la cláusula FROM, incluso si el campo no esta incluido en la instrucción SELECT, siempre y cuando la instrucción SELECT incluya al menos una función SQL agregada. Todos los campos de la lista de campos de SELECT deben o bien incluirse en la cláusula GROUP BY o como argumentos de una función SQL agregada. SELECT Id_Familia, Sum(Stock) FROM Productos GROUP BY Id_Familia; Una vez que GROUP BY ha combinado los registros, HAVING muestra cualquier registro agrupado por la cláusula GROUP BY que satisfaga las condiciones de la cláusula HAVING. HAVING es similar a WHERE, determina qué registros se seleccionan. Una vez que los registros se han agrupado utilizando GROUP BY, HAVING determina cuales de ellos se van a mostrar. SELECT Id_Familia Sum(Stock) FROM Productos GROUP BY Id_Familia HAVING Sum(Stock) > 100 AND NombreProducto Like BOS*; AVG Calcula la media Aritmética de un conjunto de valores contenidos en un campo especificado de una consulta. Su sintaxis es la siguiente Avg(expr) En donde expr representa el campo que contiene los datos numéricos para los que se desea calcular la media o una expresión que realiza un cálculo utilizando los datos de dicho campo. La media calculada por Avg es la media Aritmética (la suma de los valores dividido por el número de valores). La función Avg no incluye ningún campo Null en el cálculo. SELECT Avg(Gastos) AS Promedio FROM Pedidos WHERE Gastos > 100;
17 Count Calcula el número de registros devueltos por una consulta. Su sintaxis es la siguiente Count(expr) En donde expr contiene el nombre del campo que desea contar. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una función (la cual puede ser intrínseca o definida por el usuario pero no otras de las funciones agregadas de SQL). Puede contar cualquier tipo de datos incluso texto. Aunque expr puede realizar un cálculo sobre un campo, Count simplemente cuenta el número de registros sin tener en cuenta qué valores se almacenan en los registros. La función Count no cuenta los registros que tienen campos null a menos que expr sea el carácter comodín asterisco (*). Si utiliza un asterisco, Count calcula el número total de registros, incluyendo aquellos que contienen campos null. Count(*) es considerablemente más rápida que Count(Campo). No se debe poner el asterisco entre dobles comillas ('*'). SELECT Count(*) AS Total FROM Pedidos; Si expr identifica a múltiples campos, la función Count cuenta un registro sólo si al menos uno de los campos no es Null. Si todos los campos especificados son Null, no se cuenta el registro. Hay que separar los nombres de los campos con ampersand (&). SELECT Count(FechaEnvio & Transporte) AS Total FROM Pedidos; Max, Min Devuelven el mínimo o el máximo de un conjunto de valores contenidos en un campo especifico de una consulta. Su sintaxis es: Min(expr) Max(expr) En donde expr es el campo sobre el que se desea realizar el cálculo. Expr pueden incluir el nombre de un campo de una tabla, una constante o una función (la cual puede ser intrínseca o definida por el usuario pero no otras de las funciones agregadas de SQL). SELECT Min(Gastos) AS ElMin FROM Pedidos WHERE Pais = 'Venezuela'; SELECT Max(Gastos) AS ElMax FROM Pedidos WHERE Pais = 'Venezuela';
18 StDev, StDevP Devuelve estimaciones de la desviación Estándar para la población (el total de los registros de la tabla) o una muestra de la población representada (muestra aleatoria). Su sintaxis es: StDev(expr) StDevP(expr) En donde expr representa el nombre del campo que contiene los datos que desean evaluarse o una expresión que realiza un cálculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una función (la cual puede ser intrínseca o definida por el usuario pero no otras de las funciones agregadas de SQL) StDevP Evalúa una población, y StDev Evalúa una muestra de la población. Si la consulta contiene menos de dos registros (o ningún registro para StDevP), estas funciones devuelven un valor Null (el cual indica que la desviación Estándar no puede calcularse). SELECT StDev(Gastos) AS Desviacion FROM Pedidos WHERE Pais = 'México'; SELECT StDevP(Gastos) AS Desviacion FROM Pedidos WHERE Pais= 'España'; Sum Devuelve la suma del conjunto de valores contenido en un campo especifico de una consulta. Su sintaxis es: Sum(expr) En donde expr respresenta el nombre del campo que contiene los datos que desean sumarse o una expresión que realiza un cálculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una función (la cual puede ser intrínseca o definida por el usuario pero no otras de las funciones agregadas de SQL). SELECT Sum(PrecioUnidad * Cantidad) AS Total FROM DetallePedido; Var, VarP Devuelve una estimación de la varianza de una población (sobre el total de los registros) o una muestra de la población (muestra aleatoria de registros) sobre los valores de un campo. Su sintaxis es: Var(expr) VarP(expr) VarP Evalúa una población, y Var Evalúa una muestra de la población. Expr el nombre del campo que contiene los datos que desean evaluarse o una expresión que realiza un cálculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una función (la cual puede ser intrínseca o definida por el usuario pero no otras de las
19 funciones agregadas de SQL) Si la consulta contiene menos de dos registros, Var y VarP devuelven Null (esto indica que la varianza no puede calcularse). Puede utilizar Var y VarP en una expresión de consulta o en una Instrucción SQL. SELECT Var(Gastos) AS Varianza FROM Pedidos WHERE Pais = 'Israel'; SELECT VarP(Gastos) AS Varianza FROM Pedidos WHERE Pais = 'Cuba';
20 Consultas de Acción Las consultas de acción son aquellas que no devuelven ningún registro, son las encargadas de acciones como Añadir y borrar y modificar registros. DELETE Crea una consulta de eliminación que elimina los registros de una o más de las tablas listadas en la cláusula FROM que satisfagan la cláusula WHERE. Esta consulta elimina los registros completos, no es posible eliminar el contenido de algún campo en concreto. Su sintaxis es: DELETE Tabla.* FROM Tabla WHERE criterio DELETE es especialmente útil cuando se desea eliminar varios registros. En una instrucción DELETE con múltiples tablas, debe incluir el nombre de tabla (Tabla.*). Si especifica más de una tabla desde la que eliminar registros, todas deben ser tablas de muchos a uno. Si desea eliminar todos los registros de una tabla, eliminar la propia tabla es más eficiente que ejecutar una consulta de borrado. Se puede utilizar DELETE para eliminar registros de una única tabla o desde varios lados de una relación uno a muchos. Las operaciones de eliminación en cascada en una consulta únicamente eliminan desde varios lados de una relación. Por ejemplo, en la relación entre las tablas Clientes y Pedidos, la tabla Pedidos es la parte de muchos por lo que las operaciones en cascada solo afectaran a la tabla Pedidos. Una consulta de borrado elimina los registros completos, no únicamente los datos en campos específicos. Si desea eliminar valores en un campo especificado, crear una consulta de actualización que cambie los valores a Null. Una vez que se han eliminado los registros utilizando una consulta de borrado, no puede deshacer la operación. Si desea saber qué registros se eliminarán, primero examine los resultados de una consulta de selección que utilice el mismo criterio y Después ejecute la consulta de borrado. Mantenga copias de seguridad de sus datos en todo momento. Si elimina los registros equivocados podrá recuperarlos desde las copias de seguridad. DELETE * FROM Empleados WHERE Cargo = 'Vendedor'; INSERT INTO Agrega un registro en una tabla. Se la conoce como una consulta de datos Añadidos. Esta consulta puede ser de dos tipo: Insertar un único registro o Insertar en una tabla los registros contenidos en otra tabla. Para insertar un único Registro: En este caso la sintaxis es la siguiente: INSERT INTO Tabla (campo1, campo2,.., campon) VALUES (valor1, valor2,..., valorn) Esta consulta graba en el campo1 el valor1, en el campo2 y valor2 y así sucesivamente. Hay que prestar especial atención a acotar entre comillas simples (') los valores literales (cadenas de caracteres) y las
21 fechas indicarlas en formato mm-dd-aa y entre caracteres de almohadillas (#). Para insertar Registros de otra Tabla: En este caso la sintaxis es: INSERT INTO Tabla [IN base_externa] (campo1, campo2,..., campon) SELECT TablaOrigen.campo1, TablaOrigen.campo2,..., TablaOrigen.campoN FROM TablaOrigen En este caso se seleccionarán los campos 1,2,..., n dela tabla origen y se grabarán en los campos 1,2,.., n de la Tabla. La condición SELECT puede incluir la cláusula WHERE para filtrar los registros a copiar. Si Tabla y TablaOrigen poseen la misma estrucutra podemos simplificar la sintaxis a: INSERT INTO Tabla SELECT TablaOrigen.* FROM TablaOrigen De esta forma los campos de TablaOrigen se grabarán en Tabla, para realizar esta operación es necesario que todos los campos de TablaOrigen están contenidos con igual nombre en Tabla. Con otras palabras que Tabla posea todos los campos de TablaOrigen (igual nombre e igual tipo). En este tipo de consulta hay que tener especial atención con los campos contadores o autonuméricos puesto que al insertar un valor en un campo de este tipo se escribe el valor que contenga su campo homólogo en la tabla origen, no incrementándose como le corresponde. Se puede utilizar la instrucción INSERT INTO para agregar un registro único a una tabla, utilizando la sintaxis de la consulta de adición de registro único tal y como se mostró anteriormente. En este caso, su código específico, el nombre y el valor de cada campo del registro. Debe especificar cada uno de los campos del registro al que se le va a asignar un valor así como el valor para dicho campo. Cuando no se especifica dicho campo, se inserta el valor predeterminado o Null. Los registros se agregan al final de la tabla. tmabién se puede utilizar INSERT INTO para agregar un conjunto de registros pertenecientes a otra tabla o consulta utilizando la cláusula SELECT... FROM como se mostró anteriormente en la sintaxis de la consulta de adición de múltiples registros. En este caso la cláusula SELECT especifica los campos que se van a agregar en la tabla destino especificada. La tabla destino u origen puede especificar una tabla o una consulta. Si la tabla destino contiene una clave principal, hay que asegurarse que es única, y con valores no-null; si no es así, no se agregarán los registros. Si se agregan registros a una tabla con un campo Contador, no se debe incluir el campo Contador en la consulta. Se puede emplear la cláusula IN para agregar registros a una tabla en otra base de datos. Se pueden averiguar los registros que se agregarán en la consulta ejecutando primero una consulta de selección que utilice el mismo criterio de selección y ver el resultado. Una consulta de adición copia los registros de una o más tablas en otra. Las tablas que contienen los registros que se van a agregar no se verán afectadas por la consulta de adición. En lugar de agregar registros existentes en otra tabla, se puede especificar los valores de cada campo en un nuevo registro utilizando la cláusula VALUES. Si se omite la lista de campos, la cláusula VALUES debe incluir un valor para cada campo de la tabla, de
22 otra forma fallará INSERT. INSERT INTO Clientes SELECT Clientes_Viejos.* FROM Clientes_Nuevos; INSERT INTO Empleados (Nombre, Apellido, Cargo) VALUES ('Luis', 'Sánchez', 'Becario' INSERT INTO Empleados SELECT Vendedores.* FROM Vendedores WHERE Fecha_Contratacion < Now() - 30; UPDATE Crea una consulta de actualización que cambia los valores de los campos de una tabla especificada basándose en un criterio específico. Su sintaxis es: UPDATE Tabla SET Campo1=Valor1, Campo2=Valor2,... CampoN=ValorN WHERE Criterio; UPDATE es especialmente útil cuando se desea cambiar un gran número de registros o cuando éstos se encuentran en múltiples tablas. Puede cambiar varios campos a la vez. El ejemplo siguiente incrementa los valores Cantidad pedidos en un 10 por ciento y los valores Transporte en un 3 por ciento para aquellos que se hayan enviado al Reino Unido.: UPDATE Pedidos SET Pedido = Pedidos * 1.1, Transporte = Transporte * 1.03 WHERE PaisEnvio = 'VE'; UPDATE no genera ningún resultado. Para saber qué registros se van a cambiar, hay que examinar primero el resultado de una consulta de selección que utilice el mismo criterio y Después ejecutar la consulta de actualización. UPDATE Empleados SET Grado = 5 WHERE Grado = 2; UPDATE Productos SET Precio = Precio * 1.1 WHERE Proveedor = 8 AND Familia = 3; Si en una consulta de actualización suprimimos la cláusula WHERE todos los registros de la tabla señalada serán actualizados. UPDATE Empleados SET Salario = Salario * 1.1
23 Tipos de Datos Los tipos de datos SQL se clasifican en 13 tipos de datos primarios y de varios sinónimos válidos reconocidos por dichos tipos de datos. Tipos de dato primarios Tipo de Dato Longitud Descripción BINARY 1 byte Para consultas sobre tabla adjunta de productos de bases de datos que definen un tipo de datos Binario. BIT 1 byte Valores Si/No o True/False BYTE 1 byte Un valor entero entre 0 y 255. COUNTER 4 bytes Un número incrementado automáticamente (de tipo Long) CURRENCY 8 bytes Un entero escalable entre ,5808 y ,5807. DATETIME 8 bytes Un valor de fecha u hora entre los años 100 y SINGLE 4 bytes Un valor en punto flotante de precisión simple con un rango de *1038 a *10-45 para valores negativos, *10-45 a *1038 para valores positivos, y 0. DOUBLE 8 bytes Un valor en punto flotante de doble precisión con un rango de *10308 a * para valores negativos, * a *10308 para valores positivos, y 0. SHORT 2 bytes Un entero corto entre -32,768 y 32,767. LONG 4 bytes Un entero largo entre -2,147,483,648 y 2,147,483,647. LONGTEXT 1 byte por carácter De cero a un máximo de 1.2 gigabytes. LONGBINARY según se necesite De cero 1 gigabyte. Utilizado para objetos OLE. TEXT 1 byte por carácter De cero a 255 caracteres. La siguiente tabla recoge los sinónimos de los tipos de datos definidos: Tipo de Dato Sinónimos BINARY VARBINARY BIT BOOLEAN,LOGICAL,LOGICAL1,YESNO BYTE INTEGER1 COUNTER AUTOINCREMENT CURRENCY MONEY DATETIME DATE,TIME,TIMESTAMP SINGLE FLOAT4,IEEESINGLE,REAL DOUBLE FLOAT,FLOAT8,IEEEDOUBLE,NUMBER,NUMERIC SHORT INTEGER2,SMALLINT LONG INT,INTEGER,INTEGER4 LONGBINARY GENERAL,OLEOBJECT LONGTEXT LONGCHAR,MEMO,NOTE TEXT ALPHANUMERIC,CHAR,CHARACTER,STRING,VARCHAR VARIANT (No Admitido)VALUE
24 SubConsultas Una subconsulta es una instrucción SELECT anidada dentro de una instrucción SELECT, SELECT...INTO, INSERT...INTO, DELETE, o UPDATE o dentro de otra subconsulta. Puede utilizar tres formas de sintaxis para crear una subconsulta: comparación [ANY ALL SOME] (instrucción sql) expresión [NOT] IN (instrucción sql) [NOT] EXISTS (instrucción sql) En donde: comparación Es una expresión y un operador de comparación que compara la expresión con el resultado de la subconsulta. expresión Es una expresión por la que se busca el conjunto resultante de la subconsulta. instrucción sql Es una instrucción SELECT, que sigue el mismo formato y reglas que cualquier otra instrucción SELECT. Debe ir entre paréntesis. Se puede utilizar una subconsulta en lugar de una expresión en la lista de campos de una instrucción SELECT o en una cláusula WHERE o HAVING. En una subconsulta, se utiliza una instrucción SELECT para proporcionar un conjunto de uno o más valores especificados para evaluar en la expresión de la cláusula WHERE o HAVING. Se puede utilizar el predicado ANY o SOME, los cuales son sinónimos, para recuperar registros de la consulta principal, que satisfagan la comparación con cualquier otro registro recuperado en la subconsulta. El ejemplo siguiente devuelve todos los productos cuyo precio unitario es mayor que el de cualquier producto vendido con un descuento igual o mayor al 25 por ciento.: SELECT * FROM Productos WHERE PrecioUnidad > ANY (SELECT PrecioUnidad FROM DetallePedido WHERE Descuento >= 0.25 El predicado ALL se utiliza para recuperar únicamente aquellos registros de la consulta principal que satisfacen la comparación con todos los registros recuperados en la subconsulta. Si se cambia ANY por ALL en el ejemplo anterior, la consulta devolverá únicamente aquellos productos cuyo precio unitario sea mayor que el de todos los productos vendidos con un descuento igual o mayor al 25 por ciento. Esto es mucho más restrictivo. El predicado IN se emplea para recuperar únicamente aquellos registros de la consulta principal para los que algunos registros de la subconsulta contienen un valor igual. El ejemplo siguiente devuelve
25 todos los productos vendidos con un descuento igual o mayor al 25 por ciento.: SELECT * FROM Productos WHERE IDProducto IN (SELECT IDProducto FROM DetallePedido WHERE Descuento >= 0.25 Inversamente se puede utilizar NOT IN para recuperar únicamente aquellos registros de la consulta principal para los que no hay ningún registro de la subconsulta que contenga un valor igual. El predicado EXISTS (con la palabra reservada NOT opcional) se utiliza en comparaciones de verdad/falso para determinar si la subconsulta devuelve algún registro. Se puede utilizar tmabién alias del nombre de la tabla en una subconsulta para referirse a tablas listadas en la cláusula FROM fuera de la subconsulta. El ejemplo siguiente devuelve los nombres de los empleados cuyo salario es igual o mayor que el salario medio de todos los empleados con el mismo título. A la tabla Empleados se le ha dado el alias T1:: SELECT Apellido, Nombre, Titulo, Salario FROM Empleados AS T1 WHERE Salario >= (SELECT Avg(Salario) FROM Empleados WHERE T1.Titulo = Empleados.Titulo) ORDER BY Titulo; En el ejemplo anterior, la palabra reservada AS es opcional. SELECT Apellidos, Nombre, Cargo, Salario FROM Empleados WHERE Cargo LIKE "Agente Ven*" AND Salario > ALL (SELECT Salario FROM Empleados WHERE (Cargo LIKE "*Jefe*") OR (Cargo LIKE "*Director*") Obtiene una lista con el nombre, cargo y salario de todos los agentes de ventas cuyo salario es mayor que el de todos los jefes y directores. SELECT DISTINCTROW NombreProducto, Precio_Unidad FROM Productos WHERE (Precio_Unidad = (SELECT Precio_Unidad FROM Productos WHERE Nombre_Producto = "Almíbar anisado" Obtiene una lista con el nombre y el precio unitario de todos los productos con el mismo precio que el almíbar anisado. SELECT DISTINCTROW Nombre_Contacto, Nombre_Compañía, Cargo_Contacto, Telefono FROM Clientes WHERE (ID_Cliente IN (SELECT DISTINCTROW ID_Cliente FROM Pedidos WHERE Fecha_Pedido >= #04/1/93# <#07/1/93# Obtiene una lista de las compañías y los contactos de todos los clientes que han realizado un pedido en el segundo trimestre de SELECT Nombre, Apellidos FROM Empleados AS E WHERE EXISTS (SELECT * FROM Pedidos AS O WHERE O.ID_Empleado = E.ID_Empleado Selecciona el nombre de todos los empleados que han reservado al menos un pedido.
26 SELECT DISTINCTROW Pedidos.Id_Producto, Pedidos.Cantidad, (SELECT DISTINCTROW Productos.Nombre FROM Productos WHERE Productos.Id_Producto = Pedidos.Id_Producto) AS ElProducto FROM Pedidos WHERE Pedidos.Cantidad > 150 ORDER BY Pedidos.Id_Producto; Recupera el código del Producto y la Cantidad pedida de la tabla pedidos, extrayendo el nombre del producto de la tabla de productos.
27 Consultas de Referencias Cruzadas Una consulta de referencias cruzadas es aquella que nos permite visualizar los datos en filas y en columnas, estilo tabla, por ejemplo: Producto / año Pantalones Camisas Zapatos Si tenemos una tabla de productos y otra tabla de pedidos, podemos visualizar el total de productos pedidos por año para un artículo determinado, tal y como se visualiza en la tabla anterior. La sintaxis para este tipo de consulta es la siguiente: TRANSFORM función agregada instrucción select PIVOT campo pivot [IN (valor1[, valor2[,...]])] En donde: función agregada Es una función SQL agregada que opera sobre los datos seleccionados. instrucción select Es una instrucción SELECT. campo pivot Es el campo o expresión que desea utilizar para crear las cabeceras de la columna en el resultado de la consulta. valor1, valor2 Son valores fijos utilizados para crear las cabeceras de la columna. Para resumir datos utilizando una consulta de referencia cruzada, se seleccionan los valores de los campos o expresiones especificadas como cabeceras de columnas de tal forma que pueden verse los datos en un formato más compacto que con una consulta de selección. TRANSFORM es opcional pero si se incluye es la primera instrucción de una cadena SQL. Precede a la instrucción SELECT que especifica los campos utilizados como encabezados de fila y una cláusula GROUP BY que especifica el agrupamiento de las filas. Adicionalmente puede incluir otras cláusulas como por ejemplo WHERE, que especifica una selección adicional o un criterio de ordenación. Los valores devueltos en campo pivot se utilizan como encabezados de columna en el resultado de la consulta. Por ejemplo, al utilizar las cifras de ventas en el mes de la venta como pivot en una consulta de referencia cruzada se crearán 12 columnas. Puede restringir el campo pivot para crear encabezados a
28 partir de los valores fijos (valor1, valor2) listados en la cláusula opcional IN. tmabién puede incluir valores fijos, para los que no existen datos, para crear columnas adicionales. Ejemplos TRANSFORM Sum(Cantidad) AS Ventas SELECT Producto, Cantidad FROM Pedidos WHERE Fecha Between # # And # # GROUP BY Producto ORDER BY Producto PIVOT DatePart("m", Fecha Crea una consulta de tabla de referencias cruzadas que muestra las ventas de productos por mes para un año específico. Los meses aparecen de izquierda a derecha como columnas y los nombres de los productos aparecen de arriba hacia abajo como filas. TRANSFORM Sum(Cantidad) AS Ventas SELECT Compania FROM Pedidos WHERE Fecha Between # # And # # GROUP BY Compania ORDER BY Compania PIVOT "Trimestre " & DatePart("q", Fecha) In ('Trimestre1', 'Trimestre2', 'Trimestre 3', 'Trimestre 4' Crea una consulta de tabla de referencias cruzadas que muestra las ventas de productos por trimestre de cada proveedor en el año indicado. Los trimestres aparecen de izquierda a derecha como columnas y los nombres de los proveedores aparecen de arriba hacia abajo como filas. Un caso práctico: Se trata de resolver el siguiente problema: tenemos una tabla de productos con dos campos, el código y el nombre del producto, tenemos otra tabla de pedidos en la que anotamos el código del producto, la fecha del pedido y la cantidad pedida. Deseamos consultar los totales de producto por año, calculando la media anual de ventas. Estructura y datos de las tablas: Artículos: ID Nombre 1Zapatos2Pantalones3Blusas2. Pedidos: IdFechaCantidad111/11/ /11/ /11/ /10/ /05/ /0 8/ /01/ /08/ /10/ /12/ /12/ /10/ Para resolver la consulta planteamos la siguiente consulta: TRANSFORM Sum(Pedidos.Cantidad) AS Resultado SELECT Nombre AS Producto, Pedidos.Id AS código, Sum(Pedidos.Cantidad) AS TOTAL, Avg(Pedidos.Cantidad) AS Media FROM Pedidos INNER JOIN Artículos ON Pedidos.Id = Artículos.Id GROUP BY Pedidos.Id, Artículos.Nombre PIVOT Year(Fecha y obtenemos el siguiente resultado:
29 ProductoCódigoTOTALMedia Zapatatos Pantalones , Blusas Comentarios a la consulta: La clásula TRANSFORM indica el valor que deseamos visualizar en las columnas que realmente pertenecen a la consulta, en este caso 1996 y 1997, puesto que las demás columnas son opcionales. SELECT especifica el nombre de las columnas opcionales que deseamos visualizar, en este caso Producto, código, Total y Media, indicando el nombre del campo que deseamos mostrar en cada columna o el valor de la misma. Si incluimos una función de cálculo el resultado se hará en base a los datos de la fila actual y no al total de los datos. FROM especifica el origen de los datos. La primera tabla que debe figurar es aquella de donde deseamos extraer los datos, esta tabla debe contener al menos tres campos, uno para los títulos de la fila, otros para los títulos de la columna y otro para calcular el valor de las celdas. En este caso en concreto se deseaba visualizar el nombre del producto, como el tabla de pedidos sólo figuraba el código del mismo se añadió una nueva columna en la cláusula select llamada Producto que se corresponda con el campo Nombre de la tabla de artículos. Para vincular el código del artículo de la tabla de pedidos con el nombre del misma de la tabla artículos se insertó la cláusula INNER JOIN. La cláusula GROUP BY especifica el agrupamiento de los registros, contrariamente a los manuales de instrucción esta cláusula no es opcional ya que debe figurar siempre y debemos agrupar los registros por el campo del cual extraemos la información. En este caso existen dos campos del cual extraemos la información: pedidos.cantidad y artículos.nombre, por ellos agrupamos por los campos. Para finalizar la cláusula PIVOT indica el nombre de las columnas no opcionales, en este caso 1996 y 1997 y como vamos a el dato que aparecerá en las columnas, en este caso empleamos el año en que se produjo el pedido, extrayéndolo del campo pedidos.fecha. Otras posibilidades de fecha de la cláusula pivot son las siguientes: Para agrupamiento por Trimestres PIVOT "Tri " & DatePart("q",[Fecha] Para agrupamiento por meses (sin tener en cuenta el año) PIVOT Format([Fecha],"mmm") In ("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic" Para agrupar por días PIVOT Format([Fecha],"Short Date"
30 Consultas de Unión Internas Las vinculaciones entre tablas se realiza mediante la cláusula INNER que combina registros de dos tablas siempre que haya concordancia de valores en un campo común. Su sintaxis es: SELECT campos FROM tb1 INNER JOIN tb2 ON tb1.campo1 comp tb2.campo2 En donde: tb1, tb2 Son los nombres de las tablas desde las que se combinan los registros. campo1, campo2 Son los nombres de los campos que se combinan. Si no son numéricos, los campos deben ser del mismo tipo de datos y contener el mismo tipo de datos, pero no tienen que tener el mismo nombre. comp Es cualquier operador de comparación relacional : =, <, >, <=, >=, o <>. Se puede utilizar una operación INNER JOIN en cualquier cláusula FROM. Esto crea una combinación por equivalencia, conocida tmabién como Unión interna. Las combinaciones Equi son las más comunes; éstas combinan los registros de dos tablas siempre que haya concordancia de valores en un campo común a ambas tablas. Se puede utilizar INNER JOIN con las tablas Departamentos y Empleados para seleccionar todos los empleados de cada departamento. Por el contrario, para seleccionar todos los departamentos (incluso si alguno de ellos no tiene ningún empleado asignado) se emplea LEFT JOIN o todos los empleados (incluso si alguno no est asignado a ningún departamento), en este caso RIGHT JOIN. Si se intenta combinar campos que contengan datos Memo u Objeto OLE, se produce un error. Se pueden combinar dos campos numéricos cualesquiera, incluso si son de diferente tipo de datos. Por ejemplo, puede combinar un campo Numrico para el que la propiedad Size de su objeto Field est establecida como Entero, y un campo Contador. El ejemplo siguiente muestra cómo podría combinar las tablas Ctaegorías y Productos bas ndose en el campo IDCategoria: SELECT Nombre_Ctaegoría, NombreProducto FROM Categorias INNER JOIN Productos ON Categorias.IDCategoria = Productos.IDCategoria; En el ejemplo anterior, IDCategoria es el campo combinado, pero no est incluido en la salida de la consulta ya que no est incluido en la instrucción SELECT. Para incluir el campo combinado, incluir el nombre del campo en la instrucción SELECT, en este caso, Categorias.IDCategoria. tmabién se pueden enlazar varias cláusulas ON en una instrucción JOIN, utilizando la sintaxis siguiente:
31 SELECT campos FROM tabla1 INNER JOIN tabla2 ON tb1.campo1 comp tb2.campo1 AND ON tb1.campo2 comp tb2.campo2) OR ON tb1.campo3 comp tb2.campo3)]; tmabién puede anidar instrucciones JOIN utilizando la siguiente sintaxis: SELECT campos FROM tb1 INNER JOIN (tb2 INNER JOIN [( ]tb3 [INNER JOIN [( ]tablax [INNER JOIN...)] ON tb3.campo3 comp tbx.campox)] ON tb2.campo2 comp tb3.campo3) ON tb1.campo1 comp tb2.campo2; Un LEFT JOIN o un RIGHT JOIN puede anidarse dentro de un INNER JOIN, pero un INNER JOIN no puede anidarse dentro de un LEFT JOIN o un RIGHT JOIN. Ejemplo SELECT DISTINCTROW Sum([Precio unidad] * [Cantidad]) AS [Ventas], [Nombre] & " " & [Apellidos] AS [Nombre completo] FROM [Detalles de pedidos], Pedidos, Empleados, Pedidos INNER JOIN [Detalles de pedidos] ON Pedidos.[ID de pedido] = [Detalles de pedidos].[id de pedido], Empleados INNER JOIN Pedidos ON Empleados.[ID de empleado] = Pedidos.[ID de empleado] GROUP BY [Nombre] & " " & [Apellidos]; Crea dos combinaciones equivalentes: una entre las tablas Detalles de pedidos y Pedidos, y la otra entre las tablas Pedidos y Empleados. Esto es necesario ya que la tabla Empleados no contiene datos de ventas y la tabla Detalles de pedidos no contiene datos de los empleados. La consulta produce una lista de empleados y sus ventas totales. Si empleamos la cláusula INNER en la consulta se seleccionar n sólo aquellos registros de la tabla de la que hayamos escrito a la izquierda de INNER JOIN que contengan al menos un registro de la tabla que hayamos escrito a la derecha. Para solucionar esto tenemos dos cláusulas que sustituyen a la palabra clave INNER, éstas, son LEFT y RIGHT. LEFT toma todos los registros de la tabla de la izquierda aunque no tengan ningún registro en la tabla de la izquierda. RIGHT realiza la misma operación pero al contrario, toma todos los registros de la tabla de la derecha aunque no tenga ningún registro en la tabla de la izquierda.
32 Consultas de Unión Externas Se utiliza la operación UNION para crear una consulta de Unión, combinando los resultados de dos o más consultas o tablas independientes. Su sintaxis es: [TABLE] consulta1 UNION [ALL] [TABLE] consulta2 [UNION [ALL] [TABLE] consultan [... ]] En donde: consulta1, consulta2, consultan Son instrucciones SELECT, el nombre de una consulta almacenada o el nombre de una tabla almacenada precedido por la palabra clave TABLE. Puede combinar los resultados de dos o más consultas, tablas e instrucciones SELECT, en cualquier orden, en una única operación UNION. El ejemplo siguiente combina una tabla existente llamada Nuevas Cuentas y una instrucción SELECT: TABLE [Nuevas Cuentas] UNION ALL SELECT * FROM Clientes WHERE [Cantidad pedidos] > 1000; Si no se indica lo contrario, no se devuelven registros duplicados cuando se utiliza la operación UNION, no obstante puede incluir el predicado ALL para asegurar que se devuelven todos los registros. Esto hace que la consulta se ejecute más rápidamente. Todas las consultas en una operación UNION deben pedir el mismo número de campos, no obstante los campos no tienen porqu tener el mismo tamaño o el mismo tipo de datos. Se puede utilizar una cláusula GROUP BY y/o HAVING en cada argumento consulta para agrupar los datos devueltos. Puede utilizar una cláusula ORDER BY al final del último argumento consulta para visualizar los datos devueltos en un orden específico. SELECT [Nombre de compañía], Ciudad FROM Proveedores WHERE Pais = 'Brasil' UNION SELECT [Nombre de compañía], Ciudad FROM Clientes WHERE Pais = "Brasil" Recupera los nombres y las ciudades de todos proveedores y clientes de Brasil SELECT [Nombre de compañía], Ciudad FROM Proveedores WHERE País = 'Brasil' UNION SELECT [Nombre de compañía], Ciudad FROM Clientes WHERE País = 'Brasil' ORDER BY Ciudad Recupera los nombres y las ciudades de todos proveedores y clientes radicados en Brasil, ordenados por el nombre de la ciudad SELECT [Nombre de compañía], Ciudad FROM Proveedores WHERE País = 'Brasil' UNION SELECT [Nombre de compañía], Ciudad FROM Clientes WHERE País = 'Brasil' UNION SELECT [Apellidos], Ciudad FROM Empleados WHERE Regin = 'Amrica del Sur' Recupera los nombres y las ciudades de todos los proveedores y clientes de brasil y los apellidos y las
33 ciudades de todos los empleados de Amrica del Sur TABLE [Lista de clientes] UNION TABLE [Lista de proveedores] Recupera los nombres y cdigos de todos los proveedores y clientes
34 Estructuras de las Tablas Creación de Tablas Nuevas Si se está utilizando el motor de datos de Microsoft para acceder a bases de datos access, sólo se puede emplear esta instrucción para crear bases de datos propias de access. Su sintaxis es: CREATE TABLE tabla (campo1 tipo (tamaño) índice1, campo2 tipo (tamaño) índice2,..., índice multicampo,... ) En donde: Parte Descripción Tabla Es el nombre de la tabla que se va a crear. Campo1,campo2 Es el nombre del campo o de los campos que se van a crear en la nueva tabla. La nueva tabla debe contener, al menos, un campo. Tipo Es el tipo de datos de campo en la nueva tabla. (Ver Tipos de Datos). tamaño Es el tamaño del campo sólo se aplica para campos de tipo texto. Indice1,índice2 Es una cláusula CONSTRAINT que define el tipo de indice a crear. Esta cláusula en opcional. Indice multicampos Es una cláusula CONSTRAINT que define el tipo de indice multicampos a crear. Un índice multi campo es aquel que está indexado por el contenido de varios campos. Es opcional. CREATE TABLE Empleados (Nombre TEXT (25), Apellidos TEXT (50) Crea una nueva tabla llamada Empleados con dos campos, uno llamado Nombre de tipo texto y longutid 25 y otro llamado apellidos con longitud 50. CREATE TABLE Empleados (Nombre TEXT (10), Apellidos TEXT, Fecha_Nacimiento DATETIME) CONSTRAINT IndiceGeneral UNIQUE ([Nombre], [Apellidos], [Fecha_Nacimiento] Crea una nueva tabla llamada Empleados con un campo Nombre de tipo texto y longitud 10, otro con llamado Apellidos de tipo texto y longitud predeterminada (50) y uno más llamado Fecha_Nacimiento de tipo Fecha/Hora. tmabién crea un índice único (no permite valores repetidos) formado por los tres campos. CREATE TABLE Empleados (ID INTEGER CONSTRAINT IndicePrimario PRIMARY, Nombre TEXT, Apellidos TEXT, Fecha_Nacimiento DATETIME Crea una tabla llamada Empleados con un campo Texto de longitud predeterminada (50) llamado Nombre y otro igual llamado Apellidos, crea otro campo llamado Fecha_Nacimiento de tipo Fecha/Hora y el campo ID de tipo entero el que establece como clave principal. La cláusula CONSTRAINT Se utiliza la cláusula CONSTRAINT en las instrucciones ALTER TABLE y CREATE TABLE para crear o eliminar índices. Existen dos sintaxis para esta cláusula dependiendo si desea Crear o Eliminar un índice de un único campo o si se trata de un campo multiíndice. Si se utiliza el motor de datos de Microsoft, sólo podrá utilizar esta cláusula con las bases de datos propias de dicho motor. Para los índices de campos únicos:
35 CONSTRAINT nombre {PRIMARY KEY UNIQUE REFERENCES tabla externa [(campo externo1, campo externo2)]} Para los índices de campos múltiples: CONSTRAINT nombre {PRIMARY KEY (primario1[, primario2 [,...]]) UNIQUE (único1[, único2 [,...]]) FOREIGN KEY (ref1[, ref2 [,...]]) REFERENCES tabla externa [(campo externo1 [,campo externo2 [,...]])]} Parte Descripción Nombre Es el nombre del índice que se va a crear. PrimarioN Es el nombre del campo o de los campos que forman el índice primario. únicon Es el nombre del campo o de los campos que forman el índice de clave única. RefN Es el nombre del campo o de los campos que forman el índice externo (hacen referencia a campos de otra tabla).tabla externaes el nombre de la tabla que contiene el campo o los campos referenciados en refn Campos externos Es el nombre del campo o de los campos de la tabla externa especificados por ref1, ref2,..., refn Si se desea crear un índice para un campo cuando se esta utilizando las instrucciones ALTER TABLE o CREATE TABLE la cláusula CONTRAINT debe aparecer inmediatamente Después de la especificación del campo indexeado. Si se desea crear un índice con múltiples campos cuando se est utilizando las instrucciones ALTER TABLE o CREATE TABLE la cláusula CONSTRAINT debe aparecer fuera de la cláusula de creación de tabla. Tipo de Indice Descripción UNIQUE Genera un ndece de clave única. Lo que implica que los registros de la tabla no pueden contener el mismo valor en los campos indexados. PRIMARY KEY Genera un índice primario el campo o los campos especificados. Todos los campos de la clave principal deben ser únicos y no nulos, cada tabla sólo puede contener una única clave principal. FOREIGN KEY Genera un índice externo (toma como valor del índice campos contenidos en otras tablas). Si la clave principal de la tabla externa consta de más de un campo, se debe utilizar una definición de índice de múltiples campos, listando todos los campos de referencia, el nombre de la tabla externa, y los nombres de los campos referenciados en la tabla externa en el mismo orden que los campos de referencia listados. Si los campos referenciados son la clave principal de la tabla externa, no tiene que especificar los campos referenciados, predeterminado por valor, el motor Jet se comporta como si la clave principal de la tabla externa fueran los campos referenciados. Creación de índices Si se utiliza el motor de datos Jet de Microsoft sólo se pueden crear índices en bases de datos del mismo motor. La sintaxis para crear un índice en ua tabla ya definida en la siguiente: CREATE [ UNIQUE ] INDEX índice ON tabla (campo [ASC DESC][, campo [ASC DESC],...]) [WITH { PRIMARY DISALLOW NULL IGNORE NULL }] En donde:
36 Parte Descripción Indice Es el nombre del índice a crear. Tabla Es el nombre de una tabla existentes en la que se crear el índice. Campo Es el nombre del campo o lista de campos que consituyen el índice. ASC DESC Indica el orden de los valores de lso campos ASC indica un orden ascendente (valor predeterminado) y DESC un orden descendente. UNIQUE Indica que el indice no puede contener valores duplicados. DISALLOW NULL Prohibe valores nulos en el índice IGNORE NULL Excluye del índice los valores nulos incluidos en los campos que lo componen. PRIMARY Asigna al índice la Ctaegoría de clave principal, en cada tabla sólo puede existir un único indice que sea "Clave Principal". Si un índice es clave principal implica que que no puede contener valores nulos ni duplicados. Se puede utilizar CREATE INDEX para crear un pseudo índice sobre una tabla adjunta en una fuente de datos ODBC tal como SQL Server que no tenga todavía un índice. No necesita permiso o tener acceso a un servidor remoto para crear un pseudo índice, además la base de datos remota no es consciente y no es afectada por el pseudo índice. Se utiliza la misma sintaxis para las tabla adjunta que para las originales. Esto es especialmente útil para crear un índice en una tabla que ser a de sólo lectura debido a la falta de un índice. CREATE INDEX MiIndice ON Empleados (Prefijo, Telefono Crea un índice llamado MiIndice en la tabla empleados con los campos Prefijo y Telefono. CREATE UNIQUE INDEX MiIndice ON Empleados (ID) WITH DISALLOW NULL; Crea un índice en la tabla Empleados utilizando el campo ID, obligando que que el campo ID no contenga valores nulos ni repetidos. Modificar el Diseo de una Tabla Modifica el dise o de una tabla ya existente, se puden modificar los campos o los índices existentes. Su sintaxis es: ALTER TABLE tabla {ADD {COLUMN tipo de campo[(tamaño)] [CONSTRAINT índice] CONSTRAINT índice multicampo} DROP {COLUMN campo I CONSTRAINT nombre del índice} } En donde: Parte Descripción tabla Es el nombre de la tabla que se desea modificar. Campo Es el nombre del campo que se va a Añadir o eliminar.tipo Es el tipo de campo que se va a Añadir. tamaño Es el tamaño del campo que se va a Añadir (sólo para campos de texto). índice Es el nombre del índice del campo (cuando se crean campos) o el nombre del índice de la tabla que se desea eliminar. índice multicampo Es el nombre del índice del campo multicampo (cuando se crean campos) o el nombre del índice de la tabla que se desea eliminar. Operación Descripción ADD COLUMN Se utiliza para Añadir un nuevo campo a la tabla, indicando el nombre, el tipo de campo y opcionalmente el tamaño (para campos de tipo texto). ADD Se utliza para agregar un índice de multicampos o de un único campo. DROP COLUMN Se utliza para borrar un campo. Se especifica únicamente el nombre del campo. DROP Se utiliza para eliminar un índice. Se especifica únicamente el nombre del índice a continuación de la palabra reservada CONSTRAINT.
37 ALTER TABLE Empleados ADD COLUMN Salario CURRENCY; Agrega un campo Salario de tipo Moneda a la tabla Empleados. ALTER TABLE Empleados DROP COLUMN Salario; Elimina el campo Salario de la tabla Empleados. ALTER TABLE Pedidos ADD CONSTRAINT RelacionPedidos FOREIGN KEY (ID_Empleado) REFERENCES Empleados (ID_Empleado Agrega un indice externo a la tabla Pedidos. El índice externo se basa en el campo ID_Empleado y se refiere al campo ID_Empleado de la tabla Empleados. En este ejemplo no es necesario indicar el campo junto al nombre de la tabla en la cláusula REFERENCES, pues ID_Empleado es la clave principal de la tabla Empleados. ALTER TABLE Pedidos DROP CONSTRAINT RelacionPedidos; Elimina el ndide de la tabla Pedidos.
38 Consultas con Parámetros Las consultas con Parámetros son aquellas cuyas condiciones de búsqueda se definen mediante Parámetros. Si se ejecutan directamente desde la base de datos donde han sido definidas aparecerá un mensaje solicitando el valor de cada uno de los Parámetros. Si deseamos ejecutarlas desde una aplicación hay que asignar primero el valor de los Parámetros y Después ejecutarlas. Su sintaxis es la siguiente: PARAMETERS nombre1 tipo1, nombre2 tipo2,..., nombren tipon Consulta En donde: Parte Descripción Nombre Es el nombre del parámetro Tipo Es el tipo de datos del parámetro Consulta Una consulta SQL Puede utilizar nombre pero no tipo de datos en una cláusula WHERE o HAVING. PARAMETERS Precio_Minimo Currency, Fecha_Inicio DateTime; SELECT IDPedido, Cantidad FROM Pedidos WHERE Precio > precio_minimo AND FechaPedido >= Fecha_Inicio; El ejemplo siguiente muestra como utilizar los Parámetros en el programa de Visual Basic: Public Sub GeneraConsulta() Dim SQL As String Dim Qd As QueryDef Dim Rs As Recordset SQL = "PARAMETERS Precio_Minimo Currency, Fecha_Inicio DateTime; " SQL = SQL & "SELECT IDPedido, Cantidad FROM Pedidos WHERE Precio > " SQL = SQL & "Precio_Minimo AND FechaPedido >= Fecha_Inicio; " Set Qd = BaseDatos.CreateQueryDef(MiConsulta, SQL) Qd.Parameters!Precio_Minimo = 2 Qd.Parameters!FechaInicio = #31/12/95# Set Rs = Qd.OpenRecordset() End Sub Ejemplo: PARAMETERS [Escriba los Apellidos:] Text; SELECT * FROM Empleados WHERE [Escriba los Apellidos:] = [Apellidos]; La ejecución desde la base de datos solicita al usuario los apellidos del empleado y Después muestra los resultados.
39 Bases de Datos Externas Para el acceso a bases de datos externas se utiliza la cláusula IN. Se puede acceder a base de datos dbase, Paradox o Btrieve. Esta cláusula sólo permite la conexi n de una base de datos externa a la vez. Una base de datos externa es una base de datos que no sea la activa. Aunque para mejorar los rendimientos es mejor adjuntarlas a la base de datos actual y trabajar con ellas. Para especificar una base de datos que no pertenece a Access Basic, se agrega un punto y coma (;) al nombre y se encierra entre comillas simples. tmabién puede utilizar la palabra reservada DATABASE para especificar la base de datos externa. Por ejemplo, las l neas siguientes especifican la misma tabla: FROM Tabla IN '[dbase IV; DATABASE=C:\DBASE\DATOS\VENTAS;]'; FROM Tabla IN 'C:\DBASE\DATOS\VENTAS' 'dbase IV;' Acceso a una base de datos externa de Microsoft Access: SELECT IDCliente FROM Clientes IN MISDATOS.MDB WHERE IDCliente Like 'A*'; En donde MISDATOS.MDB es el nombre de una base de datos de Microsoft Access que contiene la tabla Clientes. Acceso a una base de datos externa de dbase III o IV: SELECT IDCliente FROM Clientes IN 'C:\DBASE\DATOS\VENTAS' 'dbase IV' WHERE IDCliente Like 'A*'; Para recuperar datos de una tabla de dbase III+ hay que utilizar 'dbase III+;' en lugar de 'dbase IV;'. Acceso a una base de datos de Paradox 3.x o 4.x: SELECT IDCliente FROM Clientes IN 'C:\PARADOX\DATOS\VENTAS' 'Paradox 4.x;' WHERE IDCliente Like 'A*'; Para recuperar datos de una tabla de Paradox versión 3.x, hay que sustituir 'Paradox 4.x;' por 'Paradox 3.x;'. Acceso a una base de datos de Btrieve: SELECT IDCliente FROM Clientes IN 'C:\BTRIEVE\DATOS\VENTAS\FILE.DDF' 'Btrieve;' WHERE IDCliente Like 'A*'; C:\BTRIEVE\DATOS\VENTAS\FILE.DDF es la ruta de acceso y nombre de archivo del archivo de definición de datos de Btrieve.
40 Omitir los Permisos de Ejecución En entornos de bases de datos con permisos de seguridad para grupos de trabajo se puede utilizar la cláusula WITH OWNERACCESS OPTION para que el usuario actual adquiera los derechos de propietario a la hora de ejecutar la consulta. Su sintaxis es: instrucción sql WITH OWNERACCESS OPTION SELECT Apellido, Nombre, Salario FROM Empleados ORDER BY Apellido WITH OWNERACCESS OPTION; Esta opción requiere que est declarado el acceso al fichero de grupo de trabajo (generalmente system.mda system.mdw) de la base de datos actual.
41 2. PostGreSQL PostgreSQL es un sistema de gestión de base de datos relacional orientada a objetos y libre, publicado bajo la licencia BSD. Como muchos otros proyectos de código abierto, el desarrollo de PostgreSQL no es manejado por una empresa y/o persona, sino que es dirigido por una comunidad de desarrolladores que trabajan de forma desinteresada, altruista, libre y/o apoyados por organizaciones comerciales. Dicha comunidad es denominada el PGDG (PostgreSQL Global Development Group) 2.1. Qué es PostGreSQL? PostGreSQL es un sistema de gestión de bases de datos objeto-relacional (ORDBMS) basado en el proyecto POSTGRES, de la universidad de Berkeley. El director de este proyecto es el profesor Michael Stonebraker, y fue patrocinado por Defense Advanced Research Projects Agency (DARPA), el Army Research Office (ARO), el National Science Foundation (NSF), y ESL, Inc. PostGreSQL es una derivación libre (OpenSource) de este proyecto, y utiliza el lenguaje SQL92/SQL99, así como otras características que comentaremos más adelante. Fue el pionero en muchos de los conceptos existentes en el sistema objeto-relacional actual, incluido, más tarde en otros sistemas de gestión comerciales. PostGreSQL es un sistema objeto-relacional, ya que incluye características de la orientación a objetos, como puede ser la herencia, tipos de datos, funciones, restricciones, disparadores, reglas e integridad transaccional. A pesar de esto, PostGreSQL no es un sistema de gestión de bases de datos puramente orientado a objetos Historia de PostGreSQL PostGreSQL (llamado también Postgres95) fue derivado del proyecto Postgres, como ya se ha comentado. A sus espaldas, este proyecto lleva más de una década de desarrollo, siendo hoy en día, el sistema libre más avanzado con diferencia, soportando la gran mayoría de las transacciones SQL, control concurrente, teniendo a su disposición varios "language bindings" como por ejemplo C, C++, Java, Python, PHP y muchos más. La implementación de Postgres DBMS comenzó en 1986, y no hubo una versión operativa hasta La versión 1.0 fue liberada en Junio de 1989 a unos pocos usuarios, tras la cual se liberó la versión 2.0 en Junio de 1990 debido a unas críticas sobre el sistema de reglas, que obligó a su reimplementación. La versión 3.0 apareció en el año 1991, e incluyó una serie de mejoras como una mayor eficiencia en el ejecutor de peticiones. El resto de versiones liberadas a partir de entonces, se centraron en la portabilidad del sistema. El proyecto se dio por finalizado en con la versión 4.2, debido al gran auge que estaba teniendo, lo cual causó la imposibilidad de mantenimiento por parte de los desarrolladores. En 1994, Andrew Yu y Jolly Chen añadieron un intérprete de SQL a este gestor. Postgres95, como así se llamó fue liberado a Internet como un proyecto libre (OpenSource). Estaba escrito totalmente en C, y la primera versión fue un 25% más pequeña que Postgres, y entre un 30 y un 50% más rápida. A parte de la corrección de algunos bugs, se mejoró el motor interno, se añadió un nuevo programa monitor, y se compiló usando la utilidad GNU Make y el compilador gcc sin necesidad de parchearlo (como había hecho falta en versiones anteriores). En 1996, los desarrolladores decidieron cambiar el nombre a al DBMS, y lo llamaron PostGreSQL (versión 6.0) para reflejar la relación entre Postgres y las versiones recientes de SQL. Se crearon
42 nuevas mejoras y modificaciones, que repercutieron en un 20-40% más de eficiencia, así como la incorporación del estándar SQL92. PostgreSQL ha tenido una larga evolución, la cual se inicia en 1982 con el proyecto Ingres en la Universidad de Berkeley. Este proyecto, liderado por Michael Stonebraker, fue uno de los primeros intentos en implementar un motor de base de datos relacional. Después de haber trabajado un largo tiempo en Ingres y de haber tenido una experiencia comercial con él mismo, Michael decidió volver a la Universidad en 1985 para trabajar en un nuevo proyecto sobre la experiencia de Ingres, dicho proyecto fue llamado post-ingres o simplemente POSTGRES. El proyecto post-ingres pretendía resolver los problemas con el modelo de base de datos relacional que habían sido aclarados a comienzos de los años El principal de estos problemas era la incapacidad del modelo relacional de comprender "tipos", es decir, combinaciones de datos simples que conforman una única unidad. Actualmente estos son llamados objetos. Se esforzaron en introducir la menor cantidad posible de funcionalidades para completar el soporte de tipos. Estas funcionalidades incluían la habilidad de definir tipos, pero también la habilidad de describir relaciones - las cuales hasta ese momento eran ampliamente utilizadas pero mantenidas completamente por el usuario. En Postgres la base de datos «comprendía» las relaciones y podía obtener información de tablas relacionadas utilizando reglas. Postgres usó muchas ideas de Ingres pero no su código. La siguiente lista muestra los hitos más importantes en la vida del proyecto Postgres. 1986: se publicaron varios papers que describían las bases del sistema. 1988: ya se contaba con una versión utilizable. 1989: el grupo publicaba la versión 1 para una pequeña comunidad de usuarios. 1990: se publicaba la versión 2 la cual tenía prácticamente reescrito el sistema de reglas. 1991: publicación de la versión 3, esta añadía la capacidad de múltiples motores de almacenamiento. 1993: crecimiento importante de la comunidad de usuarios, la cual demandaba más características. 1994: después de la publicación de la versión 4, el proyecto terminó y el grupo se disolvió. Después de que el proyecto POSTGRES terminara, dos graduados de la universidad, Andrew Yu y Jolly Chen, comenzaron a trabajar sobre el código de POSTGRES, esto fue posible dado que POSTGRES estaba licenciado bajo la BSD, y lo primero que hicieron fue añadir soporte para el lenguaje SQL a POSTGRES, dado que anteriormente contaba con un intérprete del lenguaje de consultas QUEL (basado en Ingres), creando así el sistema al cual denominaron Postgres95. Para el año 1996 se unieron al proyecto personas ajenas a la Universidad como Marc Fournier de Hub.Org Networking Services, Bruce Momjian y Vadim B. Mikheev quienes proporcionaron el primer servidor de desarrollo no universitario para el esfuerzo de desarrollo de código abierto y comenzaron a trabajar para estabilizar el código de Postgres95. En el año 1996 decidieron cambiar el nombre de Postgres95 de tal modo que refleje la característica del lenguaje SQL y lo terminaron llamando PostgreSQL, cuya primera versión de código abierto fue lanzada el 1 de agosto de La primera versión formal de PostgreSQL (6.0) fue liberada en enero de Desde entonces, muchos desarrolladores entusiastas de los motores de base de datos se unieron al proyecto, coordinaron vía Internet y entre todos comenzaron a incorporar muchas características al motor. Aunque la licencia permitía la comercialización de PostgreSQL, el código no se desarrolló en principio con fines comerciales, algo sorprendente considerando las ventajas que PostgreSQL ofrecía. La principal derivación se originó cuando Paula Hawthtorn (un miembro del equipo original de Ingres que
43 se pasó a Postgres) y Michael Stonebraker conformaron Illustra Information Technologies para comercializar Postgres. En 2000, ex inversionistas de Red Hat crearon la empresa Great Bridge para comercializar PostgreSQL y competir contra proveedores comerciales de bases de datos. Great Bridge auspició a varios desarrolladores de PostgreSQL y donó recursos de vuelta a la comunidad, pero a fines de 2001 cerró debido a la dura competencia de compañías como Red Hat y pobres condiciones del mercado. En 2001, Command Prompt, Inc. lanzó Mammonth PostgreSQL, la más antigua distribución comercial de PostgreSQL. Continúa brindando soporte a la comunidad PostgreSQL a través del auspicio de desarrolladores y proyectos, incluyendo PL/Perl, PL/php y el alojamiento de proyectos de comunidades como PostgreSQL Build Farm. En enero de 2005, PostgreSQL recibió apoyo del proveedor de base de datos Pervasive Software, conocido por su producto Btrieve que se utilizaba en la plataforma Novell Netware. Pervasive anunció soporte comercial y participación comunitaria y logró algo de éxito. Sin embargo, en julio de 2006 dejó el mercado de soporte de PostgreSQL. A mediados de 2005 otras dos compañías anunciaron planes para comercializar PostgreSQL con énfasis en nichos separados de mercados. EnterpriseDB añadió funcionalidades que le permitían a las aplicaciones escritas para trabajar con Oracle ser más fáciles de ejecutar con PostgreSQL. Greenplum contribuyó mejoras directamente orientadas a aplicaciones de Data Warehouse e Inteligencia de negocios, incluyendo el proyecto BizGres. En octubre de 2005, John Loiacono, vicepresidente ejecutivo de software en Sun Microsystems comentó: "No estamos yendo tras el OEM de Microsoft pero estamos viendo a PostgreSQL ahora", aunque no se dieron especificaciones en ese momento. Para noviembre de 2005, Sun Solaris 10 (lanzamiento 6/06) incluía PostgreSQL. En agosto de 2007 EnterpriseDB anunció el Postgres Resource Center y EnterpriseDB Postgres, diseñados para ser una completamente configurada distribución de PostgreSQL incluyendo muchos módulos contribuidos y agregados. EnterpriseDB Postgres fue renombrado Postgres Plus en marzo de El proyecto PostgreSQL continúa haciendo lanzamientos principales anualmente y lanzamientos menores de reparación de bugs, todos disponibles bajo la licencia BSD, y basados en contribuciones de proveedores comerciales, empresas aportantes y programadores de código abierto mayormente Características de PostGreSQL A continuación se enumeran las principales características de este gestor de bases de datos: Alta concurrencia Mediante un sistema denominado MVCC (Acceso concurrente multiversión, por sus siglas en inglés) PostgreSQL permite que mientras un proceso escribe en una tabla, otros accedan a la misma tabla sin necesidad de bloqueos. Cada usuario obtiene una visión consistente de lo último a lo que se le hizo commit. Esta estrategia es superior al uso de bloqueos por tabla o por filas común en otras bases, eliminando la necesidad del uso de bloqueos explícitos.
44 Amplia variedad de tipos nativos PostgreSQL provee nativamente soporte para: Números de precisión arbitraria. Texto de largo ilimitado. Figuras geométricas (con una variedad de funciones asociadas). Direcciones IP (IPv4 e IPv6). Bloques de direcciones estilo CIDR. Direcciones MAC. Arrays. Adicionalmente los usuarios pueden crear sus propios tipos de datos, los que pueden ser por completo indexables gracias a la infraestructura GiST de PostgreSQL. Algunos ejemplos son los tipos de datos GIS creados por el proyecto PostGIS. Otras características Claves ajenas también denominadas Llaves ajenas o Claves Foráneas (foreign keys). Disparadores (triggers): Un disparador o trigger se define como una acción específica que se realiza de acuerdo a un evento, cuando éste ocurra dentro de la base de datos. En PostgreSQL esto significa la ejecución de un procedimiento almacenado basado en una determinada acción sobre una tabla específica. Ahora todos los disparadores se definen por seis características: El nombre del disparador o trigger El momento en que el disparador debe arrancar El evento del disparador deberá activarse sobre... La tabla donde el disparador se activará La frecuencia de la ejecución La función que podría ser llamada Entonces combinando estas seis características, PostgreSQL le permitirá crear una amplia funcionalidad a través de su sistema de activación de disparadores (triggers). Vistas. Integridad transaccional. Herencia de tablas. Tipos de datos y operaciones geométricas. Soporte para transacciones distribuidas. Permite a PostgreSQL integrase en un sistema distribuido formado por varios recursos (p.ej, una base de datos PostgreSQL, otra Oracle, una cola de mensajes IBM MQ JMS y un ERP SAP) gestionado por un servidor de aplicaciones donde el éxito ("commit") de la transacción goblal es el resultado del éxito de las transacciones locales. Más información en inglés en thread_id=21385#95297 y en 1. Implementación del estándar SQL92/SQL Soporta distintos tipos de datos: además del soporte para los tipos base, también soporta datos de tipo fecha, monetarios, elementos gráficos, datos sobre redes (MAC, IP...), cadenas de bits, etc. También permite la creación de tipos propios.
45 3. Incorpora una estructura de datos array. 4. Incorpora funciones de diversa índole: manejo de fechas, geométricas, orientadas a operaciones con redes, etc. 5. Permite la declaración de funciones propias, así como la definición de disparadores. 6. Soporta el uso de índices, reglas y vistas. 7. Incluye herencia entre tablas (aunque no entre objetos, ya que no existen), por lo que a este gestor de bases de datos se le incluye entre los gestores objeto-relacionales. 8. Permite la gestión de diferentes usuarios, como también los permisos asignados a cada uno de ellos Lo mejor de PostGreSQL... Las características positivas que posee este gestor según las opiniones más comunes en Internet, son: 1. Posee una gran escalabilidad. Es capaz de ajustarse al número de CPUs y a la cantidad de memoria que posee el sistema de forma óptima, haciéndole capaz de soportar una mayor cantidad de peticiones simultáneas de manera correcta (en algunos benchmarks se dice que ha llegado a soportar el triple de carga de lo que soporta MySQL). 2. Implementa el uso de rollback's, subconsultas y transacciones, haciendo su funcionamiento mucho más eficaz, y ofreciendo soluciones en campos en las que MySQL no podría. 3. Tiene la capacidad de comprobar la integridad referencial, así como también la de almacenar procedimientos en la propia base de datos, equiparándolo con los gestores de bases de datos de alto nivel, como puede ser Oracle. Funciones Bloques de código que se ejecutan en el servidor. Pueden ser escritos en varios lenguajes, con la potencia que cada uno de ellos da, desde las operaciones básicas de programación, tales como bifurcaciones y bucles, hasta las complejidades de la programación orientada a objetos o la programación funcional. Triggers Los disparadores (triggers en inglés) son funciones enlazadas a operaciones sobre los datos. Algunos de los lenguajes que se pueden usar son los siguientes: Un lenguaje propio llamado PL/PgSQL (similar al PL/SQL de oracle). C. C++. Java PL/Java web. PL/Perl. plphp. PL/Python. PL/Ruby.
46 PL/sh. PL/Tcl. PL/Scheme. Lenguaje para aplicaciones estadísticas R por medio de PL/R. PostgreSQL soporta funciones que retornan "filas", donde la salida puede tratarse como un conjunto de valores que pueden ser tratados igual a una fila retornada por una consulta (query en inglés). Las funciones pueden ser definidas para ejecutarse con los derechos del usuario ejecutor o con los derechos de un usuario previamente definido. El concepto de funciones, en otros DBMS, son muchas veces referidas como "procedimientos almacenados" (stored procedures en inglés). Triggers (disparadores) Postgres tiene algunas interfaces cliente como Perl, Tcl, Python y C, así como dos Lenguajes Procedurales (PL). También es posible llamar a funciones C como acciones trigger. Notar que los eventos trigger a nivel STATEMENT no están soportados en la versión actual. Actualmente es posible especificar BEFORE o AFTER en los INSERT, DELETE o UPDATE de un registro como un evento trigger. Creación de Triggers Si un evento trigger ocurre, el administrador de triggers (llamado Ejecutor) inicializa la estructura global TriggerData *CurrentTriggerData (descrita más abajo) y llama a la función trigger para procesar el evento. La función trigger debe ser creada antes que el trigger, y debe hacerse como una función sin argumentos, y códigos de retorno opacos. La sintaxis para la creación de triggers es la siguiente: CREATE TRIGGER <trigger name> <BEFORE AFTER> <INSERT DELETE UPDATE> ON <relation name> FOR EACH <ROW STATEMENT> EXECUTE PROCEDURE <procedure name> (<function args> El nombre del trigger se usará si se desea eliminar el trigger. Se usa como argumento del comando DROP TRIGGER. La palabra siguiente determina si la función debe ser llamada antes (BEFORE) o después (AFTER) del evento. El siguiente elemento del comando determina en que evento/s será llamada la función. Es posible especificar múltiples eventos utilizado el operador OR. El nombre de la relación (relation name) determinará la tabla afectada por el evento. La instrucción FOR EACH determina si el trigger se ejecutará para cada fila afectada o bien antes (o después) de que la secuencia se haya completado. El nombre del procedimiento (procedure name) es la función C llamada.
47 Los argumentos son pasados a la función en la estructura CurrentTriggerData. El propósito de pasar los argumentos a la función es permitir a triggers diferentes con requisitos similares llamar a la misma función. Además, la función puede ser utilizada para disparar distintas relaciones (estas funciones son llamadas "general trigger funcions"). Como ejemplo de utilización de lo descrito, se puede hacer una funci ón general que toma como argumentos dos nombres de campo e inserta el nombre del usuario y la fecha (timestamp) actuales en ellos. Esto permite, por ejemplo, utilizar los triggers en los eventos INSERT para realizar un seguimiento automático de la creación de registros en una tabla de transacciones. Se podría utilizar también para registrar actualizaciones si es utilizado en un evento UPDATE. Las funciones trigger retornan un área de tuplas (HeapTuple) al ejecutor. Esto es ignorado para trigger lanzados tras (AFTER) una operación INSERT, DELETE o UPDATE, pero permite lo siguiente a los triggers BEFORE: - retornar NULL e ignorar la operación para la tupla actual (y de este modo la tupla no será insertada/actualizada/borrada - devolver un puntero a otra tupla (solo en eventos INSERT y UPDATE) que serán insertados (como la nueva versión de la tupla actualizada en caso de UPDATE) en lugar de la tupla original. Notar que no hay inicialización por parte del CREATE TRIGGER handler. Esto será cambiado en el futuro. Además, si m ás de un trigger es definido para el mismo evento en la misma relación, el orden de ejecución de los triggers es impredecible. Esto puede ser cambiado en el futuro. Si una función trigger ejecuta consultas SQL (utilizando SPI) entonces estas funciones pueden disparar nuevos triggers. Esto es conocido como triggers en cascada. No hay ninguna limitación explicita en cuanto al número de niveles de cascada. Si un trigger es lanzado por un INSERT e inserta una nueva tupla en la misma relación, el trigger será llamado de nuevo (por el nuevo INSERT). Actualmente, no se proporciona ningún mecanismo de sincronización (etc) para estos casos pero esto puede cambiar. Por el momento, existe una función llamada funny_dup17() en los tests de regresión que utiliza algunas técnicas para parar la recursividad (cascada) en si misma... Interacción con el Trigger Manager Como se ha mencionado, cuando una función es llamada por el administrador de triggers (trigger manager), la estructura TriggerData *CurrentTriggerData no es NULL y se inicializa. Por lo cual es mejor verificar que CurrentTriggerData no sea NULL al principio y asignar el valor NULL justo después de obtener la informaci ón para evitar llamadas a la función trigger que no procedan del administrador de triggers. La estructura TriggerData se define en src/include/commands/trigger.h: typedef struct TriggerData { TriggerEvent tg_event; Relation
48 tg_relation; HeapTuple tg_trigtuple; HeapTuple tg_newtuple; Trigger *tg_trigger; } TriggerData; tg_event describe los eventos para los que la función es llamada. Puede utilizar las siguientes macros para examinar tg_event: TRIGGER_FIRED_BEFORE(event) devuelve TRUE si el trigger se disparó antes; TRIGGER_FIRED_AFTER(event) devuelve TRUE si se disparó después; TRIGGER_FIRED_FOR_ROW(event) devuelve TRUE si el trigger se disparó para un evento a nivel de fila; TRIGGER_FIRED_FOR_STATEMENT(event) devuelve TRUE si el trigger se disparó para un evento a nivel de sentencia. TRIGGER_FIRED_BY_INSERT(event) devuelve TRUE si fue disparado por un INSERT; TRIGGER_FIRED_BY_DELETE(event) devuelve TRUE si fue disparado por un DELETE; TRIGGER_FIRED_BY_UPDATE(event) devuelve TRUE si fue disparado por un UPDATE. tg_relation es un puntero a una estructura que describe la relación disparadora. Mirar en src/include/utils/rel.h para ver detalles sobre esta estructura. Lo más interesante es tg_relation->rd_att (descriptor de las tuplas de la relación) y tg_relation->rd_rel->relname (nombre de la relación. No es un char*, sino NameData. Utilizar SPI_getrelname(tg_relation) para obtener char* si se necesita una copia del nombre). tg_trigtuple es un puntero a la tupla por la que tupla que se está insertando (en un actualizando (UPDATE). En caso de un INSERT/DELETE esto es no se desea reemplazar la tupla con tg_newtuple es un puntero a la nueva tupla en caso de UPDATE y NULL si es para un INSERT o un DELETE. Esto es lo que debe devolverse al Ejecutor en el caso de un UPDATE si no se desea reemplazar la tupla por otra o ignorar la operación. tg_trigger es un puntero a la estructura Trigger definida en src/include/utils/rel.h: typedef struct Trigger {
49 es disparado el trigger, esto es, la INSERT), borrando (DELETE) o lo que se debe devolver al Ejecutor si otra (INSERT) o ignorar la operación. tg_trigger es un puntero a la estructura Trigger definida en src/include/utils/rel.h: typedef struct Trigger { Oid char Oid FmgrInfo int16 bool bool bool bool int16 int16 char } Trigger; tgname es el nombre del trigger, tgnargs es el número de argumentos en tgargs, tgargs es un array de punteros a los argumentos especificados en el CREATE TRIGGER. Otros miembros son exclusivamente para uso interno. tgoid; *tgname; tgfoid; tgfunc; tgtype; tgenabled; tgisconstraint; tgdeferrable; tginitdeferred; tgnargs; tgattr[func_max_args]; **tgargs; } Trigger; tgname es el nombre del trigger, tgnargs es el número de argumentos en tgargs, tgargs es un array de punteros a los argumentos especificados en el CREATE TRIGGER. Otros miembros son exclusivamente para uso interno. Visibilidad de Cambios en Datos
50 Regla de visibilidad de cambios en Postgres: durante la ejecución de una consulta, los cambios realizados por ella misma (vía funciones SQL O SPI, o mediante triggers) le son invisibles. Por ejemplo, en la consulta INSERT INTO a SELECT * FROM a las tuplas insertadas son invisibles para el propio SELECT. En efecto, esto duplica la tabla dentro de sí misma (sujeto a las reglas de índice único, por supuesto) sin recursividad. Pero hay que recordar esto sobre visibilidad en la documentación de SPI: Los cambios hechos por la consulta Q son visibles por las consultas que empiezan tras la consulta Q, no importa si son iniciados desde Q (durante su ejecución) o una vez ha acabado. Esto es válido también para los triggers, así mientras se inserta una tupla (tg_trigtuple) no es visible a las consultas en un trigger BEFORE, mientras que esta tupla (recién insertada) es visible a las consultas de un trigger AFTER, y para las consultas en triggers BEFORE/AFTER lanzados con posterioridad! Ejemplos Hay ejemplos más complejos en src/test/regress/regress.c y en contrig/spi. He aquí un ejemplo muy sencillo sobre el uso de triggers. La función trigf devuelve el número de tuplas en la relación ttest e ignora la operaci ón si la consulta intenta insertar NULL en x (i.e - actúa como una restricción NOT NULL pero no aborta la transacción). #include "executor/spi.h" #include "commands/trigger.h" HeapTuple HeapTuple trigf() { TupleDesc HeapTuple char bool bool int /* Necesario para trabajar con SPI */ /* -"- y triggers */ trigf(void
51 tupdesc; rettuple; *when; checknull = false; isnull; ret, i; if (!CurrentTriggerData) elog(warn, "trigf: triggers sin inicializar" /* tupla para devolver al Ejecutor */ if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) rettuple = CurrentTriggerData->tg_newtuple; else rettuple = CurrentTriggerData->tg_trigtuple; /* comprobar NULLs? */ if (!TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event) && TRIGGER_FIRED_BEFORE(CurrentTriggerData->tg_event)) checknull = true; if (TRIGGER_FIRED_BEFORE(CurrentTriggerData->tg_event)) when = "antes "; else when = "después "; tupdesc = CurrentTriggerData->tg_relation->rd_att; CurrentTriggerData = NULL; /* Conexión al gestor SPI */ if ((ret = SPI_connect()) < 0) elog(warn, "trigf (lanzado %s): SPI_connect devolvió %d", when, ret /* Obtiene el número de tuplas en la relación */ ret = SPI_exec("select count(*) from ttest", 0 if (ret < 0) elog(warn, "trigf (lanzado %s): SPI_exec devolvió %d", when, ret i = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull elog (NOTICE, "trigf (lanzado %s): hay %d tuplas en ttest", when, i SPI_finish( if (checknull) { i = SPI_getbinval(rettuple, tupdesc, 1, &isnull if (isnull)
52 rettuple = NULL; } return (rettuple } Ahora, compila y create table ttest (x int4 create function trigf () returns opaque as '...path_to_so' language 'c'; vac=> create for each row CREATE vac=> create for each row CREATE vac=> insert NOTICE:trigf INSERT Insertion skipped and AFTER trigger is not fired vac=> select * from ttest; x - (0 rows) vac=> insert into ttest values (1 NOTICE:trigf (fired before): there are 0 tuples in ttest NOTICE:trigf (fired after ): there are 1 tuples in ttest ^^^^^^^^ remember what we said about visibility. INSERT vac=> select * from ttest; x - 1 (1 row) vac=> insert into ttest select x * 2 from ttest; NOTICE:trigf (fired before): there are 1 tuples in ttest NOTICE:trigf (fired after ): there are 2 tuples in ttest ^^^^^^^^ remember what we said about visibility. INSERT vac=> select * from ttest; x - 1
53 2 (2 rows) vac=> update NOTICE:trigf UPDATE 0 vac=> update NOTICE:trigf NOTICE:trigf trigger tbefore before insert or update or delete on ttest execute procedure trigf( trigger tafter after insert or update or delete on ttest execute procedure trigf( into ttest values (null (fired before): there are 0 tuples in ttest ttest set x = null where x = 2; (fired before): there are 2 tuples in ttest ttest set x = 4 where x = 2; (fired before): there are 2 tuples in ttest (fired after ): there are 2 tuples in ttest UPDATE 1 vac=> select * from ttest; x (2 rows) vac=> delete NOTICE:trigf NOTICE:trigf NOTICE:trigf NOTICE:trigf from ttest; (fired before): (fired after ): (fired before): (fired after ): 2 tuples in 1 tuples in 1 tuples in 0 tuples in
54 ^^^^^^^^ remember what we said there there there there are are are are ttest ttest ttest ttest about visibility. DELETE 2 vac=> select * from ttest; x - (0 rows) Otro ejemplo En esta ocasión, voy a explicar como podemos crear un Trigger en PostgreSQL usando PL/pgSQL. Lo primero que se debe de hacer, es crear una función la cual se encargará de manejar los procedimientos de PL. Esto deberá hacerse con la cuenta de usuario postgres en la base de datos donde vamos a crear el trigger. Por tal motivo abriremos una sesión de postgres con el usuario postgres en nuestra base de datos, la cual para fines de este ejemplo usaré el nombre de javoaxian. javoaxian@darthmaul:~$ psql -U postgres -d javoaxian Ya que estamos en el prompt de postgres, crearemos la función plpgsql_call_handler y le debemos de indicar donde debe encontrar el archivo plpgsql.so, el cual se encuentra situado en el directorio lib donde fue instalado postgresql, que en mi caso esta en /opt/pgsql/lib. javoaxian=# CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS '/opt/pgsql/lib/plpgsql.so' LANGUAGE C; Ahora dejaremos de ser el usuario postgres y nos convertiremos en el dueño de la base de datos, que en mi caso será javoaxian. javoaxian=# \c javoaxian javoaxian
55 Esto nos pedirá el password del usuario javoaxian y una vez que ingresemos éste, nos indicará que estamos conectados a la base de datos con el usuario que indicamos. Password for user javoaxian: You are now connected to database "javoaxian" as user "javoaxian". Ahora que ya ingresamos con nuestro usuario, podemos crear el lenguaje plpgsql en nuestra base de datos y le indicamos la función plpgsql_call_handler que creamos con el usuario postgres. CREATE LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler LANCOMPILER 'PL/pgSQL'; Lo anterior nos mostrará algo similar a esto: NOTICE: using pg_pltemplate information instead of CREATE LANGUAGE parameters CREATE LANGUAGE Creado el lenguaje, procederemos a crear el procedimiento almacenado que llamará el trigger que crearemos. Este procedimiento se encargará de verificar que no se inserten más de 100 registros en una tabla llamada usuario, por tal motivo, deberemos tener creada una tabla llamada usuario y para fines de este post puede estar estructurada de la siguiente manera: CREATE TABLE usuario( id INTEGER NOT NULL PRIMARY KEY, nombre VARCHAR(80) NOT NULL Ahora crearemos el procedimiento: CREATE FUNCTION sp_max_100_registros() RETURNS trigger AS $trigger_max_100_registros$ DECLARE registro RECORD; BEGIN SELECT INTO registro COUNT(*) AS numregistros FROM usuario; IF registro.numregistros < 100 THEN RETURN NEW; ELSE RAISE EXCEPTION 'No pueden existir más de 100 registros en la tabla usuario'; RETURN NULL; END IF; END; $trigger_max_100_registros$ LANGUAGE plpgsql; Como se puede observar en el procedimiento, se le deberá poner un nombre, que en este caso es sp_max_100_registros(), seguido de esto le indicamos que vamos a devolver un tipo de dato trigger y que tendrá el nombre de trigger_max_100_registros entre signos de "$". Posteriormente, declaramos una variable llamada registro en la sección de variables DECLARE y le indicamos que es de tipo RECORD ya que en esta variable se almacenará el resultado de nuestra consulta. Seguido de esta sección, colocamos la sección BEGIN, la cual nos permitirá poner el comportamiente de nuestro procedimiento hasta encontrar una instrucción END que lo finalize.
56 Entre las instrucciones BEGIN y END ejecutaremos una sentencia SELECT que cuenta el número de registros en la tabla usuario. Dicha sentencia cuenta con la opción INTO, ya que es la que permite asignar el resultado a nuestra variable registro. Luego encontraremos un IF con su respectivos THEN, ELSE y END IF, donde preguntamos por medio de la variable registro si obtuvo menos de 100 registros, si la condición es afirmativa, entonces devuelve una variable llamada NEW, la cual indica que puede ser insertado el registro en la tabla usuario, pero en caso contrario, entonces nos devuelve una excepción indicando que no pueden existir más de 100 registros en la tabla usuario. Por último indicamos el nombre del trigger entre signos de "$" que en el ejemplo es: trigger_max_100_registros y el lenguaje del procedimiento, que en este caso es plpgsql. Ya que contamos con el procedimiento almacenado, crearemos nuestro trigger, y para hacer esto, deberemos hacer lo siguiente: CREATE TRIGGER trigger_max_100_registros BEFORE INSERT ON usuario FOR EACH ROW EXECUTE PROCEDURE sp_max_100_registros( La declaración del anterior nos indica que vamos a crear un TRIGGER llamado trigger_max_100_registros, el cual se deberá lanzar antes de realizar un INSERT sobre la tabla usuario para cada registro (FOR EACH ROW), y le indicamos que deberá ejecutar el procedimiento almacenado que creamos, el cual es: sp_max_100_registros(). Ahora ya tenemos creado nuestro trigger y cada vez insertemos un registro, verificará si puede insertar dicho registro. Para borrar nuestro trigger, lo primero que hay que hacer, será ejecutar la siguiente línea: DROP TRIGGER trigger_max_100_registros ON usuario; En la instrucción anterior indicamos el nombre del trigger que queremos borrar y sobre que tabla está referenciada. Una vez que borramos el trigger, también deberemos borrar su procedimiento almacenado, y esto lo haremos de esta forma: DROP FUNCTION sp_max_100_registros( Se puede observar, que en el comando anterior deberémos indicar el nombre del procedimiento y que este debe llevar los paréntesis que abren y cierra. Ahora bien, pondré otro trigger, el cual se encarga de verificar que después de insertar en nuestra tabla usuario un registro cuyo nombre cuente con la palabra luis, ya no permita meter más registros. El procedimiento sería de esta manera: CREATE FUNCTION sp_sin_luis() RETURNS trigger AS $trigger_sin_luis$ BEGIN PERFORM * FROM usuario WHERE UPPER(nombre) LIKE UPPER('%luis%' IF NOT FOUND THEN RAISE NOTICE 'Se insertará el registro';
57 RETURN NEW; ELSE RAISE EXCEPTION 'No se insertará el registro'; RETURN NULL; END IF; END; $trigger_sin_luis$ LANGUAGE plpgsql; Y el trigger: CREATE TRIGGER trigger_sin_luis BEFORE INSERT OR UPDATE ON usuario FOR EACH ROW EXECUTE PROCEDURE sp_sin_luis( Entre las cosas diferentes del procedimiento de este nuevo trigger, es que no definimos la sección DECLARE, aparte en lugar de poner la sentencia SELECT ponemos la palabra PERFORM. La diferencia radica en que PERFORM se usa para cuando hacemos consultas en las cuales no vamos a usar el resultado de ésta. También otra diferencia es en la instrucción IF, ya que usamos la palabra NOT FOUND, la cual sirve para preguntar si no se encontraron registro en la consulta hecha. La última diferencia del procedimiento está dentro del IF, podemos observar que antes de devolver el nuevo registro (RETURN NEW), usamos la instrucción: RAISE NOTICE, y ésta nos permite mandar un mensaje a la salida estandar de notificación. La diferencia en la creación del trigger, es que también indicamos que se ejecute cuando se hagan UPDATE's. Por último, pondré un ejemplo, el cual se encarga de verificar que no se pueda insertar un registro en la tabla usuario que contenga la cadena luis. Procedimiento: CREATE FUNCTION sp_no_luis() RETURNS trigger AS $trigger_no_luis$ BEGIN IF UPPER(NEW.nombre) LIKE '%LUIS%' THEN RAISE EXCEPTION 'El registro contiene el nombre de luis'; RETURN NULL; ELSE RAISE NOTICE 'Se agregará el registro'; RETURN NEW; END IF; END; $trigger_no_luis$ LANGUAGE plpgsql; Trigger: CREATE TRIGGER trigger_no_luis BEFORE INSERT OR UPDATE ON usuario FOR EACH ROW EXECUTE PROCEDURE sp_no_luis(
58 La diferencia en este último, es que usamos la instrucción NEW para hacer la comparación. Esta instrucción contiene el nuevo registro y por consiguiente los datos de los campos ha insertar, los cuales podemos hacer referencia por medio del nombre del campo como se puede observar. Algo IMPORTANTE de mencionar, es que para poder usar la instrucción NEW u otra llamada OLD, es que cuando creemos el trigger, deberemos poner la instrucción FOR EACH ROW, ya que sin esta no se crearán estos elementos.
59 ANEXOS Resolución de Problemas Buscar Información duplicada en un campo de una tabla. Para generar este tipo de consultas lo más sencillo es utilizar el asistente de consultas de Access, editar la sentencia SQL de la consulta y pegarla en nuestro código. No obstante este tipo de consulta se consigue de la siguiente forma: SELECT DISTINCTROW Lista de Campos a Visualizar FROM Tabla WHERE CampoDeBusqueda In (SELECT CampoDeBusqueda FROM Tabla As psud nimo GROUP BY CampoDeBusqueda HAVING Count(*)>1 ) ORDER BY CampoDeBusqueda; Un caso práctico, si deseamos localizar aquellos empleados con igual nombre y visualizar su código correspondiente, la consulta sera la siguiente: SELECT DISTINCTROW Empleados.Nombre, Empleados.IdEmpleado FROM Empleados WHERE Empleados.Nombre In (SELECT Nombre FROM Empleados As Tmp GROUP BY Nombre HAVING Count(*)>1) ORDER BY Empleados.Nombre; Recuperar registros de una tabla que no contengan registros relacionados en otra. Este tipo de consulta se emplea en situaciones tales como saber que productos no se han vendido en un determinado periodo de tiempo, SELECT DISTINCTROW Productos.IdProducto, Productos.Nombre FROM Productos LEFT JOIN Pedidos ON Productos.IdProducto = Pedidos.IdProduct WHERE (Pedidos.IdProducto Is Null) AND (Pedidos.Fecha Between # # And # # La sintaxis es sencilla, se trata de realizar una Unión interna entre dos tablas seleccionadas mediante un LEFT JOIN, establecimiendo como condición que el campo relacionado de la segunda sea Null. Utlizar SQL desde Visual Basic Existen dos tipos de consultas SQL: las consultas de selección (nos devuelven datos) y las consultas de acción (aquellas que no devuelven ningún registro). Ambas pueden ser tratadas en Visual Basic pero de forma diferente. Las consultas de selección se ejecutan recogiendo la información en un recordset previamente definido mediante la instrucción openrecordset(), por ejemplo: Dim SQL as String Dim RS as recordset SQL = "SELECT * FROM Empleados;" Set RS=MiBaseDatos.OpenRecordSet(SQL)
60 Si la consula de selección se encuentra almacenada en una consulta de la base de datos: Set RS=MiBaseDatos.OpenRecordset("MiConsulta") Las consultas de acción, al no devolver ningún registro, no las podemos asignar a ningún recordset, en este caso la forma de ejecutarlas es mediante los m todos Execute y ExecuteSQL (para bases de datos ODBC), por ejemplo: Dim SQL as string SQL = "DELETE * FROM Empleados WHERE Categoria = 'Ordenanza';" MiBaseDatos.Execute SQL Funciones de Visual Basic utilizables en una Instrucción SQL Función Sintaxis Descripción Now Variable= Now Devuelve la fecha y la hora actual del sistema Date Variable=Date Devuelve la fecha actual del sistema Time Variable=Time Devuelve la hora actual del sistema Year Variable=Year(Fecha) Devuelve los cuatro dígitos correspondientes al año de Fecha Month Variable=Month(Fecha) Devuelve el número del mes del parámetro fecha. Day Variable=Day(Fecha) Devuelve el número del día del mes del parámetro fecha. Weekday Variable=Weekday(Fecha) Devuelve un número entero que representa el día de la semana del parámetro fecha. Hour Variable=Hour(Hora) Devuelve un número entre 0 y 23 que representa la hora del parámetro Hora. Minute Variable=Minute(Hora) Devuelve un número entre 0 y 59 que representa los minutos del parámetro hora. Second Variable=Second(Hora) Devuelve un número entre 0 y 59 que representa los segundos del parámetro hora.datepart Esta función devuelve una parte sealada de una fecha concreta. Su sintaxis es: DatePart(Parte, Fecha, ComienzoSemana, ComienzoAño) Parte representa a la porción de fecha que se desea obtener, los posibles valores son: Valor Descripción yyyy año q Trimestre m Mes y día del año d día del mes w día de la semana ww Semana del año h Hora m Minutos s Segundos ComienzoSemana indica el primer día de la semana. Los posibles valores son: Valor Descripción 0 Utiliza el valor por defecto del sistema 1 Domingo (Valor predeterminado) 2 Lunes 3 Martes 4 Miércoles 5 Jueves 6 Viernes 7 Sábado ComienzoAño indica cual es la primera semana del año; los posibles valores son: Valor Descripción 0 Valor del sistema 1 Comienza el año el 1 de enero (valor predeterminado). 2 Empieza con la semana que tenga al memos cuatro días en el nuevo año. 3 Empieza con la semana que está contenida completamente en el nuevo año. Evaluar valores antes de ejecutar la Consuta. Dentro de una sentencia SQL podemos emplear la función iif para indicar las condiciones de búsqueda. La sintaxis de la función iif es la siguiente: iif(expresion,valor1,valor2)
61 En donde expresión es la sentencia que evaluamos; si expresión es verdadera entonces se devuelve Valor1, si expresión es falsa se devuelve Valor2. SELECT * Total FROM Empleados WHERE Apellido = iff(tx_apellido.text <> '', TX_Apellido.Text, *) ; Supongamos que en un formulario tenemos una casilla de texto llamanda TX_Apellido. Si cuando ejecutamos esta consulta la casilla contiene algún valor se devuelven todos los empleados cuyo apellido coincida con el texto de la casilla, en caso contrario se devuelven todos los empleados. SELECT Fecha, Producto, Cantidad, (iif(codigopostal>=28000 And CodigoPostal <=28999,'Caracas','El Nacional')) AS Destino FROM Pedidos; Esta consulta devuelve los campos Fecha, Nombre del Producto y Cantidad de la tabla pedidos, añadiendo un campo al final con el valor Caracas si el código posta está dentro del intervalo, en caso contrario devuelve Nacional. Un Pequeño Manual de Estilo Siempre es bueno intentar hacer las cosas de igual modo para que el mantenimiento y la revisión nos sea una labor lo más sencilla posible. En lo que a mi respecta utilizo las siguiente normas a la hora de elaborar sentencias SQL: Las cláusulas siempre las escribo con mayúsculas. Los operadores Lógicos de sentencias siempre con mayúsculas. Las operaciones siempre la primera letra con mayúsculas y el resto en minúsculas. Los operadores Lógicos incluidos en otros operadores la primera letra con mayúsculas y el resto con minúsculas. Los Nombres de las Tablas, Campos y Consultas, los escribo siempre la primera letra con mayúsculas y el resto con minúsculas, en algunos casos utilizo el carácter "_" para definir mejor el nombre: Detalles_Pedidos. Aunque con el motor Jet se pueden utilizar acentos y espacios en blanco para nombrar los campos, las tablas y las consultas no los utilizo porque cuando se exportar tablas a otros sistemas los acentos y los espacios en blanco pueden producir errores innecesarios. Recuerda siempre que si utilizas espacios en blanco para llamar tablas o consultas cada vez que hagas referencias a ellos en una consulta debes incluir sus nombres entre corchetes. SELECT [ID de Pedido], [Nombre del Producto], Cantidad FROM [Detalles del Pedido];
62 Ejercicios 1 Administración de usuarios y grupos 1. Crear los usuarios user1 y user2; 2. Modifique esos usuarios, dando las siguientes claves: user1, y user2, Yoe_ Establecer el estilo de fecha SET DATESTYLE TO ISO, GERMAN; 4. Mostrar el estilo con: SHOW DATESTYLE; 5. Qué pasa si borra la base de datos? 6. Qué pasa si borra el esquema (SCHEMA), da error o borra las tablas? 2 - Crear una tabla (create table) Primer problema: Necesita almacenar los datos de sus amigos en una tabla. Los datos que guarda son: apellido, nombre, domicilio y teléfono. 1- Intente crear una tabla llamada "/agenda": create table /agenda( apellido varchar(30), nombre varchar(20), domicilio varchar(30), telefono varchar(11) aparece un mensaje de error porque usa un caracter no válido ("/") para el nombre. 2- Cree una tabla llamada "agenda", debe tener los siguientes campos: apellido, varchar(30 nombre, varchar(20 domicilio, varchar (30) y telefono, varchar(11). 3- Intente crearla nuevamente. Aparece mensaje de error. 4- Visualice la estructura de la tabla "agenda". 5- Elimine la tabla. 6- Intente eliminar nuevamente la tabla. Debe aparecer un mensaje de error. Segundo problema: Necesita almacenar información referente a los libros de su biblioteca personal. Los datos que guardará serán: título del libro, nombre del autor y nombre de la editorial. 1- Cree una tabla llamada "libros". Debe definirse con los siguientes campos: titulo, varchar(20
63 autor, varchar(30) y editorial, varchar(15). 2- Intente crearla nuevamente. Aparece mensaje de error. 3- Visualice la estructura de la tabla "libros". 4- Elimine la tabla. 5- Intente eliminar la tabla nuevamente. 3 - Insertar y recuperar registros de una tabla (insert into - select) Primer problema: Trabaje con la tabla "agenda" que almacena información de sus amigos. 1- Cree una tabla llamada "agenda". Debe tener los siguientes campos: apellido (cadena de 30), nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11) 2 - Visualice la estructura de la tabla "agenda". 3- Ingrese los siguientes registros: insert into agenda (apellido, nombre, domicilio, telefono) values ('Moreno','Alberto','Colon 123',' ' insert into agenda (apellido,nombre, domicilio, telefono) values ('Torres','Juan','Avellaneda 135',' ' 4- Seleccione todos los registros de la tabla: select * from agenda; 5- Elimine la tabla "agenda": 6- Intente eliminar la tabla nuevamente (aparece un mensaje de error) Segundo problema: Trabaje con la tabla "libros" que almacena los datos de los libros de su propia biblioteca. 1- Cree una tabla llamada "libros". Debe definirse con los siguientes campos: titulo (cadena de 20), autor (cadena de 30) y editorial (cadena de 15). 2- Visualice la estructura de la tabla "libros". 3- Ingrese los siguientes registros: insert into libros (titulo,autor,editorial) values ('El aleph','borges','planeta' insert into libros (titulo,autor,editorial) values ('Martin Fierro','Jose Hernandez','Emece' insert into libros (titulo,autor,editorial) values ('Aprenda PHP','Mario Molina','Emece' 4- Muestre todos los registros (select).
64 4 - Tipos de datos básicos Primer problema: Un videoclub que alquila películas en video almacena la información de sus películas en una tabla llamada "peliculas"; para cada película necesita los siguientes datos: -nombre, cadena de caracteres de 20 de longitud, -actor, cadena de caracteres de 20 de longitud, -duración, valor numérico entero. -cantidad de copias: valor entero. 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo. 2- Vea la estructura de la tabla. 3- Ingrese los siguientes registros: insert into peliculas (nombre, actor, duracion, cantidad) values ('Mision imposible','tom Cruise',128,3 insert into peliculas (nombre, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',130,2 insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','julia Roberts',118,3 insert into peliculas (nombre, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',110,2 4- Muestre todos los registros. Segundo problema: Una empresa almacena los datos de sus empleados en una tabla "empleados" que guarda los siguientes datos: nombre, documento, sexo, domicilio, sueldobasico. 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo. 2- Vea la estructura de la tabla: 3- Ingrese algunos registros: insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Juan Perez',' ','m','Sarmiento 123',500 insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Ana Acosta',' ','f','Colon 134',650 insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Bartolome Barrios',' ','m','Urquiza 479', Seleccione todos los registros. 5 - Recuperar algunos campos (select) Primer problema: Un videoclub que alquila películas en video almacena la información de sus películas en alquiler en una tabla llamada "peliculas". 1- Cree la tabla:
65 create table peliculas( titulo varchar(20), actor varchar(20), duracion integer, cantidad integer 2- Vea la estructura de la tabla. 3- Ingrese alos siguientes registros: insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible','tom Cruise',180,3 insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',190,2 insert into peliculas (titulo, actor, duracion, cantidad) values ('Mujer bonita','julia Roberts',118,3 insert into peliculas (titulo, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',110,2 4- Realice un "select" mostrando solamente el título y actor de todas las películas 5- Muestre el título y duración de todas las peliculas 6- Muestre el título y la cantidad de copias Segundo problema: Una empresa almacena los datos de sus empleados en una tabla llamada "empleados". 1- Cree la tabla: create table empleados( nombre varchar(20), documento varchar(8), sexo varchar(1), domicilio varchar(30), sueldobasico float 2- Vea la estructura de la tabla 3- Ingrese algunos registros: insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Juan Juarez',' ','m','Sarmiento 123',500 insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Ana Acosta',' ','f','Colon 134',700 insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Carlos Caseres',' ','m','Urquiza 479', Muestre todos los datos de los empleados 5- Muestre el nombre, documento y domicilio de los empleados 6- Realice un "select" mostrando el documento, sexo y sueldo básico de todos los empleados
66 6 - Recuperar algunos registros (where) Trabaje con la tabla "agenda" en la que registra los datos de sus amigos. 1- Cree la tabla, con los siguientes campos: apellido (cadena de 30), nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11). 2- Visualice la estructura de la tabla "agenda". 3- Ingrese los siguientes registros: Acosta, Ana, Colon 123, ; Bustamante, Betina, Avellaneda 135, ; Lopez, Hector, Salta 545, ; Lopez, Luis, Urquiza 333, ; Lopez, Marisa, Urquiza 333, Seleccione todos los registros de la tabla 5- Seleccione el registro cuyo nombre sea "Marisa" (1 registro) 6- Seleccione los nombres y domicilios de quienes tengan apellido igual a "Lopez" (3 registros) 7- Muestre el nombre de quienes tengan el teléfono " " (2 registros) Segundo problema: Trabaje con la tabla "libros" de una librería que guarda información referente a sus libros disponibles para la venta. 1- Cree la tabla "libros". Debe tener la siguiente estructura: create table libros ( titulo varchar(20), autor varchar(30), editorial varchar(15) 2- Visualice la estructura de la tabla "libros". 3- Ingrese los siguientes registros: El aleph,borges,emece; Martin Fierro,Jose Hernandez,Emece; Martin Fierro,Jose Hernandez,Planeta; Aprenda PHP,Mario Molina,Siglo XXI; 4- Seleccione los registros cuyo autor sea "Borges" (1 registro) 5- Seleccione los títulos de los libros cuya editorial sea "Emece" (2 registros) 6- Seleccione los nombres de las editoriales de los libros cuyo titulo sea "Martin Fierro" (2 registros)
67 7 - Operadores relacionales Primer problema: Un comercio que vende artículos de computación registra los datos de sus artículos en una tabla con ese nombre. 1- Cree la tabla, con la siguiente estructura: create table articulos( codigo integer, nombre varchar(20), descripcion varchar(30), precio float, cantidad integer 2- Ingrese algunos registros: insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (1,'impresora','Epson Stylus C45',400.80,20 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (2,'impresora','Epson Stylus C85',500,30 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (3,'monitor','Samsung 14',800,10 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (4,'teclado','ingles Biswal',100,50 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (5,'teclado','español Biswal',90,50 3- Seleccione los datos de las impresoras (2 registros) 4- Seleccione los artículos cuyo precio sea mayor o igual a 400 (3 registros) 5- Seleccione el código y nombre de los artículos cuya cantidad sea menor a 30 (2 registros) 6- Selecciones el nombre y descripción de los artículos que NO cuesten $100 (4 registros) Segundo problema: Un video club que alquila películas en video almacena la información de sus películas en alquiler en una tabla denominada "peliculas". 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table peliculas( titulo varchar(20), actor varchar(20), duracion integer, cantidad integer 2- Ingrese los siguientes registros: insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible','tom Cruise',120,3 insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',180,4
68 insert into peliculas (titulo, actor, duracion, cantidad) values ('Mujer bonita','julia R.',90,1 insert into peliculas (titulo, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',80,2 3- Seleccione las películas cuya duración no supere los 90 minutos (2 registros) 4- Seleccione el título de todas las películas en las que el actor NO sea "Tom Cruise" (2 registros) 5- Muestre todos los campos, excepto "duracion", de todas las películas de las que haya más de 2 copias (2 registros) 8 - Borrar registros (delete) Primer problema: Trabaje con la tabla "agenda" que registra la información referente a sus amigos. 1- Cree la tabla con los siguientes campos: apellido (cadena de 30), nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11): create table agenda( apellido varchar(30), nombre varchar(20), domicilio varchar(30), telefono varchar(11) 2- Ingrese los siguientes registros (insert into): Alvarez,Alberto,Colon 123, , Juarez,Juan,Avellaneda 135, , Lopez,Maria,Urquiza 333, , Lopez,Jose,Urquiza 333, , Salas,Susana,Gral. Paz 1234, Elimine el registro cuyo nombre sea "Juan" (1 registro afectado) 4- Elimine los registros cuyo número telefónico sea igual a " " (2 registros afectados) 5- Muestre la tabla. 6- Elimine todos los registros (2 registros afectados) 7- Muestre la tabla. Segundo problema: Un comercio que vende artículos de computación registra los datos de sus artículos en una tabla con ese nombre. 1- Cree la tabla, con la siguiente estructura: create table articulos( codigo integer, nombre varchar(20), descripcion varchar(30), precio float, cantidad integer
69 2- Ingrese algunos registros: insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (1,'impresora','Epson Stylus C45',400.80,20 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (2,'impresora','Epson Stylus C85',500,30 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (3,'monitor','Samsung 14',800,10 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (4,'teclado','ingles Biswal',100,50 insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (5,'teclado','español Biswal',90,50 3- Elimine los artículos cuyo precio sea mayor o igual a 500 (2 registros) 4- Elimine todas las impresoras (1 registro) 5- Elimine todos los artículos cuyo código sea diferente a 4 (1 registro) 6- Mostrar la tabla después que borra cada registro. 9 - Actualizar registros (update) Trabaje con la tabla "agenda" que almacena los datos de sus amigos. 1- Cree la tabla: create table agenda( apellido varchar(30), nombre varchar(20), domicilio varchar(30), telefono varchar(11) 2- Ingrese los siguientes registros: insert into agenda (apellido,nombre,domicilio,telefono) values ('Acosta','Alberto','Colon 123',' ' insert into agenda (apellido,nombre,domicilio,telefono) values ('Juarez','Juan','Avellaneda 135',' ' insert into agenda (apellido,nombre,domicilio,telefono) values ('Lopez','Maria','Urquiza 333',' ' insert into agenda (apellido,nombre,domicilio,telefono) values ('Lopez','Jose','Urquiza 333',' ' insert into agenda (apellido,nombre,domicilio,telefono) values ('Suarez','Susana','Gral. Paz 1234',' ' 3- Modifique el registro cuyo nombre sea "Juan" por "Juan Jose" (1 registro afectado) 4- Actualice los registros cuyo número telefónico sea igual a " " por " " (2 registros afectados) 5- Actualice los registros que tengan en el campo "nombre" el valor "Juan" por "Juan Jose" (ningún registro afectado porque ninguno cumple con la condición del "where") 6 - Luego de cada actualización ejecute un select que muestre todos los registros
70 de la tabla. Segundo problema: Trabaje con la tabla "libros" de una librería. 1- Créela con los siguientes campos: titulo (cadena de 30 caracteres de longitud), autor (cadena de 20), editorial (cadena de 15) y precio (float): create table libros ( titulo varchar(30), autor varchar(20), editorial varchar(15), precio float 2- Ingrese los siguientes registros: insert into libros (titulo, autor, editorial, precio) values ('El aleph','borges','emece',25.00 insert into libros (titulo, autor, editorial, precio) values ('Martin Fierro','Jose Hernandez','Planeta',35.50 insert into libros (titulo, autor, editorial, precio) values ('Aprenda PHP','Mario Molina','Emece',45.50 insert into libros (titulo, autor, editorial, precio) values ('Cervantes y el quijote','borges','emece',25 insert into libros (titulo, autor, editorial, precio) values ('Matematica estas ahi','paenza','siglo XXI',15 3- Muestre todos los registros (5 registros): 4- Modifique los registros cuyo autor sea igual a "Paenza", por "Adrian Paenza" (1 registro afectado) 5- Nuevamente, modifique los registros cuyo autor sea igual a "Paenza", por "Adrian Paenza" (ningún registro afectado porque ninguno cumple la condición) 6- Actualice el precio del libro de "Mario Molina" a 27 pesos (1 registro afectado): update libros set precio=27 where autor='mario Molina'; 7- Actualice el valor del campo "editorial" por "Emece S.A.", para todos los registros cuya editorial sea igual a "Emece" (3 registros afectados) 8 - Luego de cada actualización ejecute un select que muestre todos los registros de la tabla Valores null (is null) Primer problema: Una farmacia guarda información referente a sus medicamentos en una tabla llamada "medicamentos". 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo integer not null, nombre varchar(20) not null,
71 laboratorio varchar(20), precio float, cantidad integer not null 2- Visualice la estructura de la tabla "medicamentos" indicando si el campo admite valores null. 3- Ingrese algunos registros con valores "null" para los campos que lo admitan: insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(1,'sertal gotas',null,null,100 insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(2,'sertal compuesto',null,8.90,150 insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(3,'buscapina','roche',null, Vea todos los registros: 5- Ingrese un registro con valor "0" para el precio y cadena vacía para el laboratorio. 6- Ingrese un registro con valor "0" para el código y cantidad y cadena vacía para el nombre. 7- Muestre todos los registros. 8- Intente ingresar un registro con valor nulo para un campo que no lo admite (aparece un mensaje de error): 9- Recupere los registros que contengan valor "null" en el campo "laboratorio", luego los que tengan una cadena vacía en el mismo campo. Note que el resultado es diferente. 10- Recupere los registros que contengan valor "null" en el campo "precio", luego los que tengan el valor 0 en el mismo campo. Note que el resultado es distinto. 11- Recupere los registros cuyo laboratorio no contenga una cadena vacía, luego los que sean distintos de "null". Note que la salida de la primera sentencia no muestra los registros con cadenas vacías y tampoco los que tienen valor nulo; el resultado de la segunda sentencia muestra los registros con valor para el campo laboratorio (incluso cadena vacía). 12- Recupere los registros cuyo precio sea distinto de 0, luego los que sean distintos de "null". Note que la salida de la primera sentencia no muestra los registros con valor 0 y tampoco los que tienen valor nulo; el resultado de la segunda sentencia muestra los registros con valor para el campo precio (incluso el valor 0). Segundo problema: Trabaje con la tabla que almacena los datos sobre películas, llamada "peliculas". 1- Créela con la siguiente estructura: create table peliculas( codigo int not null, titulo varchar(40) not null, actor varchar(20), duracion int
72 2- Visualice la estructura de la tabla note que el campo "codigo" y "titulo", en la columna "ins_nullable" muestra "NO" y los otros campos "YES". 3- Ingrese los siguientes registros: insert into peliculas (codigo,titulo,actor,duracion) values(1,'mision imposible','tom Cruise',120 insert into peliculas (codigo,titulo,actor,duracion) values(2,'harry Potter y la piedra filosofal',null,180 insert into peliculas (codigo,titulo,actor,duracion) values(3,'harry Potter y la camara secreta','daniel R.',null insert into peliculas (codigo,titulo,actor,duracion) values(0,'mision imposible 2','',150 insert into peliculas (codigo,titulo,actor,duracion) values(4,'','l. Di Caprio',220 insert into peliculas (codigo,titulo,actor,duracion) values(5,'mujer bonita','r. Gere-J. Roberts',0 4- Recupere todos los registros para ver cómo PostgreSQL los almacenó: select * from peliculas; 5- Intente ingresar un registro con valor nulo para campos que no lo admiten (aparece un mensaje de error) 6- Muestre los registros con valor nulo en el campo "actor" y luego los que guardan una cadena vacía (note que la salida es distinta) (1 registro) 7- Modifique los registros que tengan valor de duración desconocido (nulo) por "120" (1 registro actualizado) 8- Coloque 'Desconocido' en el campo "actor" en los registros que tengan una cadena vacía en dicho campo (1 registro afectado) 9- Muestre todos los registros. Note que el cambio anterior no afectó a los registros con valor nulo en el campo "actor". 10- Elimine los registros cuyo título sea una cadena vacía (1 registro) 12 - Clave primaria Primer problema: Trabaje con la tabla "libros" de una librería. 1- Créela con los siguientes campos, estableciendo como clave primaria el campo "codigo": create table libros( codigo int not null, titulo varchar(40) not null, autor varchar(20), editorial varchar(15), primary key(codigo) 2- Ingrese los siguientes registros: insert into libros (codigo,titulo,autor,editorial)
73 values (1,'El aleph','borges','emece' insert into libros (codigo,titulo,autor,editorial) values (2,'Martin Fierro','Jose Hernandez','Planeta' insert into libros (codigo,titulo,autor,editorial) values (3,'Aprenda PHP','Mario Molina','Nuevo Siglo' 3- Ingrese un registro con código repetido (aparece un mensaje de error) 4- Intente ingresar el valor "null" en el campo "codigo" 5- Intente actualizar el código del libro "Martin Fierro" a "1" (mensaje de error) Segundo problema: Un instituto de enseñanza almacena los datos de sus estudiantes en una tabla llamada "alumnos". 1- Cree la tabla con la siguiente estructura intentando establecer 2 campos como clave primaria, el campo "documento" y "legajo" (no lo permite): create table alumnos( legajo varchar(4) not null, documento varchar(8), nombre varchar(30), domicilio varchar(30), primary key(documento), primary key(legajo) 2- Cree la tabla estableciendo como clave primaria el campo "documento": create table alumnos( legajo varchar(4) not null, documento varchar(8), nombre varchar(30), domicilio varchar(30), primary key(documento) 3- Verifique que el campo "documento" no admite valores nulos 4- Ingrese los siguientes registros: insert into alumnos (legajo,documento,nombre,domicilio) values('a233',' ','perez Mariana','Colon 234' insert into alumnos (legajo,documento,nombre,domicilio) values('a567',' ','morales Marcos','Avellaneda 348' 5- Intente ingresar un alumno con número de documento existente (no lo permite) 6- Intente ingresar un alumno con documento nulo (no lo permite) 13 - Campo entero serial (autoincremento) Primer problema: Una farmacia guarda información referente a sus medicamentos en una tabla llamada "medicamentos". 1- Cree la tabla con la siguiente estructura: create table medicamentos(
74 codigo serial, nombre varchar(20), laboratorio varchar(20), precio float, cantidad integer, primary key (codigo) 2- Visualice la estructura de la tabla "medicamentos" 3- Ingrese los siguientes registros (insert into): insert into medicamentos (nombre, laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre, laboratorio,precio,cantidad) values('buscapina','roche',4.10,200 insert into medicamentos (nombre, laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60, Verifique que el campo "código" generó los valores de modo automático. Segundo problema: Un videoclub almacena información sobre sus películas en una tabla llamada "peliculas". 1- Créela con la siguiente estructura: -codigo (serial), -titulo (cadena de 40), -actor (cadena de 20), -duracion (entero), -clave primaria: codigo. 2- Visualice la estructura de la tabla "peliculas". 3- Ingrese los siguientes registros: insert into peliculas (titulo,actor,duracion) values('mision imposible','tom Cruise',120 insert into peliculas (titulo,actor,duracion) values('harry Potter y la piedra filosofal','xxx',180 insert into peliculas (titulo,actor,duracion) values('harry Potter y la camara secreta','xxx',190 insert into peliculas (titulo,actor,duracion) values('mision imposible 2','Tom Cruise',120 insert into peliculas (titulo,actor,duracion) values('la vida es bella','zzz', Seleccione todos los registros y verifique la carga automática de los códigos. 5- Actualice las películas cuyo código es 3 colocando en "actor" 'Daniel R.' 6- Elimine la película 'La vida es bella'. 7- Elimine todas las películas cuya duración sea igual a 120 minutos. 8- Visualice los registros. 9- Ingrese el siguiente registro, sin valor para la clave primaria: insert into peliculas (titulo,actor,duracion)
75 values('mujer bonita','richard Gere',120 Note que sigue la secuencia tomando el último valor generado, aunque ya no esté Comando truncate table Primer problema: Una farmacia guarda información referente a sus medicamentos en una tabla llamada "medicamentos". 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio float, cantidad integer, primary key (codigo) 3- Ingrese los siguientes registros: insert into medicamentos (nombre, laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre, laboratorio,precio,cantidad) values('buscapina','roche',4.10,200 insert into medicamentos (nombre, laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60, Elimine todos los registros con "delete" 4- Ingrese 2 registros: insert into medicamentos (nombre, laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre, laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60, Vea los registros para verificar que continuó la secuencia al generar el valor para "codigo" 6- Vacíe la tabla con truncate table 7- Ingrese el siguiente registro: insert into medicamentos (nombre, laboratorio,precio,cantidad) values('buscapina','roche',4.10, Vea los registros para verificar que al cargar el código reinició la secuencia en Tipo de dato texto Primer problema: Una concesionaria de autos vende autos usados y almacena los datos de los autos en una tabla llamada "autos".
76 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo, estableciendo el campo "patente" como clave primaria: create table autos( patente char(6), marca varchar(20), modelo char(4), precio float, primary key (patente) Hemos definido el campo "patente" de tipo "char" y no "varchar" porque la cadena de caracteres siempre tendrá la misma longitud (6 caracteres). Lo mismo sucede con el campo "modelo", en el cual almacenaremos el año, necesitamos 4 caracteres fijos. 2- Ingrese los siguientes registros: insert into autos values('acd123','fiat 128','1970',15000 insert into autos values('acg234','renault 11','1990',40000 insert into autos values('bcd333','peugeot 505','1990',80000 insert into autos values('gcd123','renault Clio','1990',70000 insert into autos values('bcc333','renault Megane','1998',95000 insert into autos values('bvf543','fiat 128','1975', Seleccione todos los autos del año 1990: 4- Borre la tabla. 5- Crearla nuevamente con la misma estructura pero utilizando las otras palabras claves para los tipos de datos char y varchar. 6- Ingrese un registro. 7- Mostrar el contenido de la tabla. Segundo problema: Una empresa almacena los datos de sus clientes en una tabla llamada "clientes". 1- Créela eligiendo el tipo de dato más adecuado para cada campo: create table clientes( documento char(8), apellido varchar(20), nombre varchar(20), domicilio varchar(30), telefono varchar (11) 2- Analice la definición de los campos. Se utiliza char(8) para el documento porque siempre constará de 8 caracteres. Para el número telefónico se usar "varchar" y no un tipo numérico porque si bien es un número, con él no se realizarán operaciones matemáticas.
77 3- Ingrese algunos registros: insert into clientes values(' ','perez','juan','sarmiento 980',' ' insert into clientes (documento,apellido,nombre,domicilio) values(' ','perez','ana','colon 234' insert into clientes values(' ','garcia','luis','avellaneda 1454',' ' insert into clientes values(' ','juarez','ana','urquiza 444',' ' 4- Seleccione todos los clientes de apellido "Perez" (2 registros) 16 - Tipo de dato numérico Primer problema: Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla llamada "cuentas". La tabla contiene estos datos: Número de Cuenta Documento Nombre Saldo Pedro Perez Juan Lopez Juan Lopez Susana Molina Cree la tabla eligiendo el tipo de dato adecuado para almacenar los datos descriptos arriba: - Número de cuenta: entero, no puede haber valores repetidos, clave primaria; - Documento del propietario de la cuenta: cadena de caracteres de 8 de longitud (siempre 8), no nulo; - Nombre del propietario de la cuenta: cadena de caracteres de 30 de longitud, - Saldo de la cuenta: valores altos con decimales. 2- Ingrese los siguientes registros: insert into cuentas(numero,documento,nombre,saldo) values('1234',' ','pedro Perez', insert into cuentas(numero,documento,nombre,saldo) values('2234',' ','juan Lopez', insert into cuentas(numero,documento,nombre,saldo) values('3344',' ','juan Lopez', insert into cuentas(numero,documento,nombre,saldo) values('3346',' ','susana Molina',1000 Note que hay dos cuentas, con distinto número de cuenta, de la misma persona. 3- Seleccione todos los registros cuyo saldo sea mayor a "4000" (2 registros) 4- Muestre el número de cuenta y saldo de todas las cuentas cuyo propietario sea "Juan Lopez" (2 registros) 5- Muestre las cuentas con saldo negativo (1 registro) 6- Muestre todas las cuentas cuyo número es igual o mayor a "3000" (2 registros):
78 Segundo problema: Una empresa almacena los datos de sus empleados en una tabla "empleados" que guarda los siguientes datos: nombre, documento, sexo, domicilio, sueldobasico. 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table empleados( nombre varchar(30), documento char(8), sexo char(1), domicilio varchar(30), sueldobasico decimal(7,2),--máximo estimado cantidadhijos smallint --no superará los Ingrese algunos registros: insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Juan Perez',' ','m','Sarmiento 123',500,2 insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Ana Acosta',' ','f','Colon 134',850,0 insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Bartolome Barrios',' ','m','Urquiza 479', ,4 3- Ingrese un valor de "sueldobasico" con más decimales que los definidos (redondea los decimales al valor más cercano ): insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Susana Molina',' ','f','Salta 876', ,3 4- Intente ingresar un sueldo que supere los 7 dígitos (no lo permite) 5- Muestre todos los empleados cuyo sueldo no supere los 900 pesos (1 registro): 6- Seleccione los nombres de los empleados que tengan hijos (3 registros): 17 - Tipo de dato fecha y hora Primer problema: Una facultad almacena los datos de sus alumnos en una tabla denominada "alumnos". 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table alumnos( apellido varchar(30), nombre varchar(30), documento char(8), domicilio varchar(30), fechaingreso date, fechanacimiento date 2- Setee el formato para entrada de datos de tipo fecha para que acepte valores "día-mes-año"
79 3- Ingrese un alumno empleando distintos separadores para las fechas: insert into alumnos values('gonzalez','ana',' ','colon 123',' ','15/02/1972' 4- Ingrese otro alumno empleando solamente un dígito para día y mes y 2 para el año: insert into alumnos values('juarez','bernardo',' ','sucre 456',' ','15/02/1972' 5- Ingrese un alumnos empleando 2 dígitos para el año de la fecha de ingreso y "null" en "fechanacimiento": insert into alumnos values('perez','laura',' ','bulnes 345',' ',null 6- Intente ingresar un alumno con fecha de ingreso correspondiente a "15 de marzo de 1990" pero en orden incorrecto " ": insert into alumnos values('lopez','carlos',' ','sarmiento 1254',' ',null aparece un mensaje de error porque lo lee con el formato día, mes y año y no reconoce el mes Muestre todos los alumnos que ingresaron antes del '1-1-91'. 1 registro. 8- Muestre todos los alumnos que tienen "null" en "fechanacimiento". 1 registro Valores por defecto (default) Primer problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos. 1- Cree la tabla con la siguiente estructura: create table visitantes( nombre varchar(30), edad smallint, sexo char(1) default 'f', domicilio varchar(30), ciudad varchar(20) default 'Cordoba', telefono varchar(11), mail varchar(30) default 'no tiene', montocompra decimal (6,2) 2- Vea la información de las columnas "column_default" y "is_nullable" 3- Ingrese algunos registros sin especificar valores para algunos campos para ver cómo opera la cláusula "default": insert into visitantes (nombre, domicilio, montocompra) values ('Susana Molina','Colon 123',59.80 insert into visitantes (nombre, edad, ciudad, mail) values ('Marcos Torres',29,'Carlos Paz','[email protected]' select * from visitantes;
80 4- Use la palabra "default" para ingresar valores en un insert. 5- Ingrese un registro con "default values". Segundo problema: Una pequeña biblioteca de barrio registra los préstamos de sus libros en una tabla llamada "prestamos". En ella almacena la siguiente información: título del libro, documento de identidad del socio a quien se le presta el libro, fecha de préstamo, fecha en que tiene que devolver el libro y si el libro ha sido o no devuelto. 1- Cree la tabla: create table prestamos( titulo varchar(40) not null, documento char(8) not null, fechaprestamo date not null, fechadevolucion date, devuelto char(1) default 'n' 2- Ingrese algunos registros omitiendo el valor para los campos que lo admiten: insert into prestamos (titulo,documento,fechaprestamo,fechadevolucion) values ('Manual de 1 grado',' ',' ',' ' insert into prestamos (titulo,documento,fechaprestamo) values ('Alicia en el pais de las maravillas',' ',' ' insert into prestamos (titulo,documento,fechaprestamo,fechadevolucion) values ('El aleph',' ',' ',' ' insert into prestamos (titulo,documento,fechaprestamo,devuelto) values ('Manual de geografia 5 grado',' ',' ','s' 3- Seleccione todos los registros 4- Ingrese un registro colocando "default" en los campos que lo admiten y vea cómo se almacenó. 5- Intente ingresar un registro con "default values" y analice el mensaje de error (no se puede) 19 - Columnas calculadas (operadores aritméticos y de concatenación) Primer problema: Un comercio que vende artículos de computación registra los datos de sus artículos en una tabla con ese nombre. 1- Cree la tabla: create table articulos( codigo serial, nombre varchar(20), descripcion varchar(30), precio decimal(9,2), cantidad smallint default 0, primary key (codigo)
81 2- Ingrese algunos registros: insert into articulos (nombre, descripcion, precio,cantidad) values ('impresora','epson Stylus C45',400.80,20 insert into articulos (nombre, descripcion, precio) values ('impresora','epson Stylus C85',500 insert into articulos (nombre, descripcion, precio) values ('monitor','samsung 14',800 insert into articulos (nombre, descripcion, precio,cantidad) values ('teclado','ingles Biswal',100,50 3- El comercio quiere aumentar los precios de todos sus artículos en un 15%. Actualice todos los precios empleando operadores aritméticos. 4- Vea el resultado 5- Muestre todos los artículos, concatenando el nombre y la descripción de cada uno de ellos separados por coma. 6- Reste a la cantidad de todos los teclados, el valor 5, empleando el operador aritmético menos ("-") 20 - Alias Primer problema: Trabaje con la tabla "libros" de una librería. 1- Cree la tabla: create table libros( codigo serial, titulo varchar(40) not null, autor varchar(20) default 'Desconocido', editorial varchar(20), precio decimal(6,2), cantidad smallint default 0, primary key (codigo) 2- Ingrese algunos registros: insert into libros (titulo,autor,editorial,precio) values('el aleph','borges','emece',25 insert into libros (titulo,autor,editorial,precio,cantidad) values('java en 10 minutos','mario Molina','Siglo XXI',50.40,100 insert into libros (titulo,autor,editorial,precio,cantidad) values('alicia en el pais de las maravillas','lewis Carroll','Emece',15,50 3- Muestre todos los campos de los libros y un campo extra, con el encabezado "monto_total" en la que calcule el monto total en dinero de cada libro (precio por cantidad) 4- Muestre el título, autor y precio de todos los libros de editorial "Emece" y agregue dos columnas extra en las cuales muestre el descuento de cada libro, con el encabezado "descuento" y el precio con un 10% de descuento con el encabezado "precio_final".
82 5- Muestre una columna con el título y el autor concatenados con el encabezado "título_y_autor" 21 - Funciones para el manejo de cadenas Primer problema: Trabaje con la tabla que almacena los datos de clientes. 1- Créela con la siguiente estructura: create table clientes( documento char(8), apellido varchar(20), nombre varchar(20), domicilio varchar(30), telefono varchar (11) 2- Ingresar algunos registros: insert into clientes(documento,apellido,nombre,domicilio,telefono) values(' ','perez','juan','sarmiento 980',' ' insert into clientes (documento,apellido,nombre,domicilio,telefono) values(' ','perez','ana','colon 234',' ' insert into clientes(documento,apellido,nombre,domicilio,telefono) values(' ','garcia','luis','avellaneda 1454',' ' insert into clientes (documento,apellido,nombre,domicilio,telefono) values(' ','juarez','ana','urquiza 444',' ' 3- Mostrar todos los registros disponiendo en mayúsculas el apellido y el nombre. 4- Mostrar el primer caracter del nombre Funciones matemáticas Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes". 1- Créela con la siguiente estructura: create table clientes ( codigo serial, nombre varchar(30) not null, domicilio varchar(30), ciudad varchar(20), provincia varchar (20), credito decimal(9,2), primary key(codigo) 2- Ingrese 5 registros: insert into clientes(nombre,domicilio,ciudad,provincia,credito) values ('Lopez Marcos','Colon 111','Cordoba','Cordoba', insert into clientes(nombre,domicilio,ciudad,provincia,credito) values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba', insert into clientes(nombre,domicilio,ciudad,provincia,credito)
83 values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba',190 insert into clientes(nombre,domicilio,ciudad,provincia,credito) values ('Olmos Luis','Sarmiento 444','Rosario','Santa Fe', insert into clientes(nombre,domicilio,ciudad,provincia,credito) values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba', Muestre todos los registros. 4- Mostrar el campo crédito redondeado hacia arriba Funciones para el uso de fechas y horas Primer problema: Una facultad almacena los datos de sus alumnos en una tabla denominada "alumnos". 1- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table alumnos( apellido varchar(30), nombre varchar(30), documento char(8), domicilio varchar(30), fechaingreso date, fechanacimiento date 2- Setee el formato para entrada de datos de tipo fecha para que acepte valores "día-mes-año" 3- Ingrese un alumno empleando distintos separadores para las fechas 4- Ingrese otro alumno empleando solamente un dígito para día y mes y 2 para el año 5- Ingrese un alumnos empleando 2 dígitos para el año de la fecha de ingreso y "null" en "fechanacimiento" 6- Muestre los alumnos que ingresaron antes del '1-1-91'. 7- Muestre los alumnos que tienen "null" en "fechanacimiento": 8- Muestre el año de nacimiento de todos los alumnos Ordenar registros (order by) Primer problema: En una página web se guardan los siguientes datos de las visitas: número de visita, nombre, mail, pais, fecha. 1- Créela con la siguiente estructura: create table visitas ( numero serial, nombre varchar(30) default 'Anonimo', mail varchar(50), pais varchar (20),
84 fecha timestamp, primary key(numero) 2- Ingrese algunos registros: insert into visitas (nombre,mail,pais,fecha) values ('Ana Maria 10:10' insert into visitas (nombre,mail,pais,fecha) values ('Gustavo 21:30' insert into visitas (nombre,mail,pais,fecha) values 15:45' insert into visitas (nombre,mail,pais,fecha) values ('Fabiola 08:15' insert into visitas (nombre,mail,pais,fecha) values ('Fabiola 20:45' insert into visitas (nombre,mail,pais,fecha) values 16:20' insert into visitas (nombre,mail,pais,fecha) values 16:25' 3- Ordene los registros por fecha, en orden descendente. 4- Muestre el nombre del usuario, pais y el número de mes, ordenado por pais (ascendente) y número de mes (descendente) 5- Muestre el pais, el mes, el día y la hora y ordene las visitas por nombre del mes, del día y la hora. 6- Muestre los mail, país, ordenado por país, de todos los que visitaron la página en octubre (4 registros) 25 - Operadores lógicos (and - or - not) Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio decimal(5,2), cantidad smallint, primary key(codigo) 2- Ingrese algunos registros: insert into medicamentos (nombre,laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('buscapina','roche',4.10,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60,100
85 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('paracetamol 500','Bago',1.90,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('bayaspirina','bayer',2.10,150 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal jarabe','bayer',5.10, Recupere los códigos y nombres de los medicamentos cuyo laboratorio sea 'Roche' y cuyo precio sea menor a 5 (1 registro cumple con ambas condiciones) 4- Recupere los medicamentos cuyo laboratorio sea 'Roche' o cuyo precio sea menor a 5 (4 registros) Note que el resultado es diferente al del punto 4, hemos cambiado el operador de la sentencia anterior. 5- Muestre todos los medicamentos cuyo laboratorio NO sea "Bayer" y cuya cantidad sea=100 (1 registro) 6- Muestre todos los medicamentos cuyo laboratorio sea "Bayer" y cuya cantidad NO sea=100 (2 registros) Analice estas 2 últimas sentencias. El operador "not" afecta a la condición a la cual antecede, no a las siguientes. Los resultados de los puntos 6 y 7 son diferentes. 7- Elimine todos los registros cuyo laboratorio sea igual a "Bayer" y su precio sea mayor a 10 (1 registro eliminado) 8- Cambie la cantidad por 200, a todos los medicamentos de "Roche" cuyo precio sea mayor a 5 (1 registro afectado) 9- Borre los medicamentos cuyo laboratorio sea "Bayer" o cuyo precio sea menor a 3 (3 registros borrados) 26 - Otros operadores relacionales (is null) Primer problema: Trabajamos con la tabla "peliculas" de un video club que alquila películas en video. 1- Créela con la siguiente estructura: create table peliculas( codigo serial, titulo varchar(40) not null, actor varchar(20), duracion smallint, primary key (codigo) 2- Ingrese algunos registros: insert into peliculas(titulo,actor,duracion) values('mision imposible','tom Cruise',120 insert into peliculas(titulo,actor,duracion) values('harry Potter y la piedra filosofal','daniel R.',null insert into peliculas(titulo,actor,duracion) values('harry Potter y la camara secreta','daniel R.',190 insert into peliculas(titulo,actor,duracion) values('mision imposible 2','Tom Cruise',120
86 insert into peliculas(titulo,actor,duracion) values('mujer bonita',null,120 insert into peliculas(titulo,actor,duracion) values('tootsie','d. Hoffman',90 insert into peliculas (titulo) values('un oso rojo' 3- Recupere las películas cuyo actor sea nulo (2 registros) 4- Cambie la duración a 0, de las películas que tengan duración igual a "null" (2 registros) 5- Borre todas las películas donde el actor sea "null" y cuya duración sea 0 (1 registro) 27 - Otros operadores relacionales (between) Primer problema: En una página web se guardan los siguientes datos de las visitas: número de visita, nombre, mail, pais, fechayhora de la visita. 1- Créela con la siguiente estructura: create table visitas ( numero serial, nombre varchar(30) default 'Anonimo', mail varchar(50), pais varchar (20), fechayhora timestamp, primary key(numero) 3- Ingrese algunos registros: insert into visitas (nombre,mail,pais,fechayhora) values ('Ana Maria Lopez','[email protected]','Argentina',' :10' insert into visitas (nombre,mail,pais,fechayhora) values ('Gustavo Gonzalez','[email protected]','Chile',' :30' insert into visitas (nombre,mail,pais,fechayhora) values ('Juancito','[email protected]','Argentina',' :45' insert into visitas (nombre,mail,pais,fechayhora) values ('Fabiola Martinez','[email protected]','Mexico',' :15' insert into visitas (nombre,mail,pais,fechayhora) values ('Fabiola Martinez','[email protected]','Mexico',' :45' insert into visitas (nombre,mail,pais,fechayhora) values ('Juancito','[email protected]','Argentina',' :20' insert into visitas (nombre,mail,pais,fechayhora) values ('Juancito','[email protected]','Argentina',' :25' insert into visitas (nombre,mail,pais) values ('Federico1','[email protected]','Argentina' 3- Seleccione los usuarios que visitaron la página entre el ' ' y ' ' (5 registros)
87 Note que incluye los de fecha mayor o igual al valor mínimo y menores al valor máximo, y que los valores null no se incluyen. 4- Recupere las visitas cuyo número se encuentra entre 2 y 5 (4 registros) Note que incluye los valores límites Otros operadores relacionales (in) Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio decimal(6,2), cantidad smallint, fechavencimiento date not null, primary key(codigo) 2- Ingrese algunos registros: insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento) values('sertal','roche',5.2,1,' ' insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento) values('buscapina','roche',4.10,3,' ' insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento) values('amoxidal 500','Bayer',15.60,100,' ' insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento) values('paracetamol 500','Bago',1.90,20,' ' insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento) values('bayaspirina','bayer',2.10,150,' ' insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento) values('amoxidal jarabe','bayer',5.10,250,' ' 3- Recupere los nombres y precios de los medicamentos cuyo laboratorio sea "Bayer" o "Bago" empleando el operador "in" (4 registros) 4- Seleccione los remedios cuya cantidad se encuentre entre 1 y 5 empleando el operador "between" y luego el operador "in" (2 registros) Note que es más conveniente emplear, en este caso, el operador ""between" Búsqueda de patrones (like - not like) Primer problema: Una empresa almacena los datos de sus empleados en una tabla "empleados". 1- Cree la tabla: create table empleados( nombre varchar(30), documento char(8), domicilio varchar(30),
88 fechaingreso date, seccion varchar(20), sueldo decimal(6,2), primary key(documento) 2- Ingrese algunos registros: insert into empleados( values('juan Perez',' ','Colon 123',' ','Gerencia', insert into empleados values('ana Acosta',' ','Caseros 987',' ','Secretaria', insert into empleados values('lucas Duarte',' ','Sucre 235',' ','Sistemas',790 insert into empleados values('pamela Gonzalez',' ','Sarmiento 873',' ','Secretaria',550 insert into empleados values('marcos Juarez',' ','Rivadavia 801',' ','Contaduria', insert into empleados values('yolanda Perez',' ','Colon 180',' ','Administracion',400 insert into empleados values('rodolfo Perez',' ','Coronel Olmedo 588',' ','Sistemas', Muestre todos los empleados con apellido "Perez" empleando el operador "like" (3 registros) 4- Muestre todos los empleados cuyo domicilio comience con "Co" y tengan un "8" (2 registros) 5- Muestre todos los nombres y sueldos de los empleados cuyos sueldos incluyen centavos (3 registros) 6- Muestre los empleados que hayan ingresado en "1990" (3 registros) 30 - Contar registros (count) Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio decimal(6,2), cantidad smallint, fechavencimiento date not null, numerolote int default null, primary key(codigo) 3- Ingrese algunos registros:
89 insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento,numerolote) values('sertal','roche',5.2,1,' ',null insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento,numerolote) values('buscapina','roche',4.10,3,' ',null insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento,numerolote) values('amoxidal 500','Bayer',15.60,100,' ',null insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento,numerolote) values('paracetamol 500','Bago',1.90,20,' ',null insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento,numerolote) values('bayaspirina',null,2.10,null,' ',null insert into medicamentos(nombre,laboratorio,precio,cantidad,fechavencimiento,numerolote) values('amoxidal jarabe','bayer',null,250,' ',null 3- Muestre la cantidad de registros empleando la función "count(*)" (6 registros) 4- Cuente la cantidad de medicamentos que tienen laboratorio conocido (5 registros) 5- Cuente la cantidad de medicamentos que tienen precio distinto a "null" y que tienen cantidad distinto a "null", disponer alias para las columnas. 6- Cuente la cantidad de remedios con precio conocido, cuyo laboratorio comience con "B" (2 registros) 7- Cuente la cantidad de medicamentos con número de lote distinto de "null" (0 registros) 31 - Funciones de agrupamiento (count - sum - min - max - avg) Primer problema: Una empresa almacena los datos de sus empleados en una tabla "empleados". 1- Cree la tabla: create table empleados( nombre varchar(30), documento char(8), domicilio varchar(30), seccion varchar(20), sueldo decimal(6,2), cantidadhijos smallint, primary key(documento) 2- Ingrese algunos registros: insert into empleados values('juan Perez',' ','Colon 123','Gerencia',5000,2 insert into empleados
90 values('ana Acosta',' ','Caseros 987','Secretaria',2000,0 insert into empleados values('lucas Duarte',' ','Sucre 235','Sistemas',4000,1 insert into empleados values('pamela Gonzalez',' ','Sarmiento 873','Secretaria',2200,3 insert into empleados values('marcos Juarez',' ','Rivadavia 801','Contaduria',3000,0 insert into empleados values('yolanda Perez',' ','Colon 180','Administracion',3200,1 insert into empleados values('rodolfo Perez',' ','Coronel Olmedo 588','Sistemas',4000,3 insert into empleados values('martina Rodriguez',' ','Sarmiento 1234','Administracion',3800,4 insert into empleados values('andres Costa',' ',default,'Secretaria',null,null 3- Muestre la cantidad de empleados usando "count" (9 empleados) 4- Muestre la cantidad de empleados con sueldo no nulo de la sección "Secretaria" (2 empleados) 5- Muestre el sueldo más alto y el más bajo colocando un alias (5000 y 2000) 6- Muestre el valor mayor de "cantidadhijos" de los empleados "Perez" (3 hijos) 7- Muestre el promedio de sueldos de todo los empleados (3400. Note que hay un sueldo nulo y no es tenido en cuenta) 8- Muestre el promedio de sueldos de los empleados de la sección "Secretaría" (2100) 9- Muestre el promedio de hijos de todos los empleados de "Sistemas" (2) 32 - Agrupar registros (group by) Primer problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos. 1- Cree la tabla con la siguiente estructura: create table visitantes( nombre varchar(30), edad smallint, sexo char(1) default 'f', domicilio varchar(30), ciudad varchar(20) default 'Cordoba', telefono varchar(11), mail varchar(30) default 'no tiene', montocompra decimal (6,2) 2- Ingrese algunos registros: insert into visitantes values ('Susana Molina',35,default,'Colon 123',default,null,null,59.80
91 insert into visitantes values ('Marcos Torres',29,'m',default,'Carlos insert into visitantes values ('Mariana Juarez',45,default,default,'Carlos Paz',null,default,23.90 insert into visitantes (nombre, edad,sexo,telefono, mail) values ('Fabian insert into visitantes (nombre, ciudad, montocompra) values ('Alejandra Gonzalez','La Falda', insert into visitantes (nombre, edad,sexo, ciudad, mail,montocompra) values ('Gaston Perez',29,'m','Carlos insert into visitantes values ('Liliana Torres',40,default,'Sarmiento 876',default,default,default,85 insert into visitantes values ('Gabriela Duarte',21,null,null,'Rio 3- Queremos saber la cantidad de visitantes de cada ciudad utilizando la cláusula "group by" (4 filas devueltas) 4- Queremos la cantidad visitantes con teléfono no nulo, de cada ciudad (4 filas devueltas) 5- Necesitamos el total del monto de las compras agrupadas por sexo (3 filas) 6- Se necesita saber el máximo y mínimo valor de compra agrupados por sexo y ciudad (6 filas) 7- Calcule el promedio del valor de compra agrupados por ciudad (4 filas) 8- Cuente y agrupe por ciudad sin tener en cuenta los visitantes que no tienen mail (3 filas) 33 - Seleccionar grupos (having) Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes". 1- Créela con la siguiente estructura: create table clientes ( codigo serial, nombre varchar(30) not null, domicilio varchar(30), ciudad varchar(20), provincia varchar (20), telefono varchar(11), primary key(codigo) 3- Ingrese algunos registros: insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Lopez Marcos','Colon 111','Cordoba','Cordoba','null' insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba',' ' insert into clientes(nombre,domicilio,ciudad,provincia,telefono)
92 values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba',' ' insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Perez Luis','Sarmiento 444','Rosario','Santa Fe',null insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba',' ' insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Gomez Ines','San Martin 666','Santa Fe','Santa Fe',' ' insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Torres Fabiola','Alem 777','Villa del Rosario','Cordoba',' ' insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Lopez Carlos',null,'Cruz del Eje','Cordoba',null insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Ramos Betina','San Martin 999','Cordoba','Cordoba',' ' insert into clientes(nombre,domicilio,ciudad,provincia,telefono) values ('Lopez Lucas','San Martin 1010','Posadas','Misiones',' ' 3- Obtenga el total de los registros agrupados por ciudad y provincia (6 filas) 4- Obtenga el total de los registros agrupados por ciudad y provincia sin considerar los que tienen menos de 2 clientes (3 filas) Segundo problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos. 1- Créela con la siguiente estructura: create table visitantes( nombre varchar(30), edad smallint, sexo char(1), domicilio varchar(30), ciudad varchar(20), telefono varchar(11), montocompra decimal(6,2) not null 2- Ingrese algunos registros: insert into visitantes values ('Susana Molina',28,'f',null,'Cordoba',null,45.50 insert into visitantes values ('Marcela Mercado',36,'f','Avellaneda 345','Cordoba',' ',22.40 insert into visitantes values ('Alberto Garcia',35,'m','Gral. Paz 123','Alta Gracia',' ',25 insert into visitantes values ('Teresa Garcia',33,'f',default,'Alta Gracia',' ',120 insert into visitantes values ('Roberto Perez',45,'m','Urquiza 335','Cordoba',' ',33.20 insert into visitantes values ('Marina Torres',22,'f','Colon 222','Villa Dolores',' ',95 insert into visitantes values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia',null,53.50 insert into visitantes values ('Roxana Lopez',20,'f','null','Alta Gracia',null,240 insert into visitantes
93 values ('Liliana Garcia',50,'f','Paso 999','Cordoba',' ',48 insert into visitantes values ('Juan Torres',43,'m','Sarmiento 876','Cordoba',null, Obtenga el total de las compras agrupados por ciudad y sexo de aquellas filas que devuelvan un valor superior a 50 (3 filas) 4- Agrupe por ciudad y sexo, muestre para cada grupo el total de visitantes, la suma de sus compras y el promedio de compras, ordenado por la suma total y considerando las filas con promedio superior a 30 (3 filas) 34 - Registros duplicados (distinct) Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes". 1- Créela con la siguiente estructura: create table clientes ( codigo serial, nombre varchar(30) not null, domicilio varchar(30), ciudad varchar(20), provincia varchar (20), primary key(codigo) 2- Ingrese algunos registros: insert into clientes(nombre,domicilio,ciudad,provincia) values ('Lopez Marcos','Colon 111','Cordoba','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Perez Luis','Sarmiento 444','Rosario','Santa Fe' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Gomez Ines','San Martin 666','Santa Fe','Santa Fe' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Torres Fabiola','Alem 777','Villa del Rosario','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Lopez Carlos',null,'Cruz del Eje','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Ramos Betina','San Martin 999','Cordoba','Cordoba' insert into clientes(nombre,domicilio,ciudad,provincia) values ('Lopez Lucas','San Martin 1010','Posadas','Misiones' 3- Obtenga las provincias sin repetir (3 registros) 4- Cuente las distintas provincias. 5- Se necesitan los nombres de las ciudades sin repetir (6 registros) 6- Obtenga la cantidad de ciudades distintas. 7- Combine con "where" para obtener las distintas ciudades de la provincia de
94 Cordoba (3 registros) 8- Contamos las distintas ciudades de cada provincia empleando "group by" (3 registros) Segundo problema: La provincia almacena en una tabla llamada "inmuebles" los siguientes datos de los inmuebles y sus propietarios para cobrar impuestos. 1- Créela con la siguiente estructura: create table inmuebles ( documento varchar(8) not null, apellido varchar(30), nombre varchar(30), domicilio varchar(20), barrio varchar(20), ciudad varchar(20), tipo char(1),--b=baldio, e: edificado superficie decimal (8,2) 3- Ingrese algunos registros: insert into inmuebles values (' ','Perez','Alberto','San Martin 800','Centro','Cordoba','e',100 insert into inmuebles values (' ','Perez','Alberto','Sarmiento 245','Gral. Paz','Cordoba','e',200 insert into inmuebles values (' ','Lopez','Maria','San Martin 202','Centro','Cordoba','e',250 insert into inmuebles values (' ','Garcia','Carlos','Paso 1234','Alberdi','Cordoba','b',200 insert into inmuebles values (' ','Garcia','Carlos','Guemes 876','Alberdi','Cordoba','b',300 insert into inmuebles values (' ','Perez','Mariana','Caseros 456','Flores','Cordoba','b',200 insert into inmuebles values (' ','Lopez','Luis','San Martin 321','Centro','Carlos Paz','e',500 insert into inmuebles values (' ','Lopez','Luis','Lopez y Planes 853','Flores','Carlos Paz','e',350 insert into inmuebles values (' ','Perez','Alberto','Sucre 1877','Flores','Cordoba','e', Muestre los distintos apellidos de los propietarios, sin repetir (3 registros) 4- Muestre los distintos documentos de los propietarios, sin repetir (6 registros) 5- Cuente, sin repetir, la cantidad de propietarios de inmuebles de la ciudad de Cordoba (5) 6- Cuente la cantidad de inmuebles con domicilio en 'San Martin', sin repetir la ciudad (2) 7- Muestre los apellidos y nombres, sin repetir (5 registros) Note que hay 2 personas con igual nombre y apellido que aparece una sola vez.
95 8- Muestre la cantidad de inmuebles que tiene cada propietario agrupando por documento, sin repetir barrio (6 registros) 35 - Clave primaria compuesta Primer problema: Un consultorio médico en el cual trabajan 3 médicos registra las consultas de los pacientes en una tabla llamada "consultas". 1- La tabla contiene los siguientes datos: - fechayhora: timestamp not null, fecha y hora de la consulta, - medico: varchar(30), not null, nombre del médico (Perez,Lopez,Duarte), - documento: char(8) not null, documento del paciente, - paciente: varchar(30), nombre del paciente, - obrasocial: varchar(30), nombre de la obra social (IPAM,PAMI, etc.). 2- Un médico sólo puede atender a un paciente en una fecha y hora determinada. En una fecha y hora determinada, varios médicos atienden a distintos pacientes. Cree la tabla definiendo una clave primaria compuesta: create table consultas( fechayhora timestamp not null, medico varchar(30) not null, documento char(8) not null, paciente varchar(30), obrasocial varchar(30), primary key(fechayhora,medico) 3- Ingrese varias consultas para un mismo médico en distintas horas el mismo día. 4- Ingrese varias consultas para diferentes médicos en la misma fecha y hora. 5- Intente ingresar una consulta para un mismo médico en la misma hora el mismo día. Segundo problema: Un club dicta clases de distintos deportes. En una tabla llamada "inscriptos" almacena la información necesaria. 1- La tabla contiene los siguientes campos: - documento del socio alumno: char(8) not null - nombre del socio: varchar(30), - nombre del deporte (tenis, futbol, natación, basquet): varchar(15) not null, - año de inscripcion: smallint, - matrícula: si la matrícula ha sido o no pagada ('s' o 'n'). 2- Necesitamos una clave primaria que identifique cada registro. Un socio puede inscribirse en varios deportes en distintos años. Un socio no puede inscribirse en el mismo deporte el mismo año. Varios socios se inscriben en un mismo deporte en distintos años. Cree la tabla con una clave compuesta: create table inscriptos( documento char(8) not null, nombre varchar(30),
96 deporte varchar(15) not null, año date, matricula char(1), primary key(documento,deporte,año) 3- Inscriba a varios alumnos en el mismo deporte en el mismo año 4- Inscriba a un mismo alumno en varios deportes en el mismo año 5- Ingrese un registro con el mismo documento de socio en el mismo deporte en distintos años 6- Intente inscribir a un socio alumno en un deporte en el cual ya esté inscripto. 7- Intente actualizar un registro para que la clave primaria se repita Restricción check Primer problema: Una empresa tiene registrados datos de sus empleados en una tabla llamada "empleados". 1- Créela con la siguiente estructura: create table empleados ( documento varchar(8), nombre varchar(30), fechanacimiento date, cantidadhijos smallint, seccion varchar(20), sueldo decimal(6,2) 2- Agregue una restricción "check" para asegurarse que no se ingresen valores negativos para el sueldo 3- Ingrese algunos registros válidos: insert into empleados values (' ','Alberto Lopez','1965/10/05',1,'Sistemas',1000 insert into empleados values (' ','Beatriz Garcia','1972/08/15',2,'Administracion',3000 insert into empleados values (' ','Carlos Caseres','1980/10/05',0,'Contaduría', Intente agregar otra restricción "check" al campo sueldo para asegurar que ninguno supere el valor 5000 La sentencia no se ejecuta porque hay un sueldo que no cumple la restricción. 5- Elimine el registro infractor y vuelva a crear la restricción alter table empleados add constraint CK_empleados_sueldo_maximo check (sueldo<= Establezca una restricción para controlar que la fecha de nacimiento que se ingresa no supere la fecha actual
97 7- Establezca una restricción "check" para "cantidadhijos" que permita solamente valores entre 0 y Vea todas las restricciones de la tabla (5 filas) 9- Intente agregar un registro que vaya contra alguna de las restricciones al campo "sueldo". Mensaje de error porque se infringe la restricción "CK_empleados_sueldo_positivo". 10- Intente agregar un registro con fecha de nacimiento futura. Mensaje de error. 11- Intente modificar un registro colocando en "cantidadhijos" el valor "21". Mensaje de error. Segundo problema: Una playa de estacionamiento almacena los datos de los vehículos que ingresan en la tabla llamada "vehiculos". 1- Cree la tabla: create table vehiculos( numero serial, patente char(6), tipo char(4), fechahoraentrada timestamp, fechahorasalida timestamp, primary key(numero) 2- Ingresamos algunos registros: insert into vehiculos (patente,tipo,fechahoraentrada,fechahorasalida) values('aic124','auto','2007/01/17 8:05','2007/01/17 12:30' insert into vehiculos (patente,tipo,fechahoraentrada,fechahorasalida) values('caa258','auto','2007/01/17 8:10',null insert into vehiculos (patente,tipo,fechahoraentrada,fechahorasalida) values('dse367','moto','2007/01/17 8:30','2007/01/17 18:00' 3- Agregue una restricción "check" para asegurarse que la fecha de entrada a la playa no sea posterior a la fecha y hora actual 4- Agregue otra restricción "check" al campo "fechahoraentrada" que establezca que sus valores no sean posteriores a "fechahorasalida" 5- Intente ingresar un valor que no cumpla con la primera restricción establecida en el campo "fechahoraentrada" 6- Intente modificar un registro para que la salida sea anterior a la entrada Mensaje de error. 7- Vea todas las restricciones para la tabla "vehiculos": select * from information_schema.table_constraints where table_name = 'empleados'; 8- Vea todos los registros
98 37 - Restricción primary key Primer problema: Una empresa tiene registrados datos de sus empleados en una tabla llamada "empleados". 1- Créela con la siguiente estructura: create table empleados ( documento varchar(8) not null, nombre varchar(30), seccion varchar(20) 2- Ingrese algunos registros, dos de ellos con el mismo número de documento: insert into empleados values (' ','Alberto Lopez','Sistemas' insert into empleados values (' ','Beatriz Garcia','Administracion' insert into empleados values (' ','Carlos Fuentes','Administracion' 3- Intente establecer una restricción "primary key" para la tabla para que el documento no se repita ni admita valores nulos. No lo permite porque la tabla contiene datos que no cumplen con la restricción, debemos eliminar (o modificar) el registro que tiene documento duplicado: 4- Establezca la restricción "primary key" del punto 3 5- Intente actualizar un documento para que se repita. No lo permite porque va contra la restricción. 6-Intente establecer otra restricción "primary key" con el campo "nombre". No lo permite, sólo puede haber una restricción "primary key" por tabla. 7- Intente ingresar un registro con valor nulo para el documento. No lo permite porque la restricción no admite valores nulos. 8- Vea las restricciones de la tabla empleados (2 filas) Segundo problema: Una empresa de remises tiene registrada la información de sus vehículos en una tabla llamada "remis". 1- Cree la tabla con la siguiente estructura: create table remis( numero serial, patente char(6), marca varchar(15), modelo char(4) 2- Ingrese algunos registros sin repetir patente: insert into remis (patente,marca,modelo)values('abc123','renault 12','1990' insert into remis (patente,marca,modelo)values('def456','fiat Duna','1995' 3- Definir una restricción "primary key" para el campo "patente".
99 4- Establezca una restricción "primary key" para el campo "numero". (No lo permite ya que hay una "primary key") 5- Vea la información de las restricciones 38 - Restricción unique Primer problema: Una empresa de remises tiene registrada la información de sus vehículos en una tabla llamada "remis". 1- Cree la tabla con la siguiente estructura: create table remis( numero serial, patente char(6), marca varchar(15), modelo char(4) 2- Ingrese algunos registros, 2 de ellos con patente repetida y alguno con patente nula: insert into remis(patente,marca,modelo) values('abc123','renault clio','1990' insert into remis(patente,marca,modelo) values('def456','peugeot 504','1995' insert into remis(patente,marca,modelo) values('def456','fiat Duna','1998' insert into remis(patente,marca,modelo) values('ghi789','fiat Duna','1995' insert into remis(patente,marca,modelo) values(null,'fiat Duna','1995' 3- Intente agregar una restricción "unique" para asegurarse que la patente del remis no tomará valores repetidos. No se puede porque hay valores duplicados. 4- Elimine el registro con patente duplicada y establezca la restricción. Note que hay 1 registro con valor nulo en "patente". 5- Intente ingresar un registro con patente repetida (no lo permite) 6- Ingresar un registro con valor nulo para el campo "patente". Lo permite. 7- Muestre la información de las restricciones 39 - Eliminar restricciones (alter table - drop constraint) Primer problema: Una playa de estacionamiento almacena cada día los datos de los vehículos que ingresan en la tabla llamada "vehiculos". 1- Cree la tabla: create table vehiculos( patente char(6) not null,
100 tipo char(1),--'a'=auto, 'm'=moto horallegada timestamp not null, horasalida timestamp 2- Agregue una restricción "primary key" que incluya los campos "patente" y "horallegada" 3- Ingrese un vehículo: insert into vehiculos values('sdr456','a','2005/10/10 10:10',null 4- Intente ingresar un registro repitiendo la clave primaria: insert into vehiculos values('sdr456','m','2005/10/10 10:10',null No se permite. 5- Ingrese un registro repitiendo la patente pero no la hora de llegada: insert into vehiculos values('sdr456','m','2005/10/10 12:10',null 6- Ingrese un registro repitiendo la hora de llegada pero no la patente: insert into vehiculos values('sdr111','m','2005/10/10 10:10',null 7- Vea todas las restricciones para la tabla "vehiculos" 8- Elimine la restricción "primary key". 9- Vea si se han eliminado 41 - Típos de índices (create y drop) Primer problema: 1- Cree la tabla con la siguiente estructura: create table agenda( apellido varchar(30), nombre varchar(20) not null, domicilio varchar(30), telefono varchar(11), mail varchar(30), 2- Ingrese los siguientes registros: insert into agenda values('perez','juan','sarmiento 345',' ','[email protected]' insert into agenda values('garcia','ana','urquiza 367',' ','[email protected]' insert into agenda values('lopez','juan','avellaneda 900',null,'[email protected]' insert into agenda values('juarez','mariana','sucre 123',' ','[email protected]' insert into agenda values('molinari','lucia','peru 1254',' ','[email protected]' insert into agenda values('ferreyra','patricia','colon 1534',' ',null insert into agenda values('perez','susana','san Martin 333',null,null insert into agenda values('perez','luis','urquiza 444',' ','[email protected]' insert into agenda values('lopez','maria','salta
101 3- Cree un índice común por el campo apellido. 4- Cree un índice único por el mail. 5- Borre los dos índices Cláusulas limit y offset del comando select Primer problema: Trabaje con la tabla "agenda" que registra la información referente a sus amigos. 1- Cree la tabla con la siguiente estructura: create table agenda( apellido varchar(30), nombre varchar(20) not null, domicilio varchar(30), telefono varchar(11), mail varchar(30) 2- Ingrese 5 registros. 3- Realice una consulta limitando la salida a sólo 3 registros. 4- Muestre los registros desde el 2 al Muestre 4 registros a partir del 2 ordenado por apellido Combinación interna (inner join) Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Créelas con las siguientes estructuras: create table clientes ( codigo serial, nombre varchar(30), domicilio varchar(30), ciudad varchar(20), codigoprovincia smallint not null, primary key(codigo) create table provincias( codigo serial, nombre varchar(20), primary key (codigo) 2- Ingrese algunos registros para ambas tablas:
102 insert into provincias (nombre) values('cordoba' insert into provincias (nombre) values('santa Fe' insert into provincias (nombre) values('corrientes' insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Lopez Marcos','Colon 111','Córdoba',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Perez Ana','San Martin 222','Cruz del Eje',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Garcia Juan','Rivadavia 333','Villa Maria',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Perez Luis','Sarmiento 444','Rosario',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Pereyra Lucas','San Martin 555','Cruz del Eje',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Gomez Ines','San Martin 666','Santa Fe',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Torres Fabiola','Alem 777','Ibera',3 3- Obtenga los datos de ambas tablas, usando alias 4- Obtenga la misma información anterior pero ordenada por nombre de provincia. 5- Recupere los clientes de la provincia "Santa Fe" (2 registros devueltos) Segundo problema: Un club dicta clases de distintos deportes. Almacena la información en una tabla llamada "inscriptos" que incluye el documento, el nombre, el deporte y si la matricula esta paga o no y una tabla llamada "inasistencias" que incluye el documento, el deporte y la fecha de la inasistencia. 1 - Cree las tablas: create table inscriptos( nombre varchar(30), documento char(8), deporte varchar(15), matricula char(1), --'s'=paga 'n'=impaga primary key(documento,deporte) create table inasistencias( documento char(8), deporte varchar(15), fecha date 2- Ingrese algunos registros para ambas tablas: insert into inscriptos values('juan Perez',' ','tenis','s' insert into inscriptos values('maria Lopez',' ','tenis','s' insert into inscriptos values('agustin Juarez',' ','tenis','n' insert into inscriptos values('marta Garcia',' ','natacion','s' insert into inscriptos values('juan Perez',' ','natacion','s' insert into inscriptos values('maria Lopez',' ','natacion','n' insert into inasistencias values(' ','tenis',' ' insert into inasistencias values(' ','tenis',' ' insert into inasistencias values(' ','tenis',' '
103 insert into inasistencias values(' ','tenis',' ' insert into inasistencias values(' ','natacion',' ' insert into inasistencias values(' ','natacion',' ' 3- Muestre el nombre, el deporte y las fechas de inasistencias, ordenado por nombre y deporte. Note que la condición es compuesta porque para identificar los registros de la tabla "inasistencias" necesitamos ambos campos. 4- Obtenga el nombre, deporte y las fechas de inasistencias de un determinado inscripto en un determinado deporte (3 registros) 5- Obtenga el nombre, deporte y las fechas de inasistencias de todos los inscriptos que pagaron la matrícula(4 registros) 45 - Combinación externa izquierda (left join) Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Cree las tablas: create table clientes ( codigo serial, nombre varchar(30), domicilio varchar(30), ciudad varchar(20), codigoprovincia smallint not null, primary key(codigo) create table provincias( codigo serial, nombre varchar(20), primary key (codigo) 2- Ingrese algunos registros para ambas tablas: insert into provincias (nombre) values('cordoba' insert into provincias (nombre) values('santa Fe' insert into provincias (nombre) values('corrientes' insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Lopez Marcos','Colon 111','Córdoba',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Perez Ana','San Martin 222','Cruz del Eje',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Garcia Juan','Rivadavia 333','Villa Maria',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Perez Luis','Sarmiento 444','Rosario',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Gomez Ines','San Martin 666','Santa Fe',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Torres Fabiola','Alem 777','La Plata',4 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Garcia Luis','Sucre 475','Santa Rosa',5
104 3- Muestre todos los datos de los clientes, incluido el nombre de la provincia 4- Realice la misma consulta anterior pero alterando el orden de las tablas 5- Muestre solamente los clientes de las provincias que existen en "provincias" (5 registros) 6- Muestre todos los clientes cuyo código de provincia NO existe en "provincias" ordenados por nombre del cliente (2 registros) 7- Obtenga todos los datos de los clientes de "Cordoba" (3 registros) 46 - Combinación externa derecha (right join) Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "provincias" donde registra los nombres de las provincias. 1-Cree las tablas: create table clientes ( codigo serial, nombre varchar(30), domicilio varchar(30), ciudad varchar(20), codigoprovincia smallint not null, primary key(codigo) create table provincias( codigo serial, nombre varchar(20), primary key (codigo) 2- Ingrese algunos registros para ambas tablas: insert into provincias (nombre) values('cordoba' insert into provincias (nombre) values('santa Fe' insert into provincias (nombre) values('corrientes' insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Lopez Marcos','Colon 111','Córdoba',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Perez Ana','San Martin 222','Cruz del Eje',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Garcia Juan','Rivadavia 333','Villa Maria',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Perez Luis','Sarmiento 444','Rosario',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Gomez Ines','San Martin 666','Santa Fe',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Torres Fabiola','Alem 777','La Plata',4 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values ('Garcia Luis','Sucre 475','Santa Rosa',5 3- Muestre todos los datos de los clientes, incluido el nombre de la provincia empleando un "right join".
105 4- Obtenga la misma salida que la consulta anterior pero empleando un "left join". 5- Empleando un "right join", muestre solamente los clientes de las provincias que existen en "provincias" (5 registros) 6- Muestre todos los clientes cuyo código de provincia NO existe en "provincias" ordenados por ciudad (2 registros) 47 - Combinación externa completa (full join) Primer problema: Un club dicta clases de distintos deportes. Almacena la información en una tabla llamada "deportes" en la cual incluye el nombre del deporte y el nombre del profesor y en otra tabla llamada "inscriptos" que incluye el documento del socio que se inscribe, el deporte y si la matricula está paga o no. 1- Cree las tablas: create table deportes( codigo serial, nombre varchar(30), profesor varchar(30), primary key (codigo) create table inscriptos( documento char(8), codigodeporte smallint not null, matricula char(1) --'s'=paga 'n'=impaga 2- Ingrese algunos registros para ambas tablas: insert into deportes(nombre,profesor) values('tenis','marcelo Roca' insert into deportes(nombre,profesor) values('natacion','marta Torres' insert into deportes(nombre,profesor) values('basquet','luis Garcia' insert into deportes(nombre,profesor) values('futbol','marcelo Roca' insert into inscriptos values(' ',3,'s' insert into inscriptos values(' ',3,'s' insert into inscriptos values(' ',3,'n' insert into inscriptos values(' ',2,'s' insert into inscriptos values(' ',2,'s' insert into inscriptos values(' ',4,'n' insert into inscriptos values(' ',5,'n' 3- Muestre todos la información de la tabla "inscriptos", y consulte la tabla "deportes" para obtener el nombre de cada deporte (6 registros) 4- Empleando un "left join" con "deportes" obtenga todos los datos de los inscriptos (7 registros) 5- Obtenga la misma salida anterior empleando un "rigth join". 6- Muestre los deportes para los cuales no hay inscriptos, empleando un "left join" (1 registro) 7- Muestre los documentos de los inscriptos a deportes que no existen en la tabla "deportes" (1 registro)
106 8- Emplee un "full join" para obtener todos los datos de ambas tablas, incluyendo las inscripciones a deportes inexistentes en "deportes" y los deportes que no tienen inscriptos (8 registros) 48 - Combinaciones cruzadas (cross join) Primer problema: Una agencia matrimonial almacena la información de sus clientes de sexo femenino en una tabla llamada "mujeres" y en otra la de sus clientes de sexo masculino llamada "varones". 1- Cree las tablas: create table mujeres( nombre varchar(30), domicilio varchar(30), edad int create table varones( nombre varchar(30), domicilio varchar(30), edad int 2- Ingrese los siguientes registros: insert into mujeres values('maria Lopez','Colon 123',45 insert into mujeres values('liliana Garcia','Sucre 456',35 insert into mujeres values('susana Lopez','Avellaneda 98',41 insert into varones values('juan Torres','Sarmiento 755',44 insert into varones values('marcelo Oliva','San Martin 874',56 insert into varones values('federico Pereyra','Colon 234',38 insert into varones values('juan Garcia','Peru 333',50 3- La agencia necesita la combinación de todas las personas de sexo femenino con las de sexo masculino. Use un "cross join" (12 registros) 4- Realice la misma combinación pero considerando solamente las personas mayores de 40 años (6 registros) 5- Forme las parejas pero teniendo en cuenta que no tengan una diferencia superior a 10 años (8 registros) Segundo problema: Una empresa de seguridad almacena los datos de sus guardias de seguridad en una tabla llamada "guardias". también almacena los distintos sitios que solicitaron sus servicios en una tabla llamada "tareas". 1- Cree las tablas: create table guardias( documento char(8), nombre varchar(30), sexo char(1), /* 'f' o 'm' */ domicilio varchar(30), primary key (documento)
107 create table tareas( codigo serial, domicilio varchar(30), descripcion varchar(30), horario char(2), /* 'AM' o 'PM'*/ primary key (codigo) 2- Ingrese los siguientes registros: insert into guardias values(' ','juan Perez','m','Colon 123' insert into guardias values(' ','alberto Torres','m','San Martin 567' insert into guardias values(' ','luis Ferreyra','m','Chacabuco 235' insert into guardias values(' ','lorena Viale','f','Sarmiento 988' insert into guardias values(' ','irma Gonzalez','f','Mariano Moreno 111' insert into tareas(domicilio,descripcion,horario) values('colon 1111','vigilancia exterior','am' insert into tareas(domicilio,descripcion,horario) values('urquiza 234','vigilancia exterior','pm' insert into tareas(domicilio,descripcion,horario) values('peru 345','vigilancia interior','am' insert into tareas(domicilio,descripcion,horario) values('avellaneda 890','vigilancia interior','pm' 3- La empresa quiere que todos sus empleados realicen todas las tareas. Realice una "cross join" (20 registros) 4- En este caso, la empresa quiere que todos los guardias de sexo femenino realicen las tareas de "vigilancia interior" y los de sexo masculino de "vigilancia exterior". Realice una "cross join" con un "where" que controle tal requisito (10 registros) 49 - Autocombinación Primer problema: Una agencia matrimonial almacena la información de sus clientes en una tabla llamada "clientes". 1- Cree la tabla: create table clientes( nombre varchar(30), sexo char(1),--'f'=femenino, 'm'=masculino edad int, domicilio varchar(30) 2- Ingrese los siguientes registros: insert into clientes values('maria Lopez','f',45,'Colon 123' insert into clientes values('liliana Garcia','f',35,'Sucre 456' insert into clientes values('susana Lopez','f',41,'Avellaneda 98' insert into clientes values('juan Torres','m',44,'Sarmiento 755' insert into clientes values('marcelo Oliva','m',56,'San Martin 874' insert into clientes values('federico Pereyra','m',38,'Colon 234' insert into clientes values('juan Garcia','m',50,'Peru 333' 3- La agencia necesita la combinación de todas las personas de sexo femenino con las de sexo masculino. Use un "cross join" (12 registros)
108 4- Obtenga la misma salida anterior pero realizando un "join". 5- Realice la misma autocombinación que el punto 3 pero agregue la condición que las parejas no tengan una diferencia superior a 5 años (5 registros) Segundo problema: Varios clubes de barrio se organizaron para realizar campeonatos entre ellos. La tabla llamada "equipos" guarda la información de los distintos equipos que jugarán. 1- Cree la tabla: create table equipos( nombre varchar(30), barrio varchar(20), domicilio varchar(30), entrenador varchar(30) 2- Ingrese los siguientes registros: insert into equipos values('los tigres','gral. Paz','Sarmiento 234','Juan Lopez' insert into equipos values('los leones','centro','colon 123','Gustavo Fuentes' insert into equipos values('campeones','pueyrredon','guemes 346','Carlos Moreno' insert into equipos values('cebollitas','alberdi','colon 1234','Luis Duarte' 3- Cada equipo jugará con todos los demás 2 veces, una vez en cada sede. Realice un "cross join" para combinar los equipos teniendo en cuenta que un equipo no juega consigo mismo (12 registros) 4- Obtenga el mismo resultado empleando un "join". 5- Realice un "cross join" para combinar los equipos para que cada equipo juegue con cada uno de los otros una sola vez (6 registros) 50 - Combinaciones y funciones de agrupamiento Primer problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos y en otra tabla llamada "ciudades" los nombres de las ciudades. 1- Cree las tablas: create table visitantes( nombre varchar(30), edad smallint, sexo char(1) default 'f', domicilio varchar(30), codigociudad smallint not null, mail varchar(30), montocompra decimal (6,2) create table ciudades( codigo serial,
109 nombre varchar(20), primary key(codigo) 2- Ingrese algunos registros: insert into ciudades(nombre) values('cordoba' insert into ciudades(nombre) values('carlos Paz' insert into ciudades(nombre) values('la Falda' insert into ciudades(nombre) values('cruz del Eje' insert into visitantes values ('Susana Molina', 35,'f','Colon 123', 1, null,59.80 insert into visitantes values ('Marcos Torres', 29,'m','Sucre 56', 1, insert into visitantes values ('Mariana Juarez', 45,'f','San Martin 111',2,null,23.90 insert into visitantes values ('Fabian Perez',36,'m','Avellaneda insert into visitantes values ('Alejandra Garcia',28,'f',null,2,null, insert into visitantes values ('Gaston insert into visitantes values ('Mariana Juarez',33,'f',null,2,null,90 3- Cuente la cantidad de visitas por ciudad mostrando el nombre de la ciudad (3 filas) 4- Muestre el promedio de gastos de las visitas agrupados por ciudad y sexo (4 filas) 5- Muestre la cantidad de visitantes con mail, agrupados por ciudad (3 filas) 6- Obtenga el monto de compra más alto de cada ciudad (3 filas) 51 - Combinación de más de dos tablas Primer problema: Un club dicta clases de distintos deportes. En una tabla llamada "socios" guarda los datos de los socios, en una tabla llamada "deportes" la información referente a los diferentes deportes que se dictan y en una tabla denominada "inscriptos", las inscripciones de los socios a los distintos deportes. Un socio puede inscribirse en varios deportes el mismo año. Un socio no puede inscribirse en el mismo deporte el mismo año. Distintos socios se inscriben en un mismo deporte en el mismo año. 1- Cree las tablas con las siguientes estructuras: create table socios( documento char(8) not null, nombre varchar(30), domicilio varchar(30), primary key(documento) create table deportes( codigo serial,
110 nombre varchar(20), profesor varchar(15), primary key(codigo) create table inscriptos( documento char(8) not null, codigodeporte smallint not null, anio char(4), matricula char(1),--'s'=paga, 'n'=impaga primary key(documento,codigodeporte,anio) 2- Ingrese algunos registros en "socios": insert into socios values(' ','ana Acosta','Avellaneda 111' insert into socios values(' ','betina Bustos','Bulnes 222' insert into socios values(' ','carlos Castro','Caseros 333' insert into socios values(' ','daniel Duarte','Dinamarca 44' 3- Ingrese algunos registros en "deportes": insert into deportes(nombre,profesor) values('basquet','juan Juarez' insert into deportes(nombre,profesor) values('futbol','pedro Perez' insert into deportes(nombre,profesor) values('natacion','marina Morales' insert into deportes(nombre,profesor) values('tenis','marina Morales' 4- Inscriba a varios socios en el mismo deporte en el mismo año: insert into inscriptos values (' ',3,'2006','s' insert into inscriptos values (' ',3,'2006','s' insert into inscriptos values (' ',3,'2006','n' 5- Inscriba a un mismo socio en el mismo deporte en distintos años: insert into inscriptos values (' ',3,'2005','s' insert into inscriptos values (' ',3,'2007','n' 6- Inscriba a un mismo socio en distintos deportes el mismo año: insert into inscriptos values (' ',1,'2006','s' insert into inscriptos values (' ',2,'2006','s' 7- Ingrese una inscripción con un código de deporte inexistente y un documento de socio que no exista en "socios": insert into inscriptos values (' ',0,'2006','s' 8- Muestre el nombre del socio, el nombre del deporte en que se inscribió y el año empleando diferentes tipos de join. 9- Muestre todos los datos de las inscripciones (excepto los códigos) incluyendo aquellas inscripciones cuyo código de deporte no existe en "deportes" y cuyo documento de socio no se encuentra en "socios". 10- Muestre todas las inscripciones del socio con documento " " Restricciones (foreign key) Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Cree las tablas "clientes" y "provincias":
111 create table clientes ( codigo serial, nombre varchar(30), domicilio varchar(30), ciudad varchar(20), codigoprovincia smallint, primary key(codigo) create table provincias( codigo serial, nombre varchar(20), primary key(codigo) En este ejemplo, el campo "codigoprovincia" de "clientes" es una clave foránea, se emplea para enlazar la tabla "clientes" con "provincias". 2- Intente agregar una restricción "foreign key" a la tabla "clientes" que haga referencia al campo "codigo" de "provincias" (No se puede porque "provincias" no tiene restricción "primary key" "unique") 3- Establezca una restricción "primary key" al campo "codigo" de "provincias" 4- Ingrese algunos registros para ambas tablas: insert into provincias values(1,'cordoba' insert into provincias values(2,'santa Fe' insert into provincias values(3,'misiones' insert into provincias values(4,'rio Negro' insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('perez Juan','San Martin 123','Carlos Paz',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('moreno Marcos','Colon 234','Rosario',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('acosta Ana','Avellaneda 333','Posadas',3 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('luisa Lopez','Juarez 555','La Plata',6 5- Intente agregar la restricción "foreign key" del punto 2 a la tabla "clientes" No se puede porque hay un registro en "clientes" cuyo valor de "codigoprovincia" no existe en "provincias". 6- Elimine el registro de "clientes" que no cumple con la restricción y establezca la restricción nuevamente. 7- Intente agregar un cliente con un código de provincia inexistente en "provincias". No se puede. 8- Intente eliminar el registro con código 3, de "provincias". No se puede porque hay registros en "clientes" al cual hace referencia. 9- Elimine el registro con código "4" de "provincias". Se permite porque en "clientes" ningún registro hace referencia a él. 10- Intente modificar el registro con código 1, de "provincias".
112 No se puede porque hay registros en "clientes" al cual hace referencia Restricciones foreign key en la misma tabla Primer problema: Una empresa registra los datos de sus clientes en una tabla llamada "clientes". Dicha tabla contiene un campo que hace referencia al cliente que lo recomendó denominado "referenciadopor". Si un cliente no ha sido referenciado por ningún otro cliente, tal campo almacena "null". 1- Creemos la tabla: create table clientes( codigo int, nombre varchar(30), domicilio varchar(30), ciudad varchar(20), referenciadopor int, primary key(codigo) 2- Ingresamos algunos registros: insert into clientes values (50,'Juan Perez','Sucre 123','Cordoba',null insert into clientes values(90,'marta Juarez','Colon 345','Carlos Paz',null insert into clientes values(110,'fabian Torres','San Martin 987','Cordoba',50 insert into clientes values(125,'susana Garcia','Colon 122','Carlos Paz',90 insert into clientes values(140,'ana Herrero','Colon 890','Carlos Paz',9 3- Intente agregar una restricción "foreign key" para evitar que en el campo "referenciadopor" se ingrese un valor de código de cliente que no exista. No se permite porque existe un registro que no cumple con la restricción que se intenta establecer. 4- Cambie el valor inválido de "referenciadopor" del registro que viola la restricción por uno válido. 5- Agregue la restricción "foreign key" que intentó agregar en el punto Intente agregar un registro que infrinja la restricción. No lo permite. 7- Intente modificar el código de un cliente que está referenciado en "referenciadopor". No se puede. 8- Intente eliminar un cliente que sea referenciado por otro en "referenciadopor". No se puede. 9- Cambie el valor de código de un cliente que no referenció a nadie. 10- Elimine un cliente que no haya referenciado a otros Restricciones foreign key (acciones) Primer problema:
113 Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Cree las tablas "clientes" y "provincias": create table clientes ( codigo serial, nombre varchar(30), domicilio varchar(30), ciudad varchar(20), codigoprovincia smallint, primary key(codigo) create table provincias( codigo serial, nombre varchar(20), primary key(codigo) 3- Ingrese algunos registros para ambas tablas: insert into provincias values(1,'cordoba' insert into provincias values(2,'santa Fe' insert into provincias values(3,'misiones' insert into provincias values(4,'rio Negro' insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('perez Juan','San Martin 123','Carlos Paz',1 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('moreno Marcos','Colon 234','Rosario',2 insert into clientes(nombre,domicilio,ciudad,codigoprovincia) values('acosta Ana','Avellaneda 333','Posadas',3 3- Establezca una restricción "foreign key" especificando la acción "en cascade" para actualizaciones y "no_action" para eliminaciones. 4- Intente eliminar el registro con código 3, de "provincias". No se puede porque hay registros en "clientes" al cual hace referencia y la opción para eliminaciones se estableció como "no action". 5- Modifique el registro con código 3, de "provincias". 6- Verifique que el cambio se realizó en cascada, es decir, que se modificó en la tabla "provincias" y en "clientes": select *from provincias; select *from clientes; 7- Intente modificar la restricción "foreign key" para que permita eliminación en cascada. Mensaje de error, no se pueden modificar las restricciones. 8- Intente eliminar la tabla "provincias". No se puede eliminar porque una restricción "foreign key" hace referencia a ella.
114 57 - Unión Primer problema: Un supermercado almacena en una tabla denominada "proveedores" los datos de las compañías que le proveen de mercaderías; en una tabla llamada "clientes", los datos de los comercios que le compran y en otra tabla "empleados" los datos de los empleados. 1- Cree las tablas: create table proveedores( codigo serial, nombre varchar (30), domicilio varchar(30), primary key(codigo) create table clientes( codigo serial, nombre varchar (30), domicilio varchar(30), primary key(codigo) create table empleados( documento char(8) not null, nombre varchar(20), apellido varchar(20), domicilio varchar(30), primary key(documento) 2- Ingrese algunos registros: insert into proveedores(nombre,domicilio) values('bebida cola','colon 123' insert into proveedores(nombre,domicilio) values('carnes Unica','Caseros 222' insert into proveedores(nombre,domicilio) values('lacteos Blanca','San Martin 987' insert into clientes(nombre,domicilio) values('supermercado Lopez','Avellaneda 34' insert into clientes(nombre,domicilio) values('almacen Anita','Colon 987' insert into clientes(nombre,domicilio) values('garcia Juan','Sucre 345' insert into empleados values(' ','federico','lopez','colon 987' insert into empleados values(' ','ana','marquez','sucre 333' insert into empleados values(' ','luis','perez','caseros 956' 3- El supermercado quiere enviar una tarjeta de salutación a todos los proveedores, clientes y empleados y necesita el nombre y domicilio de todos ellos. Emplee el operador "union" para obtener dicha información de las tres tablas. 4- Agregue una columna con un literal para indicar si es un proveedor, un cliente o un empleado y ordene por dicha columna Subconsultas como expresión Primer problema: Un profesor almacena el documento, nombre y la nota final de cada alumno de su clase en una tabla llamada "alumnos". 1- Créela create table alumnos(
115 documento char(8), nombre varchar(30), nota decimal(4,2), primary key(documento) 2-Ingrese algunos registros: insert into alumnos values(' ','ana Algarbe',5.1 insert into alumnos values(' ','bernardo Bustamante',3.2 insert into alumnos values(' ','carolina Conte',4.5 insert into alumnos values(' ','diana Dominguez',9.7 insert into alumnos values(' ','fabian Fuentes',8.5 insert into alumnos values(' ','gaston Gonzalez', Obtenga todos los datos de los alumnos con la nota más alta, empleando subconsulta. 2 registros. 4- Realice la misma consulta anterior pero intente que la consulta interna retorne, además del máximo valor de precio, el título. Mensaje de error, porque la lista de selección de una subconsulta que va luego de un operador de comparación puede incluir sólo un campo o expresión (excepto si se emplea "exists" o "in"). 5- Muestre los alumnos que tienen una nota menor al promedio, su nota, y la diferencia con el promedio. 3 registros. 6- Cambie la nota del alumno que tiene la menor nota por 4. 1 registro modificado. 7- Elimine los alumnos cuya nota es menor al promedio. 3 registros eliminados Subconsultas con in Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "ciudades" donde registra los nombres de las ciudades. 1- Cree la tabla "clientes" (codigo, nombre, domicilio, ciudad, codigociudad) y "ciudades" (codigo, nombre). Agregue una restricción "primary key" para el campo "codigo" de ambas tablas): create table ciudades( codigo serial, nombre varchar(20), primary key (codigo) create table clientes ( codigo serial, nombre varchar(30), domicilio varchar(30), codigociudad smallint not null, primary key(codigo)
116 2- Ingrese algunos registros para ambas tablas: insert into ciudades (nombre) values('cordoba' insert into ciudades (nombre) values('cruz del Eje' insert into ciudades (nombre) values('carlos Paz' insert into ciudades (nombre) values('la Falda' insert into ciudades (nombre) values('villa Maria' insert into clientes(nombre,domicilio,codigociudad) values ('Lopez Marcos','Colon 111',1 insert into clientes(nombre,domicilio,codigociudad) values ('Lopez Hector','San Martin 222',1 insert into clientes(nombre,domicilio,codigociudad) values ('Perez Ana','San Martin 333',2 insert into clientes(nombre,domicilio,codigociudad) values ('Garcia Juan','Rivadavia 444',3 insert into clientes(nombre,domicilio,codigociudad) values ('Perez Luis','Sarmiento 555',3 insert into clientes(nombre,domicilio,codigociudad) values ('Gomez Ines','San Martin 666',4 insert into clientes(nombre,domicilio,codigociudad) values ('Torres Fabiola','Alem 777',5 insert into clientes(nombre,domicilio,codigociudad) values ('Garcia Luis','Sucre 888',5 3- Necesitamos conocer los nombres de las ciudades de aquellos clientes cuyo domicilio es en calle "San Martin", empleando subconsulta. 3 registros. 4- Obtenga la misma salida anterior pero empleando join. 5- Obtenga los nombre de las ciudades de los clientes cuyo apellido no comienza con una letra específica, empleando subconsulta. 2 registros. 6- Pruebe la subconsulta del punto 5 separada de la consulta exterior para verificar que retorna una lista de valores de un solo campo Subconsultas any - some - all Primer problema: Un club dicta clases de distintos deportes a sus socios. El club tiene una tabla llamada "inscriptos" en la cual almacena el número de "socio", el código del deporte en el cual se inscribe y la cantidad de cuotas pagas (desde 0 hasta 10 que es el total por todo el año), y una tabla denominada "socios" en la que guarda los datos personales de cada socio. 1- Cree las tablas: create table socios( numero serial, documento char(8), nombre varchar(30), domicilio varchar(30), primary key (numero) create table inscriptos (
117 numerosocio int not null, deporte varchar(20) not null, cuotas smallint, primary key(numerosocio,deporte) 2- Ingrese algunos registros: insert into socios(documento,nombre,domicilio) values(' ','alberto Paredes','Colon 111' insert into socios(documento,nombre,domicilio) values(' ','carlos Conte','Sarmiento 755' insert into socios(documento,nombre,domicilio) values(' ','fabian Fuentes','Caseros 987' insert into socios(documento,nombre,domicilio) values(' ','hector Lopez','Sucre 344' insert into inscriptos values(1,'tenis',1 insert into inscriptos values(1,'basquet',2 insert into inscriptos values(1,'natacion',1 insert into inscriptos values(2,'tenis',9 insert into inscriptos values(2,'natacion',1 insert into inscriptos values(2,'basquet',default insert into inscriptos values(2,'futbol',2 insert into inscriptos values(3,'tenis',8 insert into inscriptos values(3,'basquet',9 insert into inscriptos values(3,'natacion',0 insert into inscriptos values(4,'basquet',10 3- Muestre el número de socio, el nombre del socio y el deporte en que está inscripto con un join de ambas tablas. 4- Muestre los socios que serán compañeros en tenis y también en natación (empleando subconsulta) 3 filas devueltas. 5- Vea si el socio 1 se ha inscripto en algún deporte en el cual se haya inscripto el socio 2. 3 filas. 6- Obtenga el mismo resultado anterior pero empleando join. 7- Muestre los deportes en los cuales el socio 2 pagó más cuotas que ALGUN deporte en los que se inscribió el socio 1. 2 registros. 8- Muestre los deportes en los cuales el socio 2 pagó más cuotas que TODOS los deportes en que se inscribió el socio 1. 1 registro. 9- Cuando un socio no ha pagado la matrícula de alguno de los deportes en que se ha inscripto, se lo borra de la inscripción de todos los deportes. Elimine todos los socios que no pagaron ninguna cuota en algún deporte. 7 registros.
118 62 - Subconsultas correlacionadas Primer problema: Un club dicta clases de distintos deportes a sus socios. El club tiene una tabla llamada "inscriptos" en la cual almacena el número de "socio", el código del deporte en el cual se inscribe y la cantidad de cuotas pagas (desde 0 hasta 10 que es el total por todo el año), y una tabla denominada "socios" en la que guarda los datos personales de cada socio. 1- Cree las tablas: create table socios( numero serial, documento char(8), nombre varchar(30), domicilio varchar(30), primary key (numero) create table inscriptos ( numerosocio int not null, deporte varchar(20) not null, cuotas smallint, primary key(numerosocio,deporte) 2- Ingrese algunos registros: insert into socios(documento,nombre,domicilio) values(' ','alberto Paredes','Colon 111' insert into socios(documento,nombre,domicilio) values(' ','carlos Conte','Sarmiento 755' insert into socios(documento,nombre,domicilio) values(' ','fabian Fuentes','Caseros 987' insert into socios(documento,nombre,domicilio) values(' ','hector Lopez','Sucre 344' insert into inscriptos values(1,'tenis',1 insert into inscriptos values(1,'basquet',2 insert into inscriptos values(1,'natacion',1 insert into inscriptos values(2,'tenis',9 insert into inscriptos values(2,'natacion',1 insert into inscriptos values(2,'basquet',default insert into inscriptos values(2,'futbol',2 insert into inscriptos values(3,'tenis',8 insert into inscriptos values(3,'basquet',9 insert into inscriptos values(3,'natacion',0 insert into inscriptos values(4,'basquet',10 3- Se necesita un listado de todos los socios que incluya nombre y domicilio, la cantidad de deportes a los cuales se ha inscripto, empleando subconsulta. 4 registros. 4- Se necesita el nombre de todos los socios, el total de cuotas que debe pagar (10 por cada deporte) y el total de cuotas pagas, empleando subconsulta. 4 registros. 5- Obtenga la misma salida anterior empleando join.
119 63 - Subconsultas (Exists y No Exists) Primer problema: Un club dicta clases de distintos deportes a sus socios. El club tiene una tabla llamada "inscriptos" en la cual almacena el número de "socio", el código del deporte en el cual se inscribe y la cantidad de cuotas pagas (desde 0 hasta 10 que es el total por todo el año), y una tabla denominada "socios" en la que guarda los datos personales de cada socio. 1- Cree las tablas: create table socios( numero serial, documento char(8), nombre varchar(30), domicilio varchar(30), primary key (numero) create table inscriptos ( numerosocio int not null, deporte varchar(20) not null, cuotas smallint, primary key(numerosocio,deporte) 2- Ingrese algunos registros: insert into socios(documento,nombre,domicilio) values(' ','alberto Paredes','Colon 111' insert into socios(documento,nombre,domicilio) values(' ','carlos Conte','Sarmiento 755' insert into socios(documento,nombre,domicilio) values(' ','fabian Fuentes','Caseros 987' insert into socios(documento,nombre,domicilio) values(' ','hector Lopez','Sucre 344' insert into inscriptos values(1,'tenis',1 insert into inscriptos values(1,'basquet',2 insert into inscriptos values(1,'natacion',1 insert into inscriptos values(2,'tenis',9 insert into inscriptos values(2,'natacion',1 insert into inscriptos values(2,'basquet',default insert into inscriptos values(2,'futbol',2 insert into inscriptos values(3,'tenis',8 insert into inscriptos values(3,'basquet',9 insert into inscriptos values(3,'natacion',0 insert into inscriptos values(4,'basquet',10 3- Emplee una subconsulta con el operador "exists" para devolver la lista de socios que se inscribieron en 'natacion'. 3 registros. 4- Busque los socios que NO se han inscripto en 'natacion' empleando "not exists". 1 registro. 5- Muestre todos los datos de los socios que han pagado todas las cuotas. 1 registro.
120 64 - Subconsulta simil autocombinación Primer problema: Un club dicta clases de distintos deportes a sus socios. El club tiene una tabla llamada "deportes" en la cual almacena el nombre del deporte, el nombre del profesor que lo dicta, el día de la semana que se dicta y el costo de la cuota mensual. 1- Cree la tabla: create table deportes( nombre varchar(15), profesor varchar(30), dia varchar(10), cuota decimal(5,2) 2- Ingrese algunos registros. Incluya profesores que dicten más de un curso: insert into deportes values('tenis','ana Lopez','lunes',20 insert into deportes values('natacion','ana Lopez','martes',15 insert into deportes values('futbol','carlos Fuentes','miercoles',10 insert into deportes values('basquet','gaston Garcia','jueves',15 insert into deportes values('padle','juan Huerta','lunes',15 insert into deportes values('handball','juan Huerta','martes',10 3- Muestre los nombres de los profesores que dictan más de un deporte empleando subconsulta. 4- Obtenga el mismo resultado empleando join. 5- Buscamos todos los deportes que se dictan el mismo día que un determinado deporte (natacion) empleando subconsulta. 6- Obtenga la misma salida empleando "join" Subconsulta en lugar de una tabla Primer problema: Un club dicta clases de distintos deportes. En una tabla llamada "socios" guarda los datos de los socios, en una tabla llamada "deportes" la información referente a los diferentes deportes que se dictan y en una tabla denominada "inscriptos", las inscripciones de los socios a los distintos deportes. Un socio puede inscribirse en varios deportes el mismo año. Un socio no puede inscribirse en el mismo deporte el mismo año. Distintos socios se inscriben en un mismo deporte en el mismo año. 1- Cree las tablas con las siguientes estructuras: create table socios( documento char(8) not null, nombre varchar(30), domicilio varchar(30), primary key(documento) create table deportes( codigo serial, nombre varchar(20),
121 profesor varchar(15), primary key(codigo) create table inscriptos( documento char(8) not null, codigodeporte smallint not null, año char(4), matricula char(1),--'s'=paga, 'n'=impaga primary key(documento,codigodeporte,año) 2- Ingrese algunos registros en las 3 tablas: insert into socios values(' ','ana Acosta','Avellaneda 111' insert into socios values(' ','betina Bustos','Bulnes 222' insert into socios values(' ','carlos Castro','Caseros 333' insert into socios values(' ','daniel Duarte','Dinamarca 44' insert into deportes(nombre,profesor) values('basquet','juan Juarez' insert into deportes(nombre,profesor) values('futbol','pedro Perez' insert into deportes(nombre,profesor) values('natacion','marina Morales' insert into deportes(nombre,profesor) values('tenis','marina Morales' insert into inscriptos values (' ',3,'2006','s' insert into inscriptos values (' ',3,'2006','s' insert into inscriptos values (' ',3,'2006','n' insert into inscriptos values (' ',3,'2005','s' insert into inscriptos values (' ',3,'2007','n' insert into inscriptos values (' ',1,'2006','s' insert into inscriptos values (' ',2,'2006','s' 3- Realice una consulta en la cual muestre todos los datos de las inscripciones, incluyendo el nombre del deporte y del profesor. Esta consulta es un join. 4- Utilice el resultado de la consulta anterior como una tabla derivada para emplear en lugar de una tabla para realizar un "join" y recuperar el nombre del socio, el deporte en el cual está inscripto, el año, el nombre del profesor y la matrícula Subconsulta (update - delete) Primer problema: Un club dicta clases de distintos deportes a sus socios. El club tiene una tabla llamada "inscriptos" en la cual almacena el número de "socio", el código del deporte en el cual se inscribe y si la matricula está o no paga, y una tabla denominada "socios" en la que guarda los datos personales de cada socio. 1- Cree las tablas: create table socios( numero serial, documento char(8), nombre varchar(30), domicilio varchar(30), primary key (numero) create table inscriptos (
122 numerosocio int not null, deporte varchar(20) not null, matricula char(1),-- 'n' o 's' primary key(numerosocio,deporte) 2- Ingrese algunos registros: insert into socios(documento,nombre,domicilio) values(' ','alberto Paredes','Colon 111' insert into socios(documento,nombre,domicilio) values(' ','carlos Conte','Sarmiento 755' insert into socios(documento,nombre,domicilio) values(' ','fabian Fuentes','Caseros 987' insert into socios(documento,nombre,domicilio) values(' ','hector Lopez','Sucre 344' insert into inscriptos values(1,'tenis','s' insert into inscriptos values(1,'basquet','s' insert into inscriptos values(1,'natacion','s' insert into inscriptos values(2,'tenis','s' insert into inscriptos values(2,'natacion','s' insert into inscriptos values(2,'basquet','n' insert into inscriptos values(2,'futbol','n' insert into inscriptos values(3,'tenis','s' insert into inscriptos values(3,'basquet','s' insert into inscriptos values(3,'natacion','n' insert into inscriptos values(4,'basquet','n' 3- Actualizamos la cuota ('s') de todas las inscripciones de un socio determinado (por documento) empleando subconsulta. 4- Elimine todas las inscripciones de los socios que deben alguna matrícula. 5 registros eliminados Subconsulta (insert) Primer problema: Un comercio que vende artículos de librería y papelería almacena la información de sus ventas en una tabla llamada "facturas" y otra "clientes". 1-Cree las tablas: create table clientes( codigo serial, nombre varchar(30), domicilio varchar(30), primary key(codigo) create table facturas( numero int not null, fecha date, codigocliente int not null, total decimal(6,2), primary key(numero)
123 2-Ingrese algunos registros: insert into clientes(nombre,domicilio) values('juan Lopez','Colon 123' insert into clientes(nombre,domicilio) values('luis Torres','Sucre 987' insert into clientes(nombre,domicilio) values('ana Garcia','Sarmiento 576' insert into clientes(nombre,domicilio) values('susana Molina','San Martin 555' insert into facturas values(1200,' ',1,300 insert into facturas values(1201,' ',2,550 insert into facturas values(1202,' ',3,150 insert into facturas values(1300,' ',1,350 insert into facturas values(1310,' ',3, El comercio necesita una tabla llamada "clientespref" en la cual quiere almacenar el nombre y domicilio de aquellos clientes que han comprado hasta el momento más de 500 pesos en mercaderías. Créela la tabla: create table clientespref( nombre varchar(30), domicilio varchar(30) 4- Ingrese los registros en la tabla "clientespref" seleccionando registros de la tabla "clientes" y "facturas". 5- Vea los registros de "clientespref": 68 - Vistas Primer problema: Un club dicta cursos de distintos deportes. Almacena la información en varias tablas. El director no quiere que los empleados de administración conozcan la estructura de las tablas ni algunos datos de los profesores y socios, por ello se crean vistas a las cuales tendrán acceso. 1- Crear las tablas: create table socios( documento char(8) not null, nombre varchar(40), domicilio varchar(30), primary key (documento) create table profesores( documento char(8) not null, nombre varchar(40), domicilio varchar(30), primary key (documento) create table cursos( numero serial, deporte varchar(20), dia varchar(15), documentoprofesor char(8),
124 primary key (numero) create table inscriptos( documentosocio char(8) not null, numero smallint not null, matricula char(1), primary key (documentosocio,numero) 2- Ingrese algunos registros para todas las tablas: insert into socios values(' ','fabian Fuentes','Caseros 987' insert into socios values(' ','gaston Garcia','Guemes 65' insert into socios values(' ','hector Huerta','Sucre 534' insert into socios values(' ','ines Irala','Bulnes 345' insert into profesores values(' ','ana Acosta','Avellaneda 231' insert into profesores values(' ','carlos Caseres','Colon 245' insert into profesores values(' ','daniel Duarte','Sarmiento 987' insert into profesores values(' ','esteban Lopez','Sucre 1204' insert into cursos(deporte,dia,documentoprofesor) values('tenis','lunes',' ' insert into cursos(deporte,dia,documentoprofesor) values('tenis','martes',' ' insert into cursos(deporte,dia,documentoprofesor) values('natacion','miercoles',' ' insert into cursos(deporte,dia,documentoprofesor) values('natacion','jueves',' ' insert into cursos(deporte,dia,documentoprofesor) values('natacion','viernes',' ' insert into cursos(deporte,dia,documentoprofesor) values('futbol','sabado',' ' insert into cursos(deporte,dia,documentoprofesor) values('futbol','lunes',' ' insert into cursos(deporte,dia,documentoprofesor) values('basquet','martes',' ' insert into inscriptos values(' ',1,'s' insert into inscriptos values(' ',3,'n' insert into inscriptos values(' ',6,null insert into inscriptos values(' ',1,'s' insert into inscriptos values(' ',4,'s' insert into inscriptos values(' ',8,'s' 3- Cree una vista en la que aparezca el nombre y documento del socio, el deporte, el día y el nombre del profesor. 4- Muestre la información contenida en la vista. 5- Realice una consulta a la vista donde muestre la cantidad de socios inscriptos en cada deporte ordenados por cantidad. 6- Muestre (consultando la vista) los cursos (deporte y día) para los cuales no hay inscriptos. 7- Muestre los nombres de los socios que no se han inscripto en ningún curso (consultando la vista)
125 8- Muestre (consultando la vista) los profesores que no tienen asignado ningún deporte aún. 9- Muestre (consultando la vista) el nombre y documento de los socios que deben matrículas. 10- Consulte la vista y muestre los nombres de los profesores y los días en que asisten al club para dictar sus clases. 11- Muestre la misma información anterior pero ordenada por día. 12- Muestre todos los socios que son compañeros en tenis los lunes Secuencias (create sequence- alter sequence - nextval - drop sequence) Primer problema: Una empresa registra los datos de sus empleados en una tabla llamada "empleados". 1 - Cree la secuencia "sec_legajoempleados" estableciendo el valor mínimo (1), máximo (999), valor inicial (100), valor de incremento (2) y no circular. 2- Cree la tabla: create table empleados( legajo bigint default nextval('sec_legajoempleados'), documento char(8) not null, nombre varchar(30) not null, primary key(legajo) 3 - Ingrese algunos registros: insert into empleados(documento,nombre) values (' ','Ana Acosta' insert into empleados(documento,nombre) values (' ','Betina Bustamante' insert into empleados(documento,nombre) values (' ','Carlos Caseros' insert into empleados(documento,nombre) values (' ','Diana Dominguez' insert into empleados(documento,nombre) values (' ','Estela Esper' 4 - Recupere los registros de la tabla empleados. 5 - Efectue un select de la secuencia. 6 - Elimine la secuencia y la tabla asociada a dicha secuencia. Segundo problema: Una empresa organiza un curso de computación (dispone de dos aulas), almacenar en una tabla inscriptos los datos del estudiante. Cada vez que se inscribe un alumno asignarlo a un aula en forma alternada (primero a la 1 y luego a la 2, luego nuevamente a la 1 y así sucesivamente)
126 1 - Crear una secuencia sec_codigoaulainscriptos (valor inicial 1, incremento 1, valor máximo 2 y debe ser circular) 2 - Crear la tabla inscriptos: create table inscriptos( documento char(8) not null, nombre varchar(30) not null, codigocurso int default nextval('sec_codigoaulainscriptos'), primary key(documento) 3 - Insertar algunos registros: insert into inscriptos(documento,nombre) values (' ','Rodriguez Pablo' insert into inscriptos(documento,nombre) values (' ','Mercado Ana' insert into inscriptos(documento,nombre) values (' ','Morello Luis' insert into inscriptos(documento,nombre) values (' ','Prado Juan' insert into inscriptos(documento,nombre) values (' ','Solis Maria' 4 - Imprimir todos los alumnos del curso Imprimir todos los alumnos del curso Funciones SQL Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio decimal(5,2), cantidad smallint, primary key(codigo) 2- Ingrese algunos registros: insert into medicamentos (nombre,laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('buscapina','roche',4.10,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('paracetamol 500','Bago',1.90,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('bayaspirina','bayer',2.10,150 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal jarabe','bayer',5.10, Implementar una función que retorne el precio promedio de la tabla medicamentos. 4- Imprimir el precio promedio de los medicamentos.
127 5- Imprimir los medicamentos que tienen un precio mayor al promedio Función SQL que no retorna dato (void) Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio decimal(5,2), cantidad smallint, primary key(codigo) 2- Ingrese algunos registros: insert into medicamentos (nombre,laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('buscapina','roche',4.10,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('paracetamol 500','Bago',1.90,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('bayaspirina','bayer',2.10,150 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal jarabe','bayer',5.10, Implementar una función que reciba el código de un medicamento y proceda a borrarlo. La función no retorna dato. 4- Proceder a llamar a la función. 5- Imprimir la tabla medicamentos Función SQL que retorna un dato compuesto. Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Cree la tabla con la siguiente estructura: create table medicamentos( codigo serial, nombre varchar(20), laboratorio varchar(20), precio decimal(5,2),
128 cantidad smallint, primary key(codigo) 2- Ingrese algunos registros: insert into medicamentos (nombre,laboratorio,precio,cantidad) values('sertal','roche',5.2,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('buscapina','roche',4.10,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal 500','Bayer',15.60,100 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('paracetamol 500','Bago',1.90,200 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('bayaspirina','bayer',2.10,150 insert into medicamentos (nombre,laboratorio,precio,cantidad) values('amoxidal jarabe','bayer',5.10, Implementar una función que retorne el registro completo del medicamento más caro. 4- Proceder a llamar a la función. 75 Implementar trigger en POSTGRESQL usando PL/PGsql Ahora agregar el lenguaje plpgsql en la base de datos y le indicamos la función plpgsql_call_handler que creamos con el usuario postgresql. CREATE LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler LANCOMPILER 'PL/pgSQL'; Lo anterior, muestra algo similar a esto: NOTICE: using pg_pltemplate information instead of CREATE LANGUAGE parameters CREATE LANGUAGE Una vez creado el lenguaje, generar el procedimiento almacenado que llamará el trigger que creado. Este procedimiento verifica que no se inserten más de 100 registros en una tabla llamada usuario, por tal motivo, debemos tener creada una tabla llamada usuario y que estar estructurada de la siguiente manera: CREATE TABLE usuario( id INTEGER NOT NULL PRIMARY KEY, nombre VARCHAR(80) NOT NULL Ahora, creamos el procedimiento: CREATE FUNCTION sp_max_100_registros() RETURNS trigger AS $trigger_max_100_registros$ DECLARE registro RECORD; BEGIN SELECT INTO registro COUNT(*) AS numregistros FROM usuario; IF registro.numregistros < 100 THEN
129 RETURN NEW; ELSE RAISE EXCEPTION 'No pueden existir más de 100 registros en la tabla usuario'; RETURN NULL; END IF; END; $trigger_max_100_registros$ LANGUAGE plpgsql; Como observa, debe asignar un nombre al procedimiento, que en este caso es sp_max_100_registros(), le indicamos que vamos a devolver un tipo de dato trigger y que tendrá el nombre de trigger_max_100_registros entre signos de "$". Posteriormente, declaramos una variable llamada registro en la sección de variables DECLARE y le indicamos que es de tipo RECORD ya que en esta variable se almacena el resultado de la consulta. Seguido de esta sección, colocamos la sección BEGIN, la cual coordina el flujo de nuestro procedimiento hasta encontrar una instrucción END que lo finalize. Entre las instrucciones BEGIN y END ejecutamos una sentencia SELECT que cuenta el número de registros en la tabla usuario. Dicha sentencia cuenta con la opción INTO, ya que es la que permite asignar el resultado a nuestra variable registro. Luego encontramos un IF con su respectivos THEN, ELSE y END IF, donde preguntamos por medio de la variable registro si obtuvo menos de 100 registros, si la condición es afirmativa, entonces devuelve una variable llamada NEW, la cual indica que puede ser insertado el registro en la tabla usuario, pero en caso contrario, entonces devuelve una excepción indicando que no pueden existir más de 100 registros en la tabla usuario. Por último indicamos el nombre del trigger entre signos de "$" que en el ejemplo es: trigger_max_100_registros y el lenguaje del procedimiento, que en este caso es plpgsql. Ya que contamos con el procedimiento almacenado, creamos nuestro trigger, y para hacer esto, debemos hacer lo siguiente: CREATE TRIGGER trigger_max_100_registros BEFORE INSERT ON usuario FOR EACH ROW EXECUTE PROCEDURE sp_max_100_registros( Con la declaración anterior creamos un TRIGGER llamado trigger_max_100_registros, el cual se ejecuta antes de realizar un INSERT sobre la tabla usuario para cada registro (FOR EACH ROW), y le indicamos que ejecute dicho procedimiento almacenado, sp_max_100_registros(). Ya tenemos creado el trigger y cada vez insertemos un registro, verifica si puede insertar dicho registro. Para borrar el trigger, lo primero que hay que hacer, es ejecutar la siguiente línea: DROP TRIGGER trigger_max_100_registros ON usuario; En la instrucción anterior indicamos el nombre del trigger que queremos borrar y sobre que tabla está referenciada. Una vez que borramos el trigger, también deberemos borrar su procedimiento almacenado, y esto lo haremos de esta forma: DROP FUNCTION sp_max_100_registros( Se puede observar, que en el comando anterior deberemos indicar el nombre del procedimiento y que este debe llevar los paréntesis que abren y cierra.
130 Ahora bien, pondré otro trigger, el cual se encarga de verificar que después de insertar en nuestra tabla usuario un registro cuyo nombre cuente con la palabra luis, ya no permita agregar más registros. El procedimiento es de esta manera: CREATE FUNCTION sp_sin_luis() RETURNS trigger AS $trigger_sin_luis$ BEGIN PERFORM * FROM usuario WHERE UPPER(nombre) LIKE UPPER('%luis%' IF NOT FOUND THEN RAISE NOTICE 'Se insertará el registro'; RETURN NEW; ELSE RAISE EXCEPTION 'No se insertará el registro'; RETURN NULL; END IF; END; $trigger_sin_luis$ LANGUAGE plpgsql; Y el trigger: CREATE TRIGGER trigger_sin_luis BEFORE INSERT OR UPDATE ON usuario FOR EACH ROW EXECUTE PROCEDURE sp_sin_luis( Entre las cosas diferentes del procedimiento de este nuevo trigger, es que no definimos la sección DECLARE, aparte en lugar de poner la sentencia SELECT ponemos la palabra PERFORM. La diferencia radica en que PERFORM se usa para cuando hacemos consultas en las cuales no vamos a usar el resultado de ésta. También otra diferencia es en la instrucción IF, ya que usamos la palabra NOT FOUND, la cual sirve para preguntar si no se encontraron registro en la consulta hecha. La última diferencia del procedimiento está dentro del IF, podemos observar que antes de devolver el nuevo registro (RETURN NEW), usamos la instrucción: RAISE NOTICE, y ésta nos permite mandar un mensaje a la salida estandar de notificación. La diferencia en la creación del trigger, es que también indicamos que se ejecute cuando se hagan UPDATE's. Por último, pondré un ejemplo, el cual se encarga de verificar que no se pueda insertar un registro en la tabla usuario que contenga la cadena luis. Procedimiento: CREATE FUNCTION sp_no_luis() RETURNS trigger AS $trigger_no_luis$ BEGIN IF UPPER(NEW.nombre) LIKE '%LUIS%' THEN RAISE EXCEPTION 'El registro contiene el nombre de luis'; RETURN NULL; ELSE RAISE NOTICE 'Se agregará el registro'; RETURN NEW; END IF; END; $trigger_no_luis$ LANGUAGE plpgsql; Trigger: CREATE TRIGGER trigger_no_luis BEFORE INSERT OR UPDATE ON usuario FOR EACH ROW EXECUTE PROCEDURE sp_no_luis(
131 La diferencia en este último, es que usamos la instrucción NEW para hacer la comparación. Esta instrucción contiene el nuevo registro y por consiguiente los datos de los campos ha insertar, los cuales podemos hacer referencia por medio del nombre del campo como se puede observar. Algo IMPORTANTE de mencionar, es que para poder usar la instrucción NEW u otra llamada OLD, es que cuando creemos el trigger, deberemos poner la instrucción FOR EACH ROW, ya que sin esta no se crearán estos elementos. Ejecutar el script siguiente /*Creación de la base de datos de pedidos*/ /* Server: postgres */ /* Fecha creación: 16 diciembre 2005 */ /* Fecha revisión: 26 enero 2006 */ /* poner como nombre de la base de datos username de linux*/ \c template1 drop database if exists pedidos; create database pedidos; /* poner como nombre de la base de datos antes*/ \connect pedidos /*Creación de las tablas*/ create table clientes ( id_cliente integer not null Primary key, nombre varchar(10) not null, calle varchar(10), ciudad varchar(10) create table empleados ( id_empleado integer not null primary key, nombre varchar(10) not null, calle varchar(10), ciudad varchar(10) create table productos ( id_producto integer not null primary key, nombre varchar(10) not null, existencias integer, precio integer not null
132 create table pedidos ( id_pedido integer not null primary key, id_cliente integer, -- se permiten valores nulos para probar el full outer join id_empleado integer, fecha_pedido date not null, foreign key (id_cliente) references clientes (id_cliente), foreign key (id_empleado) references empleados (id_empleado) create table detalles_pedido ( id_pedido integer not null, id_producto integer not null, cantidad integer not null, primary key (id_pedido,id_producto), foreign key (id_pedido) references pedidos(id_pedido), foreign key (id_producto) references productos(id_producto) y este otro script /* Script de inserción de datos en la base de datos de pedidos */ /* Servidor: postgresql */ /* Fecha: 23 de enero de 2006 */ /* Fecha revisión: 20 de abril de 2010 */ -- borro el contenido de las tablas por si acaso truncate detalles_pedido, pedidos cascade; -- ods a la vez --truncate pedidos cascade; truncate clientes cascade; truncate empleados cascade; delete from productos; -- más lento, equivalente a "truncate productos cascade;" -- y ahora a meter lo necesario INSERT INTO clientes (id_cliente,nombre,calle,ciudad) VALUES (1,'ALBERTO','ZUDO','GIJON'), (2,'PACO','JONES','AVILES'), (3,'PILI','BIDINOSA','MIERES'), (4,'PEPE','LOTAS','MIERES'), (5,'RAMON','ERIA','GIJON' copy empleados (id_empleado,nombre,calle,ciudad) from stdin csv; "301","EFREN","ETICO","GIJON" "302","JESUS","PENSO","AVILES" "303","MARIA","BAJA","MIERES" "304","ISA","LADA","MIERES" "305","LUIS","AMAN","MIERES" "306","BELEN","CERIA","MIERES" \.
133 -- los campos se delimitan por tabuladores COPY productos (id_producto,nombre,existencias,precio ) from stdin; 201 PATATAS PERAS MANZANAS PLATANOS NARANJAS \. INSERT INTO pedidos (id_pedido,id_cliente,id_empleado,fecha_pedido) VALUES (101,1,303,'1-SEP-2006' INSERT INTO pedidos (id_pedido,id_cliente,id_empleado,fecha_pedido) VALUES (102,1,303,'2-SEP-2006' INSERT INTO pedidos (id_pedido,id_cliente,id_empleado,fecha_pedido) VALUES (103,2,301,'1-SEP-2006' INSERT INTO pedidos (id_pedido,id_cliente,id_empleado,fecha_pedido) VALUES (104,4,301,'1-SEP-2006' INSERT INTO pedidos (id_pedido,id_cliente,id_empleado,fecha_pedido) VALUES (105,3,302,'1-SEP-2006' -- Para el siguiente pedido no se conoce el empleado INSERT INTO pedidos (id_pedido,id_cliente,fecha_pedido) VALUES (106,3,'1-OCT-2006' INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (101,201,15 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (101,202,105 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (101,203,170 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (102,201,100 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (102,203,40 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (103,204,31 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (103,201,21 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (104,201,111 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (104,204,15 INSERT INTO detalles_pedido (id_pedido,id_producto,cantidad) VALUES (105,201,11 ahora probar los siguientes trigger, en caso de ser necesario, modificar para su ejecución. 1. Trigger para actualizar el num_productos cuando se inserta un producto en detalles_pedido. 2. Trigger para actualizar el num_produtos cuando se borra un producto en detalles_pedido. 3. Trigger para comprobar las existencias ANTES de insertar la cantidad pedida. Si las existencias son 0 o null se anula la inserción. Si las existencias no cubre la cantidad pedida se modifica la cantidad por el total de existencias. 4. Trigger que actualiza las existencias en función de lo que se ha pedido. 5. Trigger que comprueba la cantidad en función de las existencias que se disponen. ANTES de realizar el update se comprueba las existencias cubre el pedido, siguiendo la misma política que cuando insertamos. 6. Justificar sus resultados.
134 76 Transacciones 1. Transaction Isolation El SQL estándar define cuatro niveles de aislamiento de transacciones, dependiendo de si se permite o no que aparezcan los siguientes fenómenos: Lectura sucia (dirty read): una transacción lee datos modificados por otra transacción concurrente aunque no haya realizado un COMMIT. Lectura No Repetible (nonrepeatable read): una transacción relee datos (que ya leyó antes) y encuentra que han sido modificados por otra transacción (que hizo COMMIT después de la primera lectura. Lectura fantasma (phantom read): una transacción vuelve a ejecutar un select y encuentra que el resultado ha variado. datos (que ya leyó antes) y encuentra que han sido modificados por otra transacción (que hizo COMMIT despuyés de la primera lectura, debido a que otra transacción cambió las condiciones e hizo un COMMIT. Los distintos niveles con sus restricciones asociadas se presentan en la siguiente tabla: Nivel de aislamiento Lectura sucia Lectura No Repetible Fantasma Read uncommitted ; Possible Possible Possible Read committed ; Not possible Possible Possible Repeatable read ; Not possible Not possible Possible Serializable ; Not possible Not possible Not possible Cuando ejecutamos una orden SQL, Postgres realiza un autocommit. Es decir la orden es una transacción en sí misma. Si lo que queremos es englobar un conjunto de órdenes dentro de una transacción debemos iniciar la transacción tanto con BEGIN TRANSACTION como con START TRANSACTION, cuya funcionalidad es la misma y cuya sintaxis viene dada por: BEGIN [ WORK TRANSACTION ] [ transaction_mode [,...] ] START TRANSACTION [ transaction_mode [,...] ] where transaction_mode is one of: ISOLATION LEVEL { SERIALIZABLE REPEATABLE READ READ COMMITTED READ UN READ WRITE READ ONLY También es posible utilizar la orden SET TRANSACTION para establecer el funcionamiento de la siguiente transacción, pero no afectará a las subsiguientes. Cuando se inicia una transacción definimos el tipo de acceso que vamos a realizar (READ WRITE o READ ONLY), así como el nivel de aislamiento que queremos. En el caso de Postgres los cuatro niveles se reducen a dos, para mantener coherencia con el sistema de concurrencia de tipo multiversión. Uno es Read commited (valor nivel por defecto) y el otro es Serializable. Cuando especificamos el nivel Read uncommited asocia el Read commited; y cuando especificamos el nivel Repeatable read asocia el Serializable. Para finalizar una transacción, utilizamos la orden COMMIT si queremos que quede
135 reflejo en la base de datos de nuestras operaciones. En caso de fracaso de la transacción o si queremos que no quede huella de las modificaciones realizadas por la transacción ejecutaremos un ROLLBACK. /* Script de inserción de datos en la base de datos de pedidos */ /* Servidor: postgres */ /* Fecha: 10 de mayo de 2010 */ /* Fecha revisión: */ /* TERMINAL A TERMINAL B*/ BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; id_producto = 202; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS update productos SET existencias = 222 where select * from productos where id_producto=202; id_producto nombre existencias precio PERAS END TRANSACTION; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; update productos SET existencias = 333 where id_producto = 202; COMMIT; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS select * from productos where id_producto=202; id_producto nombre existencias precio PERAS COMMIT; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
136 update productos SET existencias = 111 where id_producto = 202; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS select * from productos where id_producto=202; id_producto nombre existencias precio PERAS id_producto = 202; COMMIT; concurrent update update productos SET existencias = 222 where... No responde ERROR: could not serialise access due to BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; update productos SET existencias = 666 where id_producto = 202; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS id_producto = 202; ROLLBACK; select * from productos where id_producto=202; id_producto nombre existencias precio PERAS BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; update productos SET existencias = 222 where... No responde UPDATE 1 select * from productos where id_producto=202; id_producto nombre existencias precio PERAS
SQL. Lenguaje de Consulta Estructurado. Curso básico de SQL (Leire Urcola Carrera)
SQL Lenguaje de Consulta Estructurado Curso básico de SQL (Leire Urcola Carrera) Indice de contenidos Introducción Consultas de Selección Criterios de Selección Agrupamiento de Registros y funciones agregadas
MANUAL BÁSICO DEL LENGUAJE SQL
MANUAL BÁSICO DEL LENGUAJE SQL INTRODUCCIÓN A continuación se presentan lo que son comandos DLL y DML, las clausulas, lo operadores (lógicos y de comparación), funciones de agregado, consultas, tipos de
LENGUAJE DE CONSULTA ESTRUCTURADO (SQL)
Qué es una base de datos? Una base de datos (cuya abreviatura es BD) es una entidad en la cual se pueden almacenar datos de manera estructurada, con la menor redundancia posible. Diferentes programas y
Modulo I: Introducción Gestores de Bases De Datos
Modulo I: Introducción Gestores de Bases De Datos El SQL El SQL (Lenguaje de Consulta Estructurado Structure Query Language), es un lenguaje de consulta estructurado establecido claramente como el lenguaje
Tema 4: Dinámica del Modelo Relacional. El lenguaje SQL
Tema 4: Dinámica del Modelo Relacional. El lenguaje SQL Departamento de Ciencias de la Computación e Inteligencia Artificial UNIVERSIDAD DE SEVILLA Bases de Datos Curso 2009--10 1 El Lenguaje SQL El Lenguaje
Base de Datos. Docente: Ing. Francisco Rodríguez BASE DATOS. Resultados. Internet. Requerimientos
UNIVERSIDAD NACIONAL DE TRUJILLO ESCUELA DE ING. INDUSTRIAL Base de Datos Resultados Internet Requerimientos BASE DATOS Docente: Ing. Francisco Rodríguez Base de Datos Tema 6: El Lenguaje Estándar SQL
Las cláusulas son condiciones de modificación utilizadas para definir los datos que desea seleccionar o manipular.
Comandos SQL Existen dos tipos de comandos SQL: Los DLL que permiten crear y definir nuevas bases de datos, campos e índices. Los DML que permiten generar consultas para ordenar, filtrar y extraer datos
Introducción (3) o Breve Historia o Componentes del SQL Comandos Cláusulas Operadores lógicos Operadores de Comparación Funciones de Agregado
Introducción (3) o Breve Historia o Componentes del SQL Comandos Cláusulas Operadores lógicos Operadores de Comparación Funciones de Agregado Consultas de Selección (6) o Consultas Básicas o Devolver Literales
SQL para Access VB de manejandodatos.es Página 1
SQL para Access VB de manejandodatos.es Página 1 1.- INTRODUCCION El lenguaje de consulta estructurado (SQL) es un lenguaje de base de datos normalizado, utilizado por el motor de base de datos de Microsoft
INDICE. Tutorial de SQL por Claudio Casares. ASP-ADO Tutoriales de la Cueva Pedro Rufo http.//usuarios.tripod.es/smaug
INDICE Tutorial de SQL por Claudio Casares 1. Introducción 1.1 Componentes del SQL 1.2 Comandos 1.3 Cláusulas 1.4 Operadores Lógicos 1.5 Operadores de Comparación 1.6 Funciones de Agregado 2. Consultas
MANUAL BÁSICO DEL LENGUAJE SQL
MANUAL BÁSICO DEL LENGUAJE SQL ESCUELA COLOMBIANA DE INGENIERÍA JULIO GARAVITO LABORATORIO DE INFORMÁTICA BOGOTÁ D. C. 2007-2 TABLA DE CONTENIDO INTRODUCCIÓN... 3 1. COMANDOS... 4 1.1 Comandos DLL... 4
Curso de SQL. Introducción. Breve Historia. Componentes del SQL. Comandos
Curso de SQL Introducción El lenguaje de consulta estructurado (SQL) es un lenguaje de base de datos normalizado, utilizado por los diferentes motores de bases de datos para realizar determinadas operaciones
1.3 Cláusulas Las cláusulas son condiciones de modificación utilizadas para definir los datos que desea seleccionar o manipular.
1 - Introducción 2 - Consultas de selección 3 - Criterios de selección 4 - Agrupamiento de registros 5 - Consultas de acción 6 - Tipos de datos 7 - Subconsultas 8 - Consultas de referencias cruzadas 9
Programación en SQL con PostgreSQL
Programación en SQL con PostgreSQL Francisco Alonso Sarría 1 Introducción El lenguaje estructurado de consultas (SQL) es un lenguaje de base de datos normalizado, utilizado por la gran mayoría de los servidores
1. Lenguaje de Definición de Datos. 2. Lenguaje de Manipulación de. Datos. M. C. Gustavo Alfonso Gutiérrez Carreón
1. Lenguaje de Definición de Datos 2. Lenguaje de Manipulación de Datos M. C. Gustavo Alfonso Gutiérrez Carreón Los 'sistemas de gestión de bases de datos (en inglés database management system, abreviado
CONSULTAS BASICAS EN SQL SERVER
CONSULTAS BASICAS EN SQL SERVER CONSULTAS DE SELECCION Las consultas de selección se utilizan para indicar al motor de datos que devuelva información de las bases de datos, esta información es devuelta
Introducción: Cláusulas: Las cláusulas son condiciones de modificación utilizadas para definir los datos que desea seleccionar o manipular.
Tema 10 El SQL en General. Introducción. Consultas de Selección. Agrupamiento de Registros y Funciones Agregadas. Consultas Actualizadas. Tipo de Datos. Subconsultas. Estructuras de Tablas. Consultas con
INSTITUTO SUPERIOR TECNOLÓGICO NORBERT WIENER
INSTITUTO SUPERIOR TECNOLÓGICO NORBERT WIENER ASIGNATURA: Aplicativos III (SQL Server Usuario) PROGRAMA: S3C Lima-Perú 2 MICROSOFT SQL SERVER INTRODUCCION SQL Server es un sistema administrador para Bases
GESTORES GESTORES DE BASES DE DATOS
GESTORES GESTORES DE BASES DE DATOS Existen varios tipos de Sistemas gestores de bases de datos SGBD, según el modelo de datos que utilizan. Son estos: bases jerárquica, en red, relacional, y bases de
A.1. Definiciones de datos en SQL
A.1. Definiciones de datos en SQL Las Sentencias del lenguaje de definición de datos (DDL) que posee SQL operan en base a tablas. Las Principales sentencias DDL son las siguientes: CREATE TABLE DROP TABLE
ÍNDICE INTRODUCCIÓN...17
ÍNDICE INTRODUCCIÓN...17 CAPÍTULO 1. ORACLE 11g Y EL GRID COMPUTING...19 1.1 CONCEPTO DE GRID COMPUTING...19 1.2 ORACLE GRID COMPUTING...20 1.2.1 Almacenamiento eficiente de la información...21 1.2.2 Utilización
Tema 7. Elaboración de consultas básicas de selección. Lenguajes de bases de datos. SQL básico 15/12/2011
Lenguajes de bases de datos Tema 7 Elaboración de consultas básicas de selección En esta unidad se abordan cuestiones que, aunque están definidas por el estándar ANSI/ISO SQL, no están asumidas al 100%
La forma básica de la instrucción SELECT consta de tres cláusulas SELECT, FROM y WHERE (donde)
La sintaxis básica de una consulta de selección es la siguiente: SELECT Campos FROM nombre_tabla; La forma básica de la instrucción SELECT consta de tres cláusulas SELECT, FROM y WHERE (donde) SELECT
CONSULTAS CON SQL. 3. Hacer clic sobre el botón Nuevo de la ventana de la base de datos. Aparecerá el siguiente cuadro de diálogo.
CONSULTAS CON SQL 1. Qué es SQL? Debido a la diversidad de lenguajes y de bases de datos existentes, la manera de comunicar entre unos y otras sería realmente complicada a gestionar de no ser por la existencia
MANUAL BÁSICO DE MYSQL
MANUAL BÁSICO DE MYSQL ESCUELA COLOMBIANA DE INGENIERÍA JULIO GARAVITO LABORATORIO DE INFORMÁTICA BOGOTÁ D. C. 2007-2 TABLA DE CONTENIDO MANUAL BÁSICO DE MYSQL... 1 INTRODUCCIÓN... 3 1. CONECTARSE CON
Uso de Disparadores. Miguel Angel Garduño Cordova Isaac Méndez Hernández
Reporte Uso de Disparadores Catedrático: Alumnos: Ing. María Elena Reyes Castellanos Miguel Angel Garduño Cordova Isaac Méndez Hernández Índice General Índice de tablas 2 Introducción 4 Objetivo 4 Desarrollo
Procedimientos para agrupar y resumir datos
Procedimientos para agrupar y resumir datos Contenido Introducción Presentación de los primeros n valores Uso de funciones de agregado 4 Fundamentos de GROUP BY 8 Generación de valores de agregado dentro
MANUAL BÁSICO DE POSTGRESQL
MANUAL BÁSICO DE POSTGRESQL ESCUELA COLOMBIANA DE INGENIERÍA JULIO GARAVITO LABORATORIO DE INFORMÁTICA BOGOTÁ D. C. 2007-2 TABLA DE CONTENIDO INTRODUCCIÓN... 3 1. AUTENTICACIÓN EN POSTGRESQL... 4 1.1 Autenticación
PROPIEDADES DE LOS CAMPOS. Cada campo de una tabla dispone de una serie de características que proporcionan un control
PROPIEDADES DE LOS CAMPOS Cada campo de una tabla dispone de una serie de características que proporcionan un control adicional sobre la forma de funcionar del campo. Las propiedades aparecen en la parte
LABORATORIO Nº 8 FILTROS EN EXCEL
OBJETIVO Mejorar el nivel de comprensión y el manejo de las destrezas del estudiante para utilizar filtros en Microsoft Excel. 1) FILTRAR INFORMACIÓN Para agregar un filtro a una tabla se debe seleccionar
LENGUAJE DE CONSULTA ESTRUCTURADO - SQL CONTENIDO
LENGUAJE DE CONSULTA ESTRUCTURADO - SQL 1. TIPOS DE DATOS 2. COMANDOS DDL 2.1 Créate 2.2 Drop 2.3 Alter 3. COMANDOS DML 3.1 Select 3.2 Insert 3.3 Update 3.4 Delete 4. CLAUSULAS 4.1 From 4.2 Where 4.3 Having
LENGUAJE DE MANIPULACIÓN DE DATOS
LENGUAJE DE MANIPULACIÓN DE DATOS Las instrucciones de DML funcionan con los datos de la base de datos. Mediante estas instrucciones puede cambiarlos o recuperar información. Las instrucciones de DML incluyen:
Tablas en vista hoja de datos
Contenido 1. Comprender lo que son las columnas en hojas de datos... 2 2. Agregar una columna mediante la vista Hoja de datos... 3 3. Quitar una columna mediante la vista Hoja de datos... 3 4. Agregar
Qué es una tabla dinámica? Para qué sirve una tabla dinámica?
Gracias a las múltiples solicitudes de alumnos, me he propuesto realizar este manual a modo de entregar una guía base y una ayuda de memoria para todos aquellos que trabajan con esta herramienta. He decidido
SENTENCIAS Y CONSULTAS EN SQL SERVER
SENTENCIAS Y CONSULTAS EN SQL SERVER En esta sección nos preocuparemos por conocer, las consultas en SQL que describiremos aquí. Para eso haremos un pequeño de las palabras claves que se utilizan en SQL,
Está basado en el álgebra y en el cálculo relacional.
SQL DML. Introducción SQL. QUÉ ES. SQL (Structured Query Language, Lenguaje Estructurado de Consultas): Lenguaje que permite expresar operaciones diversas (aritméticas, combinatorias, lógicas, selección
Dependiendo de las tareas, podemos clasificar las sentencias SQL en dos tipos:
CONTENIDO. 1. INTRODUCCIÓN 2. TIPOS DE SENTENCIAS SQL 3. TIPOS DE DATOS 4. SQL PLUS 5. CONSULTAS DE DATOS 6. RESTRICCIÓN Y CLASIFICACIÓN DE LOS DATOS 7. FUNCIONES A NIVEL DE FILA 8. VISUALIZACIÓN DE DATOS
Oracle Database: Introducción a SQL
Oracle University Contact Us: 001-855-844-3881 Oracle Database: Introducción a SQL Duration: 5 Days What you will learn La comprensión de los conceptos básicos de las bases de datos relacionales garantiza
Bases de datos: Lenguaje de consultas SQL
Bases de datos: Lenguaje de consultas SQL EMPEZAR LA CASA POR EL TEJADO Del código máquina a los lenguajes de alto nivel. Img 0. Del código máquina al lenguaje de alto nivel. Creación propia. De los sistemas
SQL Server 2000. FEMEPA SQL Server 2000
FEMEPA Partes del SQL El lenguaje SQL está compuesto de varios sub-lenguajes, entre los cuales destacan los tres siguientes: DML. Lenguaje de definición de datos. Todas las sentencias de manipulación de
Structured Query Language (SQL) Fundamentos de Bases de Datos InCo - 2011
Structured Query Language () Fundamentos de Bases de Datos InCo - Un poco de historia Lenguajes de consulta relacionales: SEQUEL (IBM-1970) QUEL (Ingres-1970) QBE (IBM-1970) es el lenguaje comercial más
LENGUAJE SQL. Bárbula, Febrero de 2007. Historia y Definición
LENGUAJE Integrantes: Ceci Vanessa Paredes Oswaldo Rodríguez Aury Bárbula, Febrero de 2007 : Es una herramienta para organizar, gestionar y recuperar datos almacenados en una base de datos. funciona con
Computación II. Introducción a Visual Basic
Computación II Introducción a Visual Basic Introducción a Visual Basic Microsoft Visual Basic es un conjunto de herramientas que posibilitan el desarrollo de aplicaciones para Windows de una manera rápida
CONSULTAS DE RESUMEN SQL SERVER 2005. Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE
CONSULTAS DE RESUMEN SQL SERVER 2005 Manual de Referencia para usuarios Salomón Ccance CCANCE WEBSITE CONSULTAS DE RESUMEN Una de las funcionalidades de la sentencia SELECT es el permitir obtener resúmenes
Análisis y Manejo de datos en Excel 2013 con tablas, funciones y tablas dinámicas
Análisis y Manejo de datos en Excel 2013 con tablas, funciones y tablas dinámicas José Mauricio Flores Selecciona la imagen para entrar Capítulo 1 Fórmulas y Funciones Continuar Fórmulas y Funciones Las
BASE DE DATOS ARTICULOS DE COMPUTACION.
BASE DE DATOS ARTICULOS DE COMPUTACION. Ejercicio 1. Agregar una Tabla Clientes: la cual contenga los siguientes campos: cedula, nombre, apellido, teléfono. Ejercicio 2. Agregarle cinco registros a la
Unidad III: Lenguaje de manipulación de datos (DML) 3.1 Inserción, eliminación y modificación de registros
Unidad III: Lenguaje de manipulación de datos (DML) 3.1 Inserción, eliminación y modificación de registros La sentencia INSERT permite agregar nuevas filas de datos a las tablas existentes. Está sentencia
Bases de datos: Sistemas de bases de datos:
Bases de datos: Sistemas de bases de datos: Un sistema de bases de datos es básicamente un sistema para archivar en computador, es decir, es un sistema computarizado cuyo propósito general es mantener
Vamos a profundizar un poco sobre los distintos tipos de datos que podemos introducir en las celdas de una hoja de cálculo
Tipos de datos. Vamos a profundizar un poco sobre los distintos tipos de datos que podemos introducir en las celdas de una hoja de cálculo Valores Constantes: Es un dato que se introduce directamente en
UNIDAD 2- LA CREACIÓN DE TABLAS EN ACCESS 2010
2. CREACIÓN DE TABLAS Cuando se crea una base de datos, los datos se almacenan en tablas, que son listas de filas y columnas basadas en temas. Siempre debe empezar a diseñar una base de datos creando primero
SINTAXIS DE SQL-92. <definición de esquema >::= CREATE SCHEMA <cláusula de nombre de esquema> [ <elemento de esquema>... ]
SINTAXIS DE SQL-92 Introducción: Se presenta brevemente un resumen de la sintaxis de SQL según el estándar ISO 9075 (SQL- 92), dividido en tres partes: - Lenguaje de Definición de Daots (LDD), - Lenguaje
Integridad Referencial. Restricciones (constraints)
Integridad Referencial Restricciones (constraints) Integridad de Referencial Integridad referencial: asegura la integridad entre las llaves foráneas y primarias (relaciones padre/hijo). Existen cuatro
MICROSOFT ACCESS 2007 (COMPLETO)
MICROSOFT ACCESS 2007 (COMPLETO) Descripción del funcionamiento del programa de gestión de bases de datos Microsoft Access 2007, estudiando los conceptos fundamentales de las bases de datos y explicando
Ministerio de Educación. Base de datos en la Enseñanza. Open Office. Módulo 5: Informes
Ministerio de Educación Base de datos en la Enseñanza. Open Office Módulo 5: Informes Instituto de Tecnologías Educativas 2011 Informes Los informes son la herramienta encargada de presentar los datos
ESCUELA DE INFORMÁTICA
TÉCNICO EN SISTEMAS LABORAL SUBMODULO TEMA 1 (Visual Basic for Application) Microsoft VBA (Visual Basic for Applications) es el lenguaje de macros de Microsoft Visual Basic que se utiliza para programar
ORACLE 10g. Descripción A QUIEN VA DIRIGIDO?
ORACLE 10g Descripción A QUIEN VA DIRIGIDO? Está dirigido a estudiantes y profesionista que desee conocer la tecnología Oracle, así como realizar extracción de datos, creación de objetos y administración
Elementos de un programa en C
Elementos de un programa en C Un programa en C consta de uno o más archivos. Un archivo es traducido en diferentes fases. La primera fase es el preprocesado, que realiza la inclusión de archivos y la sustitución
Access SQL: DDL y DML. Una empresa de Ingeniería precisa una base de datos para la gestión de sus proyectos.
SGBD y SQL Access SQL: DDL y DML Ejercicio Una empresa de Ingeniería precisa una base de datos para la gestión de sus proyectos. Necesita almacenar información acerca de sus empleados y los proyectos en
SUB CONSULTAS EN SQL IMPORTACIÓN Y EXPORTACIÓN DE TABLAS DE A OTRA PLATAFORMA
SUB CONSULTAS EN SQL IMPORTACIÓN Y EXPORTACIÓN DE TABLAS DE A OTRA PLATAFORMA 5 Sub Consultas en SQL Importación y exportación de SQL a otra plataforma C O N T E N I D O 1. Sub consultas en SQL 2. Importación
ÍNDICE. Introducción... Capítulo 1. Novedades de Access 2013... 1
Introducción... XIII Capítulo 1. Novedades de Access 2013... 1 Nuevas posibilidades de cifrado, compactación y reparación de archivos... 1 Trabajo en la nube... 2 Compartir la información... 3 Guardar
Diseña y Administra Bases de Datos Guía de Estudio
Diseña y Administra Bases de Datos Guía de Estudio Responde las preguntas que se te plantean Ordena los siguientes códigos: A. and edad=18 C. from clientes D. Select E. nombre, edad
CREACIÓN Y MANEJO DE TABLAS Instructivo N 1
CREACIÓN Y MANEJO DE TABLAS Instructivo N 1 CREACIÓN DE TABLAS 1. QUÉ ES UNA TABLA? Para Excel una tabla es un conjunto de datos organizados en columnas y filas, donde las columnas representan los campos
Sesión No. 10. Contextualización INFORMÁTICA 1. Nombre: Gestor de Base de Datos (Access)
INFORMÁTICA INFORMÁTICA 1 Sesión No. 10 Nombre: Gestor de Base de Datos (Access) Contextualización Microsoft Access es un sistema de gestión de bases de datos, creado para uso personal y de pequeñas organizaciones,
Pre-Taller Gestión de Privilegios de Usuarios 2. Manipulación de Vistas 3. Creación y manipulación de Triggers (Introducción al uso de PL/pgsql)
BASES DE DATOS Facyt-UC Pre-Taller 2 1. Gestión de Privilegios de Usuarios 2. Manipulación de Vistas 3. Creación y manipulación de Triggers (Introducción al uso de PL/pgsql) 1. Gestión de Privilegios de
Características del lenguaje SQL
Lenguaje SQL Características del lenguaje SQL Es el lenguaje estándar para realizar operaciones en bases de datos relacionales. Instrucciones: SELECT Consulta. Su implementación está basada en álgebra
m046a Curso Consultando SQL Server 2005/2008 con Transact-SQL, 15 h
L1. ANSI SQL SQL, STANDS STRUCTURED QUERY LANGUAGE ANSI SQL 9 2 ESTANDARD SQL LENGUAJE DBMS RELACIONALES SQL SERVER 2005/2008, DBMS MICROSOFT TRANSACT SQL (T-SQL) LENGUAJE SQL SERVER 2005/2008 T-SQL SE
UNIDAD 1.- PARTE 1 MANIPULACIÓN AVANZADA DE DATOS CON SQL. BASES DE DATOS PARA APLICACIONES. Xochitl Clemente Parra Armando Méndez Morales
UNIDAD 1.- PARTE 1 MANIPULACIÓN AVANZADA DE DATOS CON SQL. BASES DE DATOS PARA APLICACIONES Xochitl Clemente Parra Armando Méndez Morales Práctica preliminar Crear la siguiente base de datos de prácticas
Una base de datos de Access puede estar conformada por varios objetos, los más comunes son los siguientes:
MICROSOFT ACCESS DEFINICIÓN MS Access es un programa para manejar bases de datos. Una base de datos es un conjunto de datos de un determinado tema o contexto, almacenados de forma sistemática, para obtener
ACCESS XP. Objetivos. Duración. 64 horas. Contenidos. Módulo 1: Introducción. Parte 1 Bienvenida Certificado MOUS Resumen
ACCESS XP Objetivos Aprender todas las funciones del programa Access XP para la gestión de Bases de Datos. Conocer la terminología del programa y los elementos que se utilizan en la aplicación Trabajar
TEMA 10. INTRODUCCCIÓN A SQL. CONSULTAS BASADAS EN UNA TABLA
1 TEMA 10. INTRODUCCCIÓN A SQL. CONSULTAS BASADAS EN UNA TABLA 1. Definición de SQL. Características 2. Selección del origen de los datos. Cláusula FROM 3. Selección de columnas. Columnas calculadas 4.
TEMA. Sistema de Gestión de Bases de Datos. Sistemas Avanzados de Recuperación de Información (SARI) 2008-2009
TEMA Sistema de Gestión de Bases de Datos Sistemas Avanzados de Recuperación de Información (SARI) 2008-2009 Jorge Morato Lara Sonia Sánchez- Índice 1. Tema - Recuperación de la Información en Internet
Qué más puedo hacer en el cuadro de búsqueda?
Guía de usuario Búsquedas básicas Puedes hacer búsquedas en Primo muy fácilmente. Sólo escribe la palabra o las palabras que estés buscando y pulsa en el botón Buscar. NOTA: Primo asume que estás buscando
Crear una tabla dinámica
Introducción En este manual de referencia se explican los procedimientos para crear, administrar y personalizar tablas dinámicas y gráficos dinámicos. Los ejemplos ilustrativos de este material están basados
SQL (Structured Query Language)
SQL (Structured Query Language) El lenguaje de consulta estructurado o SQL (por sus siglas en inglés Structured Query Language) es un lenguaje declarativo de acceso a bases de datos relacionales que permite
Programación en Visual Basic Ricardo Rodríguez García
Manual Básico de Programación en Visual Basic 1.- Estructura de un proyecto Visual Basic Los programas o aplicaciones desarrolladas en Visual Basic van a constituir un único paquete que denominaremos proyecto.
UNIVERSIDAD AUTONOMA DE LOS ANDES UNIANDES LENGUAJE SQL. SQL es un estándar un lenguaje estructurado para consultas
LENGUAJE SQL Que es SQL? SQL es un estándar un lenguaje estructurado para consultas SQL te permite acceder y manejar bases de datos SQL es un Estándar (ANSI American National Standards Institute) Que puede
Java Avanzado. Guía 1. Java Avanzado Facultad de Ingeniería. Escuela de computación.
Java Avanzado. Guía 1 Java Avanzado Facultad de Ingeniería. Escuela de computación. Java Avanzado. Guía 2 Introducción Este manual ha sido elaborado para orientar al estudiante de Java Avanzado en el desarrollo
2. EXPRESIONES 3. OPERADORES Y OPERANDOS 4. INDENTIFICADORES COMO LOCALIDADES DE MEMORIA
CONTENIDOS: 1. TIPOS DE DATOS 2. EXPRESIONES 3. OPERADORES Y OPERANDOS 4. INDENTIICADORES COMO LOCALIDADES DE MEMORIA OBJETIO EDUCACIONAL: El alumno conocerá las reglas para cambiar fórmulas matemáticas
El Lenguaje SQL TEMA V. Grupo de Bas ses de Datos Avanzadas Univ. Carlo os III de Madrid. V.1 SQL como Lenguaje de Definición de Datos
Grupo de Bases de Datos Avanzadas Univ. Carlos III de Madrid Índice V.1 Introducción V.1 SQL como Lenguaje de V.1.1 Definición del esquema V.1.2 Evolución del esquema V.2 SQL como Lenguaje de Manipulación
El lenguaje SQL es un lenguaje estándar para el acceso y
1. INTRODUCCIÓN El lenguaje SQL es un lenguaje estándar para el acceso y manipulación de bases de datos relacionales como SQL Server. Esto quiere decir que aprender SQL es algo indispensable para cualquier
Operadores aritméticos: suma (+), resta (-), producto (*), cociente (/) y potencia (**).
TEMA 3 TRANSFORMACIÓN DE DATOS En ocasiones es necesario crear nuevas variables a partir de otras ya existentes o modificarlas para poder explotarlas de forma más adecuada. Esto se realiza mediante las
1. DML. Las subconsultas
1.1 Introducción 1. DML. Las subconsultas Una subconsulta es una consulta que aparece dentro de otra consulta o subconsulta en la lista de selección, en la cláusula WHERE o HAVING, originalmente no se
CONSULTAS SIMPLES SQL SERVER 2005. Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE
CONSULTAS SIMPLES SQL SERVER 2005 Manual de Referencia para usuarios Salomón Ccance CCANCE WEBSITE CONSULTAS SIMPLES Vamos a empezar por la instrucción que más se utiliza en SQL, la sentencia SELECT. La
El lenguaje C. 1. Identificadores, constantes y variables
Principios de Programación El lenguaje C 1. Identificadores, constantes y variables 1.1. Conceptos de memoria Los nombres de variable como x, y, suma corresponden a localizaciones o posiciones en la memoria
FÓRMULAS Y FUNCIONES
Centro de Estudios Empresariales 1 FÓRMULAS Y FUNCIONES Una fórmula nos permite calculas rápidamente valores directos introducidos en una celda y operar con valores previamente introducidos en otras celdas,
APÉNDICE D. INTRODUCCIÓN A SQL
APÉNDICE D. INTRODUCCIÓN A SQL D.1 INTRODUCCIÓN. CONCEPTOS PREVIOS D.1.1 Base de Datos Relacional Conjunto de Datos que el usuario percibe como una colección de tablas. La visión tabular de los datos es
Bases de Datos Relacionales con Base de OpenOffice y consultas SQL para Tecnología de la Información.
Bases de Datos Relacionales con Base de OpenOffice y consultas SQL para Tecnología de la Información. 1 Introducción Como ya sabes las bases de datos (BD) son la mejor forma de almacenar y trabajar con
LENGUAJE SQL. En Mysql se utiliza un subconjunto de SQL (update, insert into, delete, select, truncate,etc).
LENGUAJE SQL Un manejador de base de datos debe de contener lenguajes que permitan definir el modelos de los datos, este mismo es que permite crear la estructura de la base de datos. Lenguaje de Definicion
Sistema de Registro, Derivación y Monitoreo Chile Crece Contigo
Sistema de Registro, Derivación y Monitoreo Chile Crece Contigo MANUAL DE USO CHCC MÓDULO ESTADÍSTICO NOVIEMBRE 2011 TABLA DE CONTENIDO 1 INTRODUCCIÓN... 3 2 ACCESO AL SISTEMA... 4 3 FUNCIONALIDADES MÓDULO
Bases de Datos. Diseño y Programación Avanzada de Aplicaciones. Curso
Bases de Datos Diseño y Programación Avanzada de Aplicaciones Curso 2002-2003 INDICE Fichero vs. Bases de Datos Relacionales Un fichero constituye la forma más básica de almacenamiento de información.
Conceptos Avanzados de Programación en Internet
Página 1 Conceptos Avanzados de Programación en Internet (1) Introducción a las Bases de Datos (2) Lenguaje Estándar de Consultas SQL Página 2 Lenguaje SQL. Introducción BD Justificación de las Bases de
COMANDOS DE SQL, OPERADORES, CLAUSULAS Y CONSULTAS SIMPLES DE SELECCIÓN
COMANDOS DE SQL, OPERADORES, CLAUSULAS Y CONSULTAS SIMPLES DE SELECCIÓN Tipos de datos SQL admite una variada gama de tipos de datos para el tratamiento de la información contenida en las tablas, los tipos
RESUMEN DEL LENGUAJE SQL
RESUMEN DEL LENGUAJE SQL AUTORÍA JOSEFA PÉREZ DOMINGUEZ TEMÁTICA INFORMATICA ETAPA CICLO FORMATIVO DE GRADO SUPERIOR Y MEDIO DE INFORMATICA Resumen Con esta publicación muestra un resumen de la sintaxis
SQLModificaciones a la BD
SQL Modificaciones a la BD Amparo López Gaona tación Mayo 2012 Modificación de Datos Las instrucciones de SQL para modificación de los datos en una BD se clasifican en tres tipos: Insertar tuplas en una
Tema: Funciones en Excel (III) Funciones de fecha y hora Las fechas son a menudo una parte crítica de análisis de datos
Tema: Funciones en Excel (III) Funciones de fecha y hora Las fechas son a menudo una parte crítica de análisis de datos Índice: 1 Para qué las funciones fecha y hora? 2 Generalidades El especial tratamiento
Contenido. Introducción Usando di Monitoring como un usuario normal Uso de di Monitoring como un operador de entrada de datos...
1 Contenido Introducción... 3 Características principales... 3 Los niveles de usuario... 4 El aprendizaje de di Monitoring... 4 Usando di Monitoring como un usuario normal... 5 Acceso a di Monitoring...
Desde los programas más simples escritos en un lenguaje de programación suelen realizar tres tareas en forma secuencial.
Tipos de Datos Desde los programas más simples escritos en un lenguaje de programación suelen realizar tres tareas en forma secuencial. Entrada de datos Procesamientos de datos Salida de resultados Los
