PROCEDIMIENTOS ALMACENADOS Y TRIGGERS Bases de Datos Ingeniería de Sistemas y Computación Universidad Nacional de Colombia 2007 Procedimientos almacenados Un procedimiento almacenado es un conjunto de sentencias SQL y de control de flujo Un procedimiento almacenado es una colección de instrucciones guardadas en la Base de Datos La ventaja de un procedimiento almacenado es que al ser ejecutado, éste se ejecuta directamente en el motor de bases de datos, el cual usualmente corre en un servidor separado. Bases de Datos - 2007 Procedimientos almacenados Beneficios de los procedimientos almacenados: Simplifican la ejecución de tareas repetitivas Corren más rápido que las mismas instrucciones ejecutadas en forma interactiva Reducen el tráfico a través de la red Pueden capturar errores antes que ellos puedan entrar a la base de datos Establece consistencia porque ejecuta las tareas de la misma forma Permite el desarrollo modular de aplicaciones Ayuda a proveer seguridad Puede forzar reglas y defaults complejos de los negocios Bases de Datos - 2007 Tipos de procedimientos almacenados Procedimientos almacenados definidos por el usuario Son procedimientos definidos por el usuario que se deben llamar explícitamente Triggers Son procedimientos definidos por el usuario que se ejecutan automáticamente cuando se modifica un dato en una tabla Procedimientos del sistema Procedimientos suministrados por el sistema Procedimientos extendidos Procedimientos que hacen llamadas al sistema operativo y ejecutan tareas a ese nivel Bases de Datos - 2007 Interactive Execution Bases de Datos - 2007 Creación de un procedimiento almacenado Bases de Datos - 2007 Ejecución de un procedimiento almacenado Bases de Datos - 2007 Ventajas en el rendimiento Un procedimiento almacenado se ejecuta más rápido que un batch porque: El procedimiento almacenado ya ha sido analizado Ya se han resuelto las referencias a los objetos referenciados en el procedimiento almacenado No se necesita construir el árbol de búsqueda, él usa el que se hace en el momento de compilarlo No se necesita crear un plan de búsqueda, porque ya el procedimiento tiene uno Bases de Datos - 2007 Crear y borrar procedimientos almacenados Sintaxis simplificada para create: create proc procedure_name as statements return Ejemplo: create proc proc_update_titles as update titles set price = price * $0.95 where total_sales < 3000 return Sintaxis simplificada para drop: drop proc procedure_name Ejemplo: drop proc proc_update_titles Bases de Datos - 2007 Crear procedimientos almacenados Sintaxis para Sybase: create procedure [owner.]procedure_name [;number] [[ (]@parameter_name datatype [= default] [output] [, @parameter_name datatype [= default] [output]] ...[)]] [with recompile] as sql_statements Bases de Datos - 2007 Crear procedimientos almacenados Sintaxis para SQL Server: create procedure procedure_name (parameter_name datatype default_value [, parameter_name datatype default_value...] ) as statements return Bases de Datos - 2007 Crear procedimientos almacenados Sintaxis para Oracle: CREATE [OR REPLACE] PROCEDURE <procedure_name> [(<param1> [IN|OUT|IN OUT] <type>, <param2> [IN|OUT|IN OUT] <type>, ...)] IS -- Declaracion de variables locales BEGIN -- Sentencias [EXCEPTION] -- Sentencias control de excepcion END [<procedure_name>]; Bases de Datos - 2007 Ejecutar procedimientos almacenados Sintaxis simplificada: [exec | execute] procedure_name Ejemplo: execute proc_update_titles Bases de Datos - 2007 Variables Los procedimientos almacenados pueden crear y usar variables locales Las variables sólo existen mientras exista el procedimiento Las variables no las puede usar otro proceso Bases de Datos - 2007 Sentencias válidas e inválidas Un procedimiento almacenado puede: Seleccionar y modificar datos Crear tablas temporales y permanentes Llamar otros procedimientos almacenados Referenciar objetos de bases de datos Un procedimiento almacenado no puede ejecutar: use database create view create default create rule create procedure create trigger Bases de Datos - 2007 Procedimientos almacenados y permisos Para permitir que otros usen un procedimiento almacenado, el propietario debe dar los respectivos permisos Sintaxis simplificada: grant execute on procedure_name to user_list Ejemplo: grant execute on proc_update_titles to icastaneda, grupo5, aortizs Bases de Datos - 2007 Crear procedimientos almacenados Crear un procedimiento almacenado sencillo: create proc proc_hello as print "Hello, <your_name>" return Ver el código fuente de un procedimiento: sp_helptext proc_hello Ejecutar el procedimiento: exec proc_hello Borrar los objetos de bases de datos: drop proc proc_hello Bases de Datos - 2007 Parámetros de entrada An input Parámetro is a variable local to a procedimiento almacenado that can receive a value from the exec procedure Sentencia Bases de Datos - 2007 Definir parámetros de entrada Sintaxis simplificada: create procedure procedure_name (parameter_name datatype default_value [, parameter_name datatype default_value...] ) as statements return Bases de Datos - 2007 Pasar parámetros Dos métodos para pasar valores a parámetros: Paso de parámetros por posición Paso de parámetros por nombre Bases de Datos - 2007 Paso de parámetros por posición Sintaxis para paso por posición: [exec | execute] procedure_name value [, value...] Ejemplo: exec proc_author_info "Ringer“,"Albert" au_lname -------Ringer Ringer au_fname -------Albert Albert title ----Is Anger the Enemy? Life Without Fear Los parámetros se deben pasar en el mismo orden en que ellos aparecen en la sentencia create procedure Como este método es más propenso a errores, se aconseja el paso por nombre Bases de Datos - 2007 Paso de parámetros por nombre Sintaxis para paso por nombre: [exec | execute] procedure procedure_name parameter_name = value [, parameter_name = value ] Ejemplo: exec proc_author_info @lname = "Ringer", @fname = "Albert" au_lname -------Ringer Ringer au_fname -------Albert Albert title ----Is Anger the Enemy? Life Without Fear Los nombres de los parámetros en la sentencia exec deben concordar con los nombres de los parámetros usados en la sentencia create procedure Los parámetros pueden pasar en cualquier orden Bases de Datos - 2007 Valores por default Se puede asignar un valor por default a un parámetro cuando él no se indica en la sentencia exec Ejemplo: create proc proc_state_authors (@state char(2) = "CA") as select au_lname, au_fname, state from authors where state = @state return exec proc_state_authors -- No state value passed au_lname -------White Green ... state ----CA CA au_fname -------Johnson Marjorie Bases de Datos - 2007 Parámetros de entrada: errores comunes Los valores que se pasan no tienen el mismo tipo de datos que los parámetros definidos En la misma sentencia, se pasa un parámetro por posición después de haber pasado un parámetro por nombre Aunque no es recomendado, es posible mezclar los dos métodos para pasar valores, sin embargo, después de pasar un valor a un parámetro por nombre, todos los restantes de deben pasar por nombre Olvido de uno o más parámetros El olvido de uno o más valores para los parámetros, hace que se usen los valores por default Los valores para los parámetros se pasan en un orden errado Bases de Datos - 2007 Parámetros de entrada Crear un procedimiento almacenado que tenga un parámetro de entrada: create proc proc_hello_param (@name varchar(30)) as print "Hello %1!", @name return Ejecutar el procedimiento con y sin un valor para el parámetro de entrada. Una sentencia fallará: exec proc_hello_param exec proc_hello_param "<yourname>" Crear un procedimiento almacenado que tiene un valor por default para un parámetro de entrada: create proc proc_hello_def (@name varchar(30) = "whoever you are") as print "Hello %1!", @name return Bases de Datos - 2007 Parámetros de entrada • Ejecutar el procedimiento con y sin un valor para el parámetro de entrada: exec proc_hello_def exec proc_hello_def "<yourname>" • ¿Cuál procedimiento almacenado parece ser más amigable? • Borrar los objetos de bases de datos creados: drop proc proc_hello_param, proc_hello_def Bases de Datos - 2007 Retorno de valores A return Parámetro is a variable local to a procedimiento almacenado that can send a value to the exec procedure Sentencia Bases de Datos - 2007 Crear parámetros que retornan valores Sintaxis simplificada: create procedure procedure_name (parameter_name datatype output [, parameter_name datatype output...] ) as statements return Bases de Datos - 2007 Usar parámetros que retornan valores Sintaxis simplificada: [exec | execute] procedure_name variable output Los valores que retornan los parámetros se pasan automáticamente al conjunto respuesta El retorno de valores se pueden pasar por nombre o por posición Se recomienda el paso por nombre Bases de Datos - 2007 Legibilidad Para hacer un código más legible: Utilizar comentarios Utilizar indentación Usar espacios en blanco y dejar el código organizado en columnas Declarar e iniciar las variables en un bloque Establecer un conjunto de buenas prácticas para legibilidad Bases de Datos - 2007 Chequeo de valores que van a ser parámetros de entrada El servidor sólo chequea que los valores y sus respectivos parámetros concuerden en el tipo de datos Los procedimientos almacenados deben verificar que los valores pasados se encuentren dentro del dominio establecido Bases de Datos - 2007 Mensajes de error por omisión de valores para los parámetros Si un procedimiento almacenado requiere valores para los parámetros, el usuario debe incluir un tratamiento de esos errores y un manejo de mensajes de error Ejemplo: create proc proc_cutoff (@title_id char(6) = NULL, @max_price money = NULL) as if @title_id is NULL or @max_price is NULL begin raiserror 20001 "Execution for this procedure is: exec proc_cutoff title_id, max_price" return end ... return Bases de Datos - 2007 Retorno de valores de estado A return status is a value that indicates whether or not the procedure successfully completed Bases de Datos - 2007 Retorno de valores de estado Values Meaning Greater than 0 No predefined meaning; available for user-detected errors 0 Successful completetion -1 through –99 System-detected error Less than –99 No predefined meaning; available for user-detected erros Bases de Datos - 2007 Retorno de valores de estado Sintaxis simplificada: create proc procedure_name as statements return [return_status] Ejemplo: create proc proc_datacheck as if (select max(total_sales) from titles) < 3000 begin print "All the books have sold less than 3000." return 100 end else ... return 0 Bases de Datos - 2007 Captura del valor del estado de retorno Los valores de retorno se deben capturar en variables Sintaxis simplificada: [exec | execute] variable = procedure_name parameter_list Ejemplo: declare @status int exec @status = proc_datacheck if @status = 100 exec proc_max_under_3000 else print "proc_datacheck was successful" Bases de Datos - 2007 Límite de anidamiento para procedimientos Los procedimientos almacenados pueden llamar otros procedimientos almacenados El máximo nivel de anidamiento es 16 La variable @@nestlevel contiene el nivel de anidamiento actual Si se excede el nivel máximo: Se abortan los procedimientos pendientes El servidor retorna un error Bases de Datos - 2007 Crear procedimientos con recompile En un procedimiento, usar la opción with recompile para forzar al servidor a crear un nuevo plan de búsqueda cada vez que se ejecute el procedimiento Sintaxis simplificada: create proc procedure_name with recompile as statements return Bases de Datos - 2007 Ejecución de procedimientos with recompile Cuando se ejecute un procedimiento almacenado, usar la opción with recompile para forzar al servidor a crear un nuevo plan de búsqueda para esa ejecución del procedimiento Esta opción se puede usar cuando se ejecuta cualquier procedimiento almacenado Sintaxis simplificada: [exec | execute] procedure_name with recompile Ejemplo: execute proc_update_titles with recompile Bases de Datos - 2007 Trigger Un trigger es un procedimiento almacenado asociado con una tabla, el cual se ejecuta automáticamente cuando se modifica un dato de esa tabla User-Defined Can It Be Can It Be Can It Use Explicitly Executed Parameters? Called? Automatically? Yes No Yes No Yes No Stored Procedure Trigger Bases de Datos - 2007 Aplicaciones Típicas de triggers Hacer modificaciones en cascada sobre tablas relacionadas Deshacer cambios que violan la integridad de los datos Forzar restricciones que son muy complejas para reglas y restricciones Mantener datos duplicados Mantener columnas con datos derivados Hacer ajustes de registros Bases de Datos - 2007 Definición de un trigger Un trigger se define asociado con una tabla para una o más sentencias de manipulación de datos Un trigger se puede definir para insert, update, o delete o cualquier combinación de ellos Bases de Datos - 2007 Activación de un trigger Cuando se modifica un dato en una tabla que tiene declarado un trigger para esa sentencia, el trigger se “dispara” El trigger se dispara una vez, independientemente del número de filas afectadas El trigger se dispara aunque no hayan filas afectadas Bases de Datos - 2007 Triggers and transacciones Un trigger es parte de la transacción que causa el disparo El trigger puede deshacer: Así mismo solamente Así mismo y la sentencia que causa el disparo La transacción total Bases de Datos - 2007 Reglas para triggers Los triggers pueden: Declarar variables locales Invocar procedimientos almacenados Los triggers no pueden: Llamarse directamente Usar parámetros Definirse sobre tablas temporales o vistas Crear objetos permanentes de base de datos Las operaciones con registro mínimo (como select into) no disparan los triggers Bases de Datos - 2007 Crear triggers Sintaxis simplificada: create trigger trigger_name on table_name for {insert | update | delete} [, {insert | update | delete} ...] as sql_statements Bases de Datos - 2007 Crear triggers - Oracle Sintaxis simplificada: CREATE [OR REPLACE] TRIGGER <nombre_trigger> {BEFORE|AFTER} {DELETE|INSERT|UPDATE [OF col1, col2, ..., colN] [OR {DELETE|INSERT|UPDATE [OF col1, col2, ..., colN]...]} ON <nombre_tabla> [FOR EACH ROW [WHEN (<condición>)]] DECLARE -- variables locales BEGIN -- Sentencias [EXCEPTION] -- Sentencias control de excepcion END <nombre_trigger>; Bases de Datos - 2007 Borrar Triggers Sintaxis simplificada: drop trigger trigger_name Ejemplo: drop trigger trg_i_sales Bases de Datos - 2007 Procedimientos del sistema para procedimientos almacenados sp_depends {table_name | trigger_name} Cuando se da el nombre de tabla, lista todos los objetos (incluyendo triggers) de la misma base de datos Cuando se da el nombre de trigger, lista todas las tablas referencias sp_help trigger_name Muestra información del trigger sp_helptext trigger_name Muestra el código usado para crear el trigger sp_rename old_trigger_name, new_trigger_name Cambia el nombre del trigger Bases de Datos - 2007 Las tablas inserted y deleted inserted y deleted son dos tablas que se crean automáticamente cada vez que se dispara un trigger inserted almacena cualquier fila que se vaya a añadir a la tabla deleted almacena cualquier fila que se vaya a borrar de la tabla Bases de Datos - 2007 :old :new en Triggers Oracle Sentencia SQL OLD NEW Insert No definido; todos los campos toman valor NULL. Valores que serán insertados cuando se complete la orden. Update Valores originales de la fila, antes de la actualización. Nuevos valores que serán escritos cuando se complete la orden. Delete Valores, antes del borrado de la fila. No definidos; todos los campos toman el valor NULL. Bases de Datos - 2007 Borrados A delete adds rows to the deleted table Bases de Datos - 2007 Inserciones An insert adds rows to the inserted table Bases de Datos - 2007 Actualizaciones An update adds rows to both tables Bases de Datos - 2007 Reglas para las tablas inserted y deleted Ambas tablas tienen las mismas columnas que la tabla asociada al trigger El trigger puede consultar datos de las dos tablas Otros procesos no pueden consultar datos de las dos tablas El trigger no puede modificar datos en las dos tablas Cada anidamiento de triggers tiene sus propias tablas inserted y deleted Si un trigger modifica datos de su tabla asociada, esos cambios no se reflejan en las tablas inserted and deleted de ese trigger Bases de Datos - 2007 Triggers y rollbacks Tres tipos de rollbacks: Deshacer el trigger Deshacer el trigger y la sentencia que lo disparó Deshacer toda la transacción Bases de Datos - 2007 Deshacer un trigger rollback trigger deshace el trigger y la sentencia que lo disparó Sintaxis: rollback trigger [with raiserror error_number [error_statement] ] Bases de Datos - 2007 Prácticas recomendadas al hacer Triggers Las siguientes consideraciones se deben hacer al elaborar triggers: @@rowcount if update triggers anidados triggers recursivos Bases de Datos - 2007 if update if update es una condición que le permite a un trigger chequear si ha habido un cambio en una determinada columna Sólo se puede usar en triggers Usualmente se usa para chequear si el valor de una llave primaria ha cambiado Sintaxis simplificada: if update (column_name) [ {and | or} update (column_name)]... Bases de Datos - 2007 Triggers anidados Un trigger anidado es un trigger que se dispara en respuesta a una modificación hecha en un trigger Nivel máximo de anidamiento: 16 Tanto los procedimientos almacenados como los triggers cuentan en la determinación del nivel máximo @@nestlevel retorna el nivel de anidamiento Bases de Datos - 2007 Triggers recursivos Un trigger recursivo es aquel que se dispara cuando modifica su propia tabla Por default, un trigger que modifica su propia tabla no causa un disparo recursivo del trigger Bases de Datos - 2007 Métodos para integridad de datos Dos métodos para implementar integridad de datos Domain Integrity Entity Integrity Referential Integrity Constraints Check constraints Primary key constraints, unique constraints References constraints Database Objects Rules Indexes Triggers Bases de Datos - 2007 Actualización de valores llave Acción deseada Restricciones Triggers Insertarar valor de llave primaria Permitido Permitido Insertar valor de llave foránea Permitido Permitido Actualizar valor de llave primaria No permitido* Permitido Actualizar valor de llave foránea Permitido Permitido Borrar valor de llave primaria No permitido* Permitido Borrar valor de llave foránea Permitido Permitido *Valores de llaves primarias se pueden actualizar o borrar si no están referencidos en llaves foráneas Solamente en triggers es posible borrar o actualizar una llave primaria Sólo en triggers es posible hacer cambios en cascada Bases de Datos - 2007 Restricciones vs triggers Ventajas de las restricciones: Las restricciones (y reglas) son más rápidas que los triggers Las restricciones no requieren codificación adicional Es mejor para chequear datos antes de ingresarlos a la base de datos Ventajas de los triggers: Muy flexible Los triggers pueden hacer cualquier cosa que se pueda codificar Mejor para las reglas complejas del negocio que no se pueden expresar como restricciones referenciales tales como actualizaciones o borrados en cascada Bases de Datos - 2007 Preguntas Gracias por su Atención Bases de Datos - 2007