24.04.2013 Views

Trigger Los triggers o disparadores son objetos de la base de datos ...

Trigger Los triggers o disparadores son objetos de la base de datos ...

Trigger Los triggers o disparadores son objetos de la base de datos ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Trigger</strong><br />

Un trigger(o <strong>de</strong>senca<strong>de</strong>nador) es una c<strong>la</strong>se especial <strong>de</strong> procedimiento almacenado que se ejecuta<br />

automáticamente cuando se produce un evento en el servidor <strong>de</strong> <strong>base</strong>s <strong>de</strong> <strong>datos</strong>.<br />

<strong>Los</strong> <strong>triggers</strong> o <strong>disparadores</strong> <strong>son</strong> <strong>objetos</strong> <strong>de</strong> <strong>la</strong> <strong>base</strong> <strong>de</strong> <strong>datos</strong> que ejecutan acciones cuando se<br />

producen ciertos eventos (tanto DML como DDL) (inserciones, modificaciones, borrados, creación<br />

<strong>de</strong> tab<strong>la</strong>s, etc.).<br />

<strong>Trigger</strong> DML, se ejecutan cuando un usuario intenta modificar <strong>datos</strong> mediante un evento <strong>de</strong><br />

lenguaje <strong>de</strong> manipu<strong>la</strong>ción <strong>de</strong> <strong>datos</strong> (DML). <strong>Los</strong> eventos DML <strong>son</strong> instrucciones INSERT, UPDATE o<br />

DELETE <strong>de</strong> una tab<strong>la</strong> o vista.<br />

<strong>Trigger</strong> DDL, se ejecutan en respuesta a una variedad <strong>de</strong> eventos <strong>de</strong> lenguaje <strong>de</strong> <strong>de</strong>finición <strong>de</strong><br />

<strong>datos</strong> (DDL). Estos eventos correspon<strong>de</strong>n principalmente a instrucciones CREATE, ALTER y DROP<br />

<strong>de</strong> Transact-SQL, y a <strong>de</strong>terminados procedimientos almacenados <strong>de</strong>l sistema que ejecutan<br />

operaciones <strong>de</strong> tipo DDL.<br />

La estructura básica <strong>de</strong> un trigger es:<br />

L<strong>la</strong>mada <strong>de</strong> activación: es <strong>la</strong> sentencia que permite "disparar" el código a ejecutar. Restricción: es<br />

<strong>la</strong> condición necesaria para realizar el código. Esta restricción pue<strong>de</strong> ser <strong>de</strong> tipo condicional o <strong>de</strong><br />

tipo nulidad.<br />

Acción a ejecutar: es <strong>la</strong> secuencia <strong>de</strong> instrucciones a ejecutar una vez que se han cumplido <strong>la</strong>s<br />

condiciones iniciales.<br />

Existen dos tipos <strong>de</strong> <strong>disparadores</strong> que se c<strong>la</strong>sifican según <strong>la</strong> cantidad <strong>de</strong> ejecuciones a realizar:<br />

Row <strong>Trigger</strong>s (o Disparadores <strong>de</strong> fi<strong>la</strong>): <strong>son</strong> aquel<strong>la</strong>s que se ejecutaran n-veces si se l<strong>la</strong>ma n-veces<br />

<strong>de</strong>s<strong>de</strong> <strong>la</strong> tab<strong>la</strong> asociada al trigger<br />

Statement <strong>Trigger</strong>s (o Disparadores <strong>de</strong> secuencia): <strong>son</strong> aquellos que sin importar <strong>la</strong> cantidad <strong>de</strong><br />

veces que se cump<strong>la</strong> con <strong>la</strong> condición, su ejecución es única.<br />

Características:<br />

No aceptan parámetros o argumentos (pero podrían almacenar los <strong>datos</strong> afectados en tab<strong>la</strong>s<br />

temporales)<br />

No pue<strong>de</strong>n ejecutar <strong>la</strong>s operaciones COMMIT o ROLLBACK por que estas <strong>son</strong> parte <strong>de</strong> <strong>la</strong> sentencia<br />

SQL <strong>de</strong>l disparador (únicamente a través <strong>de</strong> transacciones autónomas)<br />

Pue<strong>de</strong>n causar errores <strong>de</strong> mutaciones en <strong>la</strong>s tab<strong>la</strong>s, si se han escrito <strong>de</strong> manera <strong>de</strong>ficiente.<br />

Usos<br />

Son usados para mejorar <strong>la</strong> administración <strong>de</strong> <strong>la</strong> Base <strong>de</strong> <strong>datos</strong>, sin necesidad <strong>de</strong> contar con que el<br />

usuario ejecute <strong>la</strong> sentencia <strong>de</strong> SQL.<br />

A<strong>de</strong>más, pue<strong>de</strong>n generar valores <strong>de</strong> columnas, previene errores <strong>de</strong> <strong>datos</strong>, sincroniza tab<strong>la</strong>s,<br />

modifica valores <strong>de</strong> una vista, etc.<br />

Permite implementar programas basados en paradigma lógico (sistemas expertos, <strong>de</strong>ducción).


Ventajas y <strong>de</strong>sventajas:<br />

- No pue<strong>de</strong>n ser invocados directamente; al intentar modificar los <strong>datos</strong> <strong>de</strong> una tab<strong>la</strong> para <strong>la</strong> que<br />

se ha <strong>de</strong>finido un disparador, el disparador se ejecuta automáticamente.<br />

- No reciben y retornan parámetros.<br />

- Son apropiados para mantener <strong>la</strong> integridad <strong>de</strong> los <strong>datos</strong>, no para obtener resultados <strong>de</strong><br />

consultas.<br />

-Pue<strong>de</strong>n hacer referencia a campos <strong>de</strong> otras tab<strong>la</strong>s.<br />

-<strong>Los</strong> <strong>disparadores</strong> se ejecutan DESPUES <strong>de</strong> <strong>la</strong> ejecución <strong>de</strong> una instrucción "insert", "update" o<br />

"<strong>de</strong>lete" en <strong>la</strong> tab<strong>la</strong> en <strong>la</strong> que fueron <strong>de</strong>finidos. Las restricciones se comprueban ANTES <strong>de</strong> <strong>la</strong><br />

ejecución <strong>de</strong> una instrucción "insert", "update" o "<strong>de</strong>lete". Por lo tanto, <strong>la</strong>s restricciones se<br />

comprueban primero, si se infringe alguna restricción, el <strong>de</strong>senca<strong>de</strong>nador no llega a ejecutarse.<br />

-Mejor utilización <strong>de</strong> <strong>la</strong> CPU<br />

-Menor necesidad <strong>de</strong> limpieza <strong>de</strong> <strong>la</strong>s memorias intermedias durante el procesamiento <strong>de</strong> <strong>la</strong>s<br />

transacciones<br />

-Puntos <strong>de</strong> verificación más rápidos<br />

-Menor tiempo <strong>de</strong> recuperación<br />

-SQL Server registra <strong>la</strong>s transacciones <strong>de</strong> tal modo que <strong>la</strong>s actualizaciones en una <strong>de</strong> el<strong>la</strong>s siempre<br />

se puedan recuperar o reducir al último estado consistente si el equipo cliente o servidor fal<strong>la</strong>.<br />

Aunque el motor <strong>de</strong> <strong>base</strong> <strong>de</strong> <strong>datos</strong> Microsoft Jet y los archivos .mdb también proporcionan<br />

transacciones, éstas no se administran mediante un registro <strong>de</strong> transacciones separado en los<br />

archivos .mdb y pue<strong>de</strong>n fal<strong>la</strong>r sin posibilidad <strong>de</strong> recuperación si se daña el archivo <strong>de</strong> <strong>la</strong> <strong>base</strong> <strong>de</strong><br />

<strong>datos</strong>.<br />

Sintaxis básica:<br />

create triggre NOMBREDISPARADOR<br />

on NOMBRETABLA<br />

for EVENTO- insert, update o <strong>de</strong>lete<br />

as<br />

SENTENCIAS<br />

Ejemplos <strong>de</strong> <strong>triggers</strong>:<br />

1.-<br />

CREATE TRIGGER TR_CUENTAS<br />

ON CUENTAS<br />

AFTER UPDATE<br />

AS<br />

BEGIN<br />

SET NOCOUNT ON;<br />

INSERT INTO HCO_SALDOS<br />

(IDCUENTA, SALDO, FXSALDO)


SELECT IDCUENTA, SALDO, getdate()<br />

FROM INSERTED<br />

END<br />

2.-<br />

CREATE TRIGGER TR_RESULTADO<br />

ON RESULTADO<br />

AFTER UPDATE<br />

AS<br />

BEGIN<br />

SET NOCOUNT ON;<br />

IF UPDATE (SALDO) -- Solo si se actualiza SALDO<br />

BEGIN<br />

INSERT INTO HCO_SALDOS<br />

(IDCUENTA, SALDO, FXSALDO)<br />

SELECT IDCUENTA, SALDO, getdate()<br />

FROM INSERTED<br />

END<br />

3.-<br />

CREATE TRIGGER TR_SEGURIDAD<br />

ON DATABASE FOR DROP_TABLE, ALTER_TABLE<br />

AS<br />

BEGIN<br />

RAISERROR ('No está permitido borrar ni modificar tab<strong>la</strong>s!’, 16, 1)<br />

ROLLBACK TRANSACTION<br />

END


Procedimientos almacenados en Transact SQL<br />

Un procedimiento es un programa <strong>de</strong>ntro <strong>de</strong> <strong>la</strong> <strong>base</strong> <strong>de</strong> <strong>datos</strong> que ejecuta una acción o conjunto<br />

<strong>de</strong> acciones específicas.<br />

Un procedimiento tiene un nombre, un conjunto <strong>de</strong> parámetros (opcional) y un bloque <strong>de</strong> código.<br />

En Transact SQL los procedimientos almacenados pue<strong>de</strong>n <strong>de</strong>volver valores (numérico entero) o<br />

conjuntos <strong>de</strong> resultados. <strong>Los</strong> procedimientos pue<strong>de</strong>n:<br />

Incluir parámetros<br />

L<strong>la</strong>mar a otros procedimientos<br />

Devolver un valor <strong>de</strong> estado a un procedimiento <strong>de</strong> l<strong>la</strong>mada o lote para indicar el éxito o el<br />

fracaso <strong>de</strong>l mismo y <strong>la</strong> razón <strong>de</strong> dicho fallo<br />

Devolver valores <strong>de</strong> parámetros a un procedimiento <strong>de</strong> l<strong>la</strong>mada o lote<br />

Ejecutarse en SQL Server remotos<br />

Para crear un procedimiento almacenado <strong>de</strong>bemos emplear <strong>la</strong> sentencia CREATE PROCEDURE.<br />

CREATE PROCEDURE [param1 , ...]<br />

AS<br />

-- Sentencias<br />

Para modificar un procedimiento almacenado <strong>de</strong>bemos emplear <strong>la</strong> sentencia ALTER PROCEDURE.<br />

ALTER PROCEDURE [param1 , ...]<br />

AS<br />

-- Sentencias


Usos<br />

<strong>Los</strong> usos 'típicos' <strong>de</strong> los procedimientos almacenados se aplican en <strong>la</strong> validación <strong>de</strong> <strong>datos</strong>,<br />

integrados <strong>de</strong>ntro <strong>de</strong> <strong>la</strong> estructura <strong>de</strong>l banco <strong>de</strong> <strong>datos</strong>. <strong>Los</strong> procedimientos almacenados usados<br />

con tal propósito se l<strong>la</strong>man comúnmente <strong>disparadores</strong>, o <strong>triggers</strong>. Otro uso común es <strong>la</strong><br />

'encapsu<strong>la</strong>ción' <strong>de</strong> un API para un proceso complejo o gran<strong>de</strong> que podría requerir <strong>la</strong> 'ejecución' <strong>de</strong><br />

varias consultas SQL, tales como <strong>la</strong> manipu<strong>la</strong>ción <strong>de</strong> un 'dataset' enorme para producir un<br />

resultado resumido.<br />

También pue<strong>de</strong>n ser usados para el control <strong>de</strong> gestión <strong>de</strong> operaciones, y ejecutar procedimientos<br />

almacenados <strong>de</strong>ntro <strong>de</strong> una transacción <strong>de</strong> tal manera que <strong>la</strong>s transacciones sean efectivamente<br />

transparentes para ellos.<br />

Ventajas<br />

-La ventaja <strong>de</strong> un procedimiento almacenado, en respuesta a una petición <strong>de</strong> usuario, está<br />

directamente bajo el control <strong>de</strong>l motor <strong>de</strong>l manejador <strong>de</strong> <strong>base</strong>s <strong>de</strong> <strong>datos</strong>, lo cual corre<br />

generalmente en un servidor separado <strong>de</strong> manejador <strong>de</strong> <strong>base</strong>s <strong>de</strong> <strong>datos</strong> aumentando con ello, <strong>la</strong><br />

rapi<strong>de</strong>z <strong>de</strong> procesamiento <strong>de</strong> requerimientos <strong>de</strong>l manejador <strong>de</strong> <strong>base</strong>s <strong>de</strong> <strong>datos</strong>. El servidor <strong>de</strong> <strong>la</strong><br />

<strong>base</strong> <strong>de</strong> <strong>datos</strong> tiene acceso directo a los <strong>datos</strong> necesarios para manipu<strong>la</strong>r y sólo necesita enviar el<br />

resultado final al usuario. <strong>Los</strong> procedimientos almacenados pue<strong>de</strong>n permitir que <strong>la</strong> lógica <strong>de</strong>l<br />

negocio se encuentre como un API en <strong>la</strong> <strong>base</strong> <strong>de</strong> <strong>datos</strong>, que pue<strong>de</strong>n simplificar <strong>la</strong> gestión <strong>de</strong> <strong>datos</strong><br />

y reducir <strong>la</strong> necesidad <strong>de</strong> codificar <strong>la</strong> lógica en el resto <strong>de</strong> los programas cliente. Esto pue<strong>de</strong> reducir<br />

<strong>la</strong> probabilidad <strong>de</strong> que los <strong>datos</strong> sean corrompidos por el uso <strong>de</strong> programas clientes <strong>de</strong>fectuosos o<br />

erróneos. De este modo, el motor <strong>de</strong> <strong>base</strong> <strong>de</strong> <strong>datos</strong> pue<strong>de</strong> asegurar <strong>la</strong> integridad <strong>de</strong> los <strong>datos</strong> y <strong>la</strong><br />

consistencia, con <strong>la</strong> ayuda <strong>de</strong> procedimientos almacenados.<br />

-Una señal <strong>de</strong> un sistema <strong>de</strong> <strong>base</strong> <strong>de</strong> <strong>datos</strong> es que evita que los usuarios accedan directamente a<br />

<strong>la</strong>s tab<strong>la</strong>s y fuerzan a utilizar los P.A. Para funciones específicas.<br />

-Es más fácil gestionar los conjuntos <strong>de</strong> P.A. Por funcionalidad que gestionar una tab<strong>la</strong> a nivel <strong>de</strong><br />

columnas.<br />

Desventajas:<br />

Pue<strong>de</strong> que no sea el mejor lugar para poner una lógica compleja. Sin embargo, tras <strong>la</strong> i<strong>de</strong>a <strong>de</strong> que<br />

una lógica compleja pertenece en código <strong>de</strong> aplicación y no en procedimientos almacenados,<br />

procedimientos almacenados se convierten simplemente en <strong>la</strong>s operaciones CRUD (cada mesa<br />

tiene un "Crear", "Leer", "actualización" y "Borrar" procedimiento). En ese caso, los<br />

procedimientos almacenados no aña<strong>de</strong> ningún valor a <strong>la</strong> <strong>de</strong>manda, sólo complicar el<br />

mantenimiento y <strong>la</strong> convierten en residuos.


Ejemplos:<br />

1.-<br />

CREATE PROCEDURE spu_addCliente @nombre varchar(100),<br />

@apellido1 varchar(100),<br />

@apellido2 varchar(100),<br />

@nifCif varchar(20),<br />

@fxNaciento datetime<br />

AS<br />

INSERT INTO CLIENTES<br />

(nombre, apellido1, apellido2, nifcif, fxnacimiento) VALUES<br />

(@nombre, @apellido1, @apellido2, @nifCif, @fxNaciento)<br />

DECLARE @fecha_nacimiento datetime<br />

set @fecha_nacimiento = convert(datetime, '13/05/1975', 103)<br />

EXEC spu_addCliente 'Pedro', 'Herrarte', 'Sanchez',<br />

'00000002323', @fecha_nacimiento<br />

2.-<br />

CREATE PROCEDURE spu_ObtenerSaldoCuenta @numCuenta varchar(20),<br />

@saldo <strong>de</strong>cimal(10,2) output<br />

AS<br />

BEGIN<br />

SELECT @saldo = SALDO<br />

FROM CUENTAS<br />

WHERE NUMCUENTA = @numCuenta<br />

END<br />

Y para ejecutar este procedure:<br />

DECLARE @saldo <strong>de</strong>cimal(10,2)<br />

EXEC spu_ObtenerSaldoCuenta '200700000001', @saldo output<br />

PRINT @saldo<br />

3.-<br />

CREATE PROCEDURE spu_EstaEnNumerosRojos @numCuenta varchar(20)<br />

AS<br />

BEGIN<br />

IF (SELECT SALDO FROM CUENTAS<br />

WHERE NUMCUENTA = @numCuenta) < 0<br />

BEGIN<br />

RETURN 1<br />

END<br />

ELSE<br />

RETURN 0<br />

END<br />

DECLARE @rv int<br />

EXEC @rv = spu_EstaEnNumerosRojos '200700000001'<br />

PRINT @rv

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!