Está en la página 1de 63

Sql Server

Desencadenadores
Concepto
• Controlar los datos
– no permitir eliminar un cliente si tiene pedidos
• solución: relación de clave externa
– permitir insertar y modificar, pero no eliminar
• solución: configuración seguridad del servidor
– notificar cuando se elimina un dato
– notificar cuando superamos 1000€ de venta
• solución: uso de desencadenadores (triggers)
Tipos de desencadenadores
• INSERT
• UPDATE
• DELETE
• INSTEAD OF
Introducción
• un desencadenador es una serie de
instrucciones Sql
• muy similar al procedimiento almacenado
– a un desencadenador NO se le puede llamar con
EXEC
– los desencadenadores se activan cuando un
usuario ejecuta una instrucción Transact-SQL
Tipos
• los desencadenadores del lenguaje de manipulación
de datos (DML) se activan con instrucciones
– INSERT
– UPDATE
– DELETE
• desencadenadores del lenguaje de definición de
datos (DDL)
– CREATE
– ALTER
– DROP
Ejemplo
• desencadenador para INSERT
– no puede insertar un cliente extranjero
– cuando usuario inserta un nuevo cliente
• desencadenador INSERT
– ejecuta
– determina si cumple criterio del desencadenador
» cumple
• completa insert
Desencadenadores INSERT
• se puede usar para modificar o impedir un
registro que se está insertando
– impedir insertar un cliente de tal ciudad o con un
descuento superior a tanto
– añadir datos al registro que se inserta
– añadir cambios en cascadas en otras tablas
• insertar un registro en tabla de usuarios y además en la
tabla de contactos
• Se activan cuando se intenta crear un nuevo
registro en una tabla con el comando INSERT
– Sql copia el nuevo registro en una tabla de
desencadenadores
– y tb en otra tabla especial almacenada en
memoria llamada inserted
• el nuevo registro existe en dos tablas
– desencadenadores
– inserted
» ambos deben coincidir
• Tabla inserted
– fundamental para hacer cambios en cascada
• cuando se venda algo
– debemos restar de unidades en stock
– permite entonces mantener el inventario actualizado
Solución
• almacenar cantidad vendida en una variable
de memoria y actualizar tabla con UPDATE
– requiere más codigo
– ralentiza el sistema
• utilizar tabla inserted
– extrae el valor de inserted y lo aplica a la tabla de
existencias
• UPDATE tabla1
• SET tabla1.existencias= (tabla1.existencias –
tabla2.unidadesvendidas)
• FROM tabla1 JOIN tabla2
• ON tabla1.id=tabla2.id
Crear desencadenador
• Explorador objetos – Bases de Datos – Tablas –
Tabla elegida – carpeta Desencadenadores
– boton derecho – nuevo desencadenador
– se abre una plantilla
Desencadenador
• CREATE TRIGGER dbo.nombreDesencadenador ON dbo.NombreTabla
AFTER INSERT
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

•   UPDATE p
  SET p.unidadesenstock = (p.unidadesenstock - q.unidadesvendidas)
  FROM Productos p JOIN Ventas q
   ON   p.id=q.id

END
GO
• clic en ejecutar para crear el desencadenador
• ya hemos creado el desencadenador INSERT
en la tabla
• creamos un nuevo registro en la tabla
• vemos cómo se debe activar el
desencadenador
– modifica existencias en stock
• Abrimos nueva sonsulta

– INSERT tabla existencias


– VALUES (dato1, dato2, dato3, getDate())
• Comprobamos
– haces otra consulta
• SELECT * FROM Tabla

• ha cambiado la cantidad???
Desencadenadores DELETE
• usados para restringuir los datos que los
usuarios pueden eliminar de una BD
– no eliminar
– comunicar su eliminación
Método de trabajo para DELETE
• cuando se ejecuta una instrucción DELETE
– Sql quita un registro de una tabla
– con desencadenador DELETE
• Sql mueve el registro a una tabla en memoria llamada
deleted
• los registros NO desaparecen por completo
• se puede hacer referencia a ellos
Crear desencadenador DELETE
• Explorador de objetos – Tabla – seleccionas
una – carpeta Desencadenadores – boton
derecho – nuevo desencadenador
• para crear el desencadenador debemos
Ejecutar
• CREATE TRIGGER dbo.nombreDesencadenador ON dbo.NombreTabla
AFTER DELETE
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

• IF (SELECT ciudad FROM deleted) = ‘Madrid’


• BEGIN
• PRINT ‘no se puede eliminar’
• PRINT ‘la transaccion ha sido cancelada’
• ROLLBACK
• END


END
GO
• eliminas algunos registros
– DELETE FROM Customers
– WHERE nombre = ‘juan’
• comprueba si ha eliminado algo
• funciona?
Desencadenadores UPDATE
• permiten restringir instrucciones UPDATE
emitidas por los usuarios
– intercepta modificaciones de datos y las verifica
– utiliza una combinación de los métodos usados
por los desencadenadores INSERT y DELETE
• el desencadenador UPDATE utiliza las dos tablas
– inserted
– deleted
• una acción UPDATE se compone de dos
acciones
– una eliminación
– seguida de una inserción

– ventaja
• podemos comparar las dos tablas
• Permite arreglar errores como
– vender un producto en exceso
– cuando existencias en stock tenga números
negativos…
• Podemos crear un desencadenador que
compruebe las unidades en Stock de una tabla
– Carpeta desencadenadores – boton derecho -
nuevo
• CREATE TRIGGER dbo.nombreDesencadenador ON dbo.NombreTabla
AFTER UPDATE
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

•  IF (SELECT existencias FROM inserted) < 0


• BEGIN
• PRINT ‘no se puede actualizar’
• PRINT ‘la transaccion ha sido cancelada’
• ROLLBACK
• END

END
GO
• vamos a ver si se activa el desencadenador
– UPDATE tabla productos
– SET existencias = (existencias – 1000)
– WHERE id=10
• intenta cambiar el numero de existencias para
el producto 10
– tiene que dar error
– comprueba los datos de la tabla con un select si
quieres
Desencadenador IF UPDATE
• este desencadenador rechaza cambios en un
campo
– imagina un campo que no puede cambiar
• CREATE TRIGGER dbo.nombreDesencadenador ON dbo.NombreTabla
AFTER UPDATE
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

•  IF UPDATE (campo)


• BEGIN
• PRINT ‘no se puede actualizar’
• PRINT ‘la transaccion ha sido cancelada’
• ROLLBACK
• END

END
GO
• intenta

• UPDATE tabla
• SET campo=‘dato’
• WHERE nombre=‘juan’
• no debe permitir actualizar el campo
Desencadenadores INSTEAD OF
• este desencadenador es el responsable de
insertar o eliminar nuevos registros.
• si insertas registros en una tabla
– debes incluir todos los registros obligatorios
– piensa en una vista que no muestre todos los
campos
• error …al insertar
• con INSTEAD OF evitamos ese error
• Creamos una vista de una tabla
– CREATE VIEW nombre vista AS
– SELECT campo2, campo2
– FROM Customers
– WHERE City=‘Madrid’
• vemos la vista

• SELECT * FROM nombrevista


• intentamos insertar un nuevo registro en la
vista

• INSERT nombrevista
• VALUES (‘dato1’, ‘dato2’, ….)

• si ejecutas error…pq no metes todos los


campos obligatorios
• Creamos un nuevo desencadenador
• CREATE TRIGGER dbo.nombreDesencadenador ON dbo.NombreVista
INSTEAD OF
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

• DECLARE
• @PARAMETRO1 VARCHAR(20),
• @PARAMETRO2 CHAR(5)
• SET @CIUDAD=‘Madrid’
• SET @PARAMETRO1 = (SELECT CAMPO1 FROM INSERTED)

• INSERT Customers
• VALUES (@PARAMETRO1, @PARAMETRO2, @CIUDAD….)

END
GO
• Ejecuta el desencadenador para crearlo
• ahora vuelves a repetir el codigo de INSERT en
la vista
• da error?
Avanzado
• Combinar desencadenadores para facilitar
administración
• usar RAISERROR() en lugar de PRINT()
• desencadenadores recursvios
– desencadenador de una tabla realiza una acción
que activa el desencadenador de otra tabla
Combinar desencadenadores
• nos aseguramos que nadie pueda insertar,
actualizar o eliminar registros excepto la
administración
• No necesitamos crear tres desencadenadores
distintos
– los combinamos de dos en dos o tres
• Creamos un nuevo desencadenador
• CREATE TRIGGER dbo.nombreDesencadenador ON dbo.NombreTabla
AFTER DELETE, UPDATE
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

•  IF (SELECT nombre FROM deleted) =‘juan’


• BEGIN
• PRINT ‘no se puede eliminar’
• PRINT ‘la transaccion ha sido cancelada’
• ROLLBACK
• END

END
GO
• Ejecuta el desencadenador para crearlo

• ahora intenta eliminar a juan

• DELETE FROM Customers


• WHERE nombre=‘juan’

• debe saltar error


• ahora igual con UPDATE

• UPDATE Customers
• SET nombre=‘maria’
• WHERE nombre=‘juan’

• tb debe saltar error


Notificar error con RAISERROR()
• Print para mostrar mensajes de error
– no podemos enviar alerta a la administración
• RAISERRROR permite enviar mensajes a cualquiera
– RAISERROR(‘message’, severity, state)
• message
– mensaje de error
• severity
– gravedad de error
– de 1 a 25 (el más grave)
– 10 es informativo
• state
– si se genera en más de un lugar del desencadenador
– en comienzo 1, en medio 2….
• podemos modificar un desencadenador
• con ALTER
• ALTER TRIGGER dbo.nombreDesencadenador ON dbo.NombreTabla
AFTER DELETE, UPDATE
AS
BEGIN
  — No retorna el mensaje de cantidad de registros afectados
  SET NOCOUNT ON  

•  IF (SELECT nombre FROM deleted) =‘juan’


• BEGIN
• RAISERROR (‘no se puede eliminar’, 10,1)
• ROLLBACK
• END

END
GO
• lo pruebas intentando delete

• DELETE FROM Customers


• WHERE nombre=‘juan’
Desencadenadores recursivos
• Podemos tener desencadenadores en cada
tabla de datos
– un desencadenador que actualiza otras tablas
puede activar desencadenadores de esas tablas
• un ejemplo podria ser
– al insertar un nuevo registro en tabla Pedidos
• desencadenador INSERT se activa y actualiza la
columna de la tabla Productos
– resta la cantidad vendida
• en la tabla Productos
– desencadenador UPDATE para asegurarse que la cantidad no
es menor que cero
• No funciona
– protección
• desencadenadores recursivos están deshabilitados por
defecto
• todos los desencadenadores juntos se
consideran como una transacción
– comando ROLLBACK
• si no se aplican ambos, se cancela todo y se eliminan
los datos hasta el momento
• solo recursivos hasta 16 niveles
• Bases de datos – boton derecho –
Propiedades – pagina Opciones –
Desencadenadores recursivos habilitados en
True
• consulta nueva

– INSERT Pedidos
– VALUES (1, 3, 5, getDate())
• comprobamos

• SELECT * from Pedidos


• si tnemos los desencadenadores INSERT y
UPDATE
– deben aplicarse ahora
Desencadenores DDL
• Data Definition Language
• los DDL NO se activan con eventos de
– INSERT, UPDATE Y DELETE
• sino
– CREATE, ALTER Y DROP
• instrucción que modifica la estructura de datos
• Desencadenador que evita eliminar registros
• CREATE TRIGGER dbo.nombreDesencadenador ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS

– PRINT ‘no se puede eliminar’


• ROLLBACK
• END

END
GO
• hacemos una consulta

• DROP TABLE laquequieras

• no puede dejarte

También podría gustarte