Programación y Acceso a BD con SQL Pedro Pablo Alarcón Agustín Yagüe Departamento de O.E.I. Escuela Universitaria de Informática Universidad Politécnica de Madrid Programación en el Servidor 1. Introducción... 2 2. Servidor de Datos... 2 3. Programación de acciones y tareas... 3 Acceso desde Clientes 4. Arquitectura cliente/servidor...10 5. Conectividad de datos...19 6. Utilización de SQL...25 1
1. Introducción Desarrollo de la aplicación en el Servidor: Definición de datos Manipulación de datos Programación de acciones y tareas Proporciona servicios de datos y negocio Desarrollo de la aplicación en el Cliente: Proporciona el interface al usuario Dependiente del lenguaje de programación utilizado para su implementación Proporciona servicios de usuario y negocio 2. Servidor de Datos En el servidor, habitualmente, tendremos un SGBD. Debe permitir: Definición de datos (LDD) Manipulación de datos (LMD) Control de datos (LCD) Programación de acciones y tareas (LDD y LMD) En la mayoría de los casos se utiliza SQL Debe soportar al menos un protocolo de red basado en TCP/IP Número alto de clientes conectados y gestión de transacciones y bloqueos concurrentes 2
Servidor de Datos Bases de Datos medias y grandes Oracle, DB2, Informix, Sybase,... (mainframes... Windows) Bases de Datos pequeñas y medias SQLServer (servidor solo en Windows NT) Interbase Access, FoxPro, Paradox MySQL (limitaciones: transacciones, integridad referencial,...)... 3. Programación de Acciones y Tareas Lenguaje de control de flujo Extensiones de SQL Disparadores Pequeño programa que se almacena con el esquema de la base de datos y que se define para que se ejecute de forma automática como resultado de alguna acción de actualización que se lleva a cabo sobre la base de datos Procedimientos almacenados Parecido a un disparador excepto que se ejecuta cuando es llamado desde un disparador, otro procedimiento almacenado o un programa 3
Programación de Acciones y Tareas Disparadores y procedimientos almacenados Suelen ir asociados a la capa de negocio de la aplicación y por tanto permiten trasladar al servidor una parte de la lógica del negocio. La utilización de disparadores permite disminuir el tráfico de red de la aplicación, y facilita la lógica del programa cliente que realiza el acceso a la base de datos Pueden entenderse como un entorno basado en LDD y LMD, ya que se almacenan en el esquema de la base de datos Lenguaje de Control de Flujo Ampliación de SQL DECLARE para la definición de variables BEGIN.. END, para la definición de bloques de instrucciones SQL IF.. ELSE para la ejecución condicional WHILE para ejecución repetitiva o iterativa RETURN, para la definición de procedimientos almacenados PRINT, para el envío de mensajes a los usuarios Comentarios 4
Procedimientos Almacenados Compuestos de instrucciones SQL instrucciones de control de flujo Son compilados, por lo que su ejecución es rápida Pueden recibir y devolver parámetros, que permiten modularizar o descomponer problemas grandes y complejos Procedimientos Almacenados CREATE PROCEDURE calcularfunsueldo @tipofun char(3), @resultado money output AS if tipofun = max select @resultado= max(sueldo) from categoria else if tipofun = min select @resultado= min(sueldo) from categoria return else if tipofun = avg begin select @resultado= avg(sueldo) from categoria end 5
Disparadores Un disparador es un conjunto de acciones que se realizan automáticamente cuando se intenta hacer una actualización determinada sobre una tabla específica. Son similares a los procedimientos almacenados, con la salvedad que se ejecutan al ocurrir un evento determinado Eventos: inserción, modificación y borrado. Disparadores CREATE TRIGGER ActualizaStock ON Pedidos FOR insert, update, delete Update Almacen set stock = stock + (selectcantidad from inserted where inserted.codart = Almacen.CodArt) where codart = inserted.codart Update Almacen set stock = stock - (select cantidad from inserted where deleted.codart = Almacen.CodArt) where codart = deleted.codart 6
Interbase CREATE PROCEDURE nombre [(param <tipodato> [, param <tipodato>...])] [RETURNS <tipodato> [, param <tipodato>...])] AS <cuerpo> [terminador] <cuerpo> = [<listavariables>] <bloque> < listavariables > = DECLARE VARIABLE var <tipodato>; [DECLARE VARIABLE var <tipodato>;...] <bloque> =BEGIN <sentencias> [<sentencias>...] END <sentencias> = {<bloque> sentencia;} EXECUTE PROCEDURE nombre [param [, param...]]; Interbase CREATE TRIGGER nombre FOR tabla [ACTIVE INACTIVE] {BEFORE AFTER} {DELETE INSERT UPDATE} [POSITION numero] AS <cuerpo> terminador <cuerpo> = [<lista_declaracion_variables>] <bloque> < lista_declaracion_variables > = DECLARE VARIABLE variable <tipodato>; [DECLARE VARIABLE variable <tipodato>;...] <bloque> = BEGIN <sentencia> [<sentencia>...] END <sentencia> = {<bloque> sentencia;} 7
Interbase Cursor DECLARE cursor CURSOR FOR <select> [FOR UPDATE OF <col> [, <col>...]]; Sentencias asociadas: OPEN, FETCH, CLOSE Funciones Externas DECLARE EXTERNAL FUNCTION nombre [<tipodato> CSTRING (int) [, <tipodato> CSTRING (int)...]] RETURNS {<tipodato> [BY VALUE] CSTRING (int)} ENTRY_POINT "<entryname>" MODULE_NAME "<modulename>"; SQL Server CREATE PROC[EDURE] nombreprocedimiento [;número] [{@parámetro tipodatos} [VARYING] [= predeterminado] [OUTPUT]] [,...n] [WITH {RECOMPILE ENCRYPTION RECOMPILE, ENCRYPTION } ] [FOR REPLICATION] AS instrucciónsql [...n] 8
SQL Server CREATE TRIGGER nombre ON tabla [WITH ENCRYPTION] { {FOR { [DELETE] [,] [INSERT] [,] [UPDATE] } [WITH APPEND] [NOT FOR REPLICATION] AS instrucciónsql [...n] } {FOR { [INSERT] [,] [UPDATE] } [WITH APPEND] [NOT FOR REPLICATION] AS {IF UPDATE (columna) [{AND OR} UPDATE (columna)] [...n] IF (COLUMNS_UPDATED() {operadornivelbit} máscarabitsactualizada) { operadorcomparación} máscarabitscolumna [...n] } instrucciónsql [...n] } } Cursores Sintaxis de SQL-92 DECLARE nombrecursor [INSENSITIVE] [SCROLL] CURSOR FOR instrucciónselect [FOR {READ ONLY UPDATE [OF listacolumnas [,...n]]}] Sintaxis extendida de Transact-SQL (SqlServer) DECLARE nombrecursor CURSOR [LOCAL GLOBAL] [FORWARD_ONLY SCROLL] [STATIC KEYSET DYNAMIC FAST_FORWARD] [READ_ONLY SCROLL_LOCKS OPTIMISTIC] [TYPE_WARNING] FOR instrucciónselect [FOR UPDATE [OF nombrecolumna [,...n]]] 9
4. Arquitectura Cliente/Servidor Un sistema Cliente/Servidor es aquel en el que dos o más procesos funcionan de forma independiente pero de forma cooperativa. En un sistema Cliente/Servidor una aplicación pide datos a otra, una vez realizada la petición elabora la respuesta y la devuelve a la aplicación demandante. Arquitectura Cliente/Servidor Base de Datos Servidor (SGBD) Disco SELECT * FROM CLIENTES WHERE CIUDAD= MADRID 10
Arquitectura Cliente/Servidor Cliente Servidor (SGBD) Base de Datos Disco SELECT * FROM CLIENTES SELECT * FROM CLIENTES WHERE CIUDAD= MADRID 100.000 filas 10.000 filas Menor Tráfico en la Red Menor complejidad en los programas cliente SELECT * FROM CLIENTES WHERE CIUDAD= MADRID AND EDAD < 18 10 filas Menor ocupación de memoria Modelo Cliente/Servidor de dos capas Paralelismo con la implementación física Ordenador Servidor Ordenador Cliente Petición Red Petición Respuesta Respuesta Aplicación Servidora Aplicación Cliente 11
Modelo Cliente/Servidor de tres capas Componentes agrupadas por capas Interface Interface Servicios de datos Servicios del negocio Servicios de Usuario Análisis del modelo de servicio El modelo de servicio representa la forma lógica de agrupar los componentes que se crean. El modelo de servicio es independiente de la plataforma sobre la que se desarrolle. Existen tres tipos de servicios: Servicios de usuario Servicios de negocio Servicios de datos 12
5. Conectividad de Bases de Datos ODBC Open Data Base Connectivity (Conectividad de Bases de Datos) Anteriormente se utilizaba Sql embebido, mediante precompiladores ODBC permitió que tanto ordenadores grandes como pequeños utilizasen Sql como vehículo SQL Embebido Precompilador (del SGBDR) Compilador ProgramAcceso; Var... Begin... EXEC SQL DECLARE CURSOR cli FOR SELECT * FROM CLIENTES... End Programa Fuente Programa Precompilado Programa Objeto SGBDR BD 13
ODBC Aplicación Administrador de Drivers ODBC Driver Oracle Driver Interbase Driver Access (Jet) Consulta: Clientes Origen de datos: Albaranes Origen de datos: Productos ORACLE BD1.GDB BD2.MDB ODBC Protocolo estándar para el acceso a la información de servidores de bases de datos SQL. Hay que instalar controladores de ODBC que permitan que se realice la conexión a estos servidores de bases de datos SQL. La arquitectura de la aplicación/controlador en 32 bits es: Aplicación Administrador de controladores ODBC Controlador ODBC Fuente de Datos 14
ODBC Descripción de las capas: Aplicación: realiza llamadas a la API de ODBC para enviar las instrucciones ODBC y obtener los resultados. Administrador de drivers: realiza dos tareas que corresponden al modo de funcionamiento oculto y al modo de funcionamiento mediante interface. Oculto: realiza la carga de los drivers por petición de cada aplicación. Interface: realiza el mantenimiento de los drivers y fuentes de datos. ODBC Descripción de las capas: Controlador: recibe las llamadas de la aplicación hacia las funciones de la API de ODBC y las traduce al lenguaje nativo de cada servidor. Fuente de Datos: es la asociación de un nombre de fuente con una base de datos del servidor al que se realiza la conexión. Almacena los elementos fundamentales de la conexión: ubicación del servidor, nombre de la base de datos, nombre de usuario y contraseña, etc. 15
ODBC Cursores: Un cursor es un puntero a las filas resultantes de una consulta sobre una base de datos. Los cursores deben situarse sobre la primera fila y deben permitir desplazamientos bidireccionales sobre el conjunto resultado. Tipos de cursores: Estáticos: no se actualizan.reflejan el estado de los datos en el momento de la consulta. (snapshot) Dinámicos: refrescan el estado de las memorias locales cada vez que un usuario realiza una modificación. Pseudodinámicos: el refresco de los datos de un registro se realiza cuando el usuario se sitúa sobre él. ODBC Configuración de ODBC: Permite que las aplicaciones se conecten a fuentes de datos sin importar posteriormente el controlador que la base de datos lleva asociada. Se pueden configurar tres tipos de conexiones: DSN de Usuario: permite establecer la configuración de la conexión para el equipo local y para el usuario actual. DSN de Sistema: permite establecer la configuración de la conexión para el equipo local y para cualquier usuario de la máquina. DSN de Archivo: permite establecer la configuración de la conexión para cualquier usuario con el mismo controlador. 16
JDBC JDBC es para Java lo que ODBC para Windows. Es un conjunto de primitivas que los drivers JDBC deben poder entender para acceder a una base de datos. Permiten a cualquier programa Java acceder a bases de datos. El acceso se hace a través de un driver JDBC específico. Es necesario JDBC porque ODBC está escrito en C y por lo tanto es dependiente de la máquina. JDBC Esquema de conectividad: 17
6. Utilización de SQL Interacción con la BD Java Visual Basic Interacción con la BD Comandos SQL interactivos en modo textual Comandos embebidos en lenguajes ad-hoc (4gl o similares) de los gestores pl/sql de Oracle Transact-sql de SqlServer i4gl de Informix... Comandos de SQL embebido en programas (Pascal, C, Cobol, Ada, etc.) Comandos embebidos en lenguajes con objetos de acceso a datos y conectividad con bases de datos (ODBC, JDBC) 18
Ejemplo SQL de modo interactivo SELECT Nombre, Apellidos, Sueldo FROM Empleados WHERE sueldo > 2000 Nombre Apellidos Sueldo Rosa Alvarez 3000 Pablo Pérez 2500 SQL embebido en un lenguaje ad-hoc Ejemplo con PL/SQL de Oracle declare Salario number; begin select Sueldo into Salario from Empleados where Code = 1234 for update of Sueldo; if Salario > 500 then update Empleados set Sueldo = Sueldo * 1.1 wherecode = 1234 ; else update Empleados set Sueldo = Sueldo * 1.15 wherecode = 1234 ; end if; commit; exception when no_data_found then insert into Errors values( Empleado no encontrado',sysdate); end; 19
SQL embebido en un lenguaje externo Ejemplo con Pascal Write ( categoria:?'); Readln(categoria); EXEC SQL DECLARE E CURSOR FOR SELECT Nombre, Apellidos, Sueldo FROM Empleados WHERE categoria = :categoria ; EXEC SQL OPEN E ; EXEC SQL FETCH E INTO :nombre, :apellidos, :sueldo; While SQLCODE = 0 do begin Write ( empleado:', nombre, apellidos, aumento?'); Readln(aumento); EXEC SQL UPDATE Empleados SET Sueldo = Sueldo + :aumento WHERE CURRENT OF E EXEC SQL FETCH E INTO :nombre, :apellidos, :sueldo; End; EXEC SQL CLOSE CURSOR E; SQL embebido en un lenguaje externo Ejemplo con Java public void buscarcliente (String codemp) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection conexion = DriverManager.getConnection ("jdbc:odbc:prueba", "yo", "yo"); Statementsentencia = conexion.createstatement(); sql= "SELECT Nombre,Apellidos,Sueldo FROM Cuentas WHERE E# ='" + codemp + "'"; ResultSet rs = sentencia.executequery(sql); if (rs.next()) { String nif = rs.getstring( Nombre"); String nombre = rs.getstring(" Apellidos "); String apellidos = rs.getstring( Sueldo"); // visualizar los datos } else { System.out.println ("Codigo de empleado no encontrado"); } rs.close(); } catch (SQLException ex) { System.out.println(ex.getMessage); } } 20
SQL embebido en un lenguaje externo Ejemplo con Visual Basic Dim miconexion As New ADODB.Connection, micomando As New ADODB.Command Dim mirecordset As New ADODB.Recordset, msqlas String miconexion.open "DSN=mibd" Set micomando.activeconnection = miconexion msql= "SELECT Nombre, Apellidos, Sueldo FROM Empleados " & _ "WHERE E# = " & codemp micomando.commandtype = adcmdtext micomando.commandtext = msql Set mirecordset = micomando.execute If Notmirecordset.EOF Then nombre = mirecordset.fields(0) apellidos = mirecordset.fields(1) sueldo = mirecordset.fields(2) Else msgbox Empleado no encontrado" End If mirecordset.close miconexion.close Java Driver: Permite conectarse a la BD. Es diferente para cada gestor. DriverManager: permite gestionar los drivers instalados. DriverPropertyInfo: proporciona la información del driver. Connection: Representa una conexión a la base de datos. DatabaseMetadata: da información sobre la base de datos a la que se acceder. (tablas, etc) Statement: permite ejecutar sentencias SQL sin parámetros. PreparedStatement: permite ejecutar sentencias SQL con parámetros. CallableStatements: permite ejecutar sentencias SQL con parámetros de entrada y salida Resultset: contiene el conjunto resultado de una consulta ResultsetMetadata: Obtiene información del resultset. 21
Java Conexión (Objeto Connection) close() cierra la conexión de la base de datos commit() y rollback() confirma o rechaza los cambios en la base de datos createstatement() crea un nuevo objeto de sentencia sql Java Sentencia (Objeto Statement) close() cierra la conexión con la base de datos executequery(string) ejecuta la consulta representada en String devuelve un ResultSet con el resultado executeupdate(string) ejecuta la sentencia representada en String Update, Insert, Delete o sentencias de definición devuelve un entero con el número de filas afectadas 22
Java Resultado (Objeto ResultSet) close() cierra la conexión con la base de datos findcolumn(string) devuelve la posición que ocupa la columna String getxxxx(int) devuelve el valor de la columna que ocupa la columna int en la fila actual getxxxx(string) devuelve el valor de la columna String en la fila actual next() devuelve true si hay mas filas, si no hay devuelve false Java (ejemplo) Database mibd = new Database(); mibd.setconnection (new borland.jbc1.dataset.connectiondescriptor ( jdbc:odbc:dataset curso, SYSDBA, masterkey, false, sun.jdbc.odbc.jdbcodbcdriver )); Statement msql = mibd.createstatement (); ResultSet mrs = msql.executequery ( select Nombre, categ FROM conductores ); while (mrs.next()) { String mnombre = getstring( Nombre ); int mcateg = getint( categ ); } 23