Você está na página 1de 19

Tengamos o no tengamos Triggers almacenados en nuestra base de datos, suceden

situaciones que nosotros no vemos en las tablas.


Cada vez que insertamos registros en una tabla, se crea una tabla temporal con el nombre
INSERTED, la cual, una vez los registros terminan de ser insertados, pues esa tabla se
elimina de forma automática.
TABLA TEMPORAL UNA VEZ INSERTADOS LOS REGISTROS SE ELIMINA AUTOMATICAMENTE

De igual manera sucede cuando eliminamos registros, creando una tabla temporal
llamada DELETED, que cuando finalizamos la eliminación, pues dicha tabla temporal es
eliminada también automáticamente.
TABLA TEMPORAL UNA VEZ ELIMINADOS LOS REGISTROS SE ELIMINA AUTOMATICAMENTE

Por otra parte, cuando realizamos un UPDATE, pues se crean dos tablas temporales,
DELETED e INSERTED. Ya que un UPDATE, utiliza la tabla temporal DELETED, para
eliminar un registro que posteriormente, con la tabla INSERTED, lo sustituirá por uno
actualizado.
SE CREAN 2 TABLAS TEMPORALES

YA QUE UPDATE UTILILZA LA TABLA TEMPORAL DELETED, PARA ELIMINAR UN REGISTRO

1
Y LA TABLA TEMPORAL INSERTED LO SUSTITUIRA POR UNO ACTUALIZADO SE ELIMINAN AUTOMATICAMENTE

Cabe mencionar que estas tablas temporales, se crean a partir de la misma estructura, de
las tablas con las cuales estemos trabajando. ¿Por qué resalto estos puntos? Pues… por
el simple hecho que los triggers aprovechan estas situaciones para ejecutarse.

¿QUÉ ES UN TRIGGER?
Es un procedimiento almacenado el cual se dispara cuando intentamos modificar una tabla
o una vista, a diferencia de los procedimientos almacenados, los triggers no se pueden
ejecutar de forma directa. Sino que obedecen a acciones que se realizan en una tabla en
particular en donde se hayan establecido, dependiendo de la acción que los desencadene.
Que puede ser un INSERT, un DELETE o un UPDATE.

2
EJEMPLO:
Vamos a crear la Base de datos Inventario y dentro de ella vamos a crear las siguientes
tablas: Productos, Historial y Ventas. Con las cuales vamos a realizar diferentes
ejemplos.
create database inventario;
GO

use inventario;
GO

create table productos


(
id_Cod int identity primary key,
cod_prod varchar(4) not null,
nombre varchar(50) not null,
existencia int not null,
)
GO

Create table historial


(fecha date,
descripcion varchar(100),
usuario varchar(20))
GO

create table ventas


(cod_prod varchar(4),
precio money,
cantidad int
)
GO

Realicemos una consulta de las Tablas historial y productos para verificar que no tienen
registros almacenados en ellas.

3
El primer Trigger que vamos a crear se dispara cuando insertemos registros en la Tabla
productos, guardando en la tabla historial el detalle de la acción.
Nota: Este Trigger se dispara por inserción en la tabla productos, bajo el contexto que se
declara en la cláusula AS para su ejecución.
create trigger TR_ProductoInsertado
on productos for insert
as
insert into historial values(getdate(), 'registro insertado',
system_user)
go

Creamos el trigger TR_ProductoInsertado:

Dicho Trigger ha sido almacenado en la siguiente ubicación


y pueden ver que es parte de la tabla productos por lo tanto
se disparara cuando hagamos inserciones de nuevos
registros en ella.

4
Vamos a insertar el primer registro y note que aparecen dos filas afectadas, en donde
la primera corresponde a la inserción del nuevo registro y la segunda es el resultado
de la ejecución del Trigger. Lo cual envió a la Tabla historial un registro de la acción
realizada.

Realicemos una consulta:

5
OBSERVACIONES:
Si se quieren agregar más datos al historial, como el nombre del producto o el código del
producto, pues hay que modificar tanto el Trigger como la estructura de la tabla, es decir la
tabla historial.
-- ELIMINA PRIMERO LA TABLA HISTORIAL--
drop table historial

-- CREAR LA TABLA HISTORIAL NUEVAMENTE


Create table historial
(fecha date,
cod_prod varchar(4),
descripcion varchar(100),
usuario varchar(20))
GO

--- ELIMINAR LOS REGISTRO DE LA TABLA PRODUCTOS


truncate table productos
go

-- MODIFICAR AHORA EL TRIGGER, Y CAMBIAMOS LA PALABRA CREATE POR ALTER


-- PARA HACER LA RESPECTIVA MODIFICACION
alter trigger TR_ProductoInsertado
on productos for insert
as
declare @cod_prod varchar(4)
select @cod_prod = cod_prod from inserted
insert into historial values(getdate(), @cod_prod, 'registro insertado',
system_user)
go

-- INSERTAMOS UN REGISTRO
insert into productos values('A001','MEMORIA USB 32GB',175);

-- REALIZAMOS UNA CONSULTA


select * from historial
select * from productos
go

historial

productos

6
Ahora bien, sucede algo que debemos de evitar durante la ejecución del
Trigger, y es el hecho de que alguien puede percatarse de que hay un
Trigger detrás de todo el proceso.

Hay que modificar el Trigger de tal forma que solo aparezca la fila afectada
correspondiente a la inserción de los datos, para ello vamos a colocar lo
siguiente al Trigger.

alter trigger TR_ProductoInsertado


on productos for insert
as
set nocount on
declare @cod_prod varchar(4)
select @cod_prod = cod_prod from inserted
insert into historial values(getdate(), @cod_prod, 'registro insertado',
system_user)
go

7
El segundo Trigger que vamos a crear, que nos registre las acciones de eliminación en
la tabla.

create trigger TR_ProductoEliminado


on productos for delete
as
set nocount on
declare @cod_prod varchar(4)
select @cod_prod = cod_prod from deleted
insert into historial values(getdate(), @cod_prod, 'registro eliminado',
system_user)
go

8
Ahora bien, vamos a eliminar un registro para verificar la ejecución del Trigger de
TR_ProductoEliminado.

--- ELIMINEMOS UN PRODUCTO DE LA TABLA PARA VERIFICAR LA EJECUCION DEL


TRIGGER DE ELIMINACION

delete from productos where cod_prod = 'A003'


GO

Realicemos una consulta de ambas tablas para verificar los movimientos generados.

9
El tercer Trigger que vamos a crear, que nos registre las acciones de actualización en la
tabla.

create trigger TR_ProductoActualizado


on productos for update
as
set nocount on
declare @cod_prod varchar(4)
select @cod_prod = cod_prod from inserted
insert into historial values(getdate(), @cod_prod, 'registro
actualizado', system_user)
go

Ahora bien, vamos a actualizar un registro para verificar la ejecución del Trigger de
TR_ProductoActualilzado.

update productos set existencia =180 where cod_prod = 'A001'


go

historial

productos

10
Vamos a crear un Trigger por medio del cual disminuiremos las existencias de un
determinado producto, cuando insertemos un registro en la tabla ventas o para que se
comprenda mejor, cuando realicemos una operación de venta.

create trigger TR_Ventas


on ventas for insert
AS
set nocount on
update productos set productos.existencia = productos.existencia -
inserted.cantidad
from inserted inner join productos
on productos.cod_prod = inserted.cod_prod
go

Realicemos una consulta de las dos tablas para


ver que producto vamos a vender.

ventas

productos

11
Realicemos la venta del producto A002.

--- REALICEMOS LA VENTA DEL PRODUCTO A002, ASUMIENDO QUE EL PRODUCTO


TIENE UN COSTO DE 150 DE 3 PRODUCTOS

insert into ventas values('A002', 450, 3)


go

--- CONSULTEMOS LAS TABLAS VENTAS Y PRODUCTOS

select * from ventas


select * from productos
go

ventas

productos

12
Con este procedimiento almacenado podemos verificar si una tabla contiene o no un
Trigger almacenado y a su vez podemos verificar cual es el Tipo de Trigger que
contiene.

sp_helptrigger ventas
go

sp_helptrigger productos
go

13
OBSERVACIONES:

Existen 2 tipos de Trigger:


1. Tipo after
2. Tipo instead of

1. Tipo after: Son aquellos que se disparan después de una acción, como puede ser
un UPDATE, un DELETE o un INSERT. Como habrán notado en cada uno de los
Triggers se utilizó la cláusula FOR, pudiendo haber utilizado la cláusula AFTER, sin
embargo, cuando utilizamos FOR por defecto se comprende que el Trigger que
estamos definiendo es de tipo AFTER.

2. Tipo instead of: Este tipo de Trigger se dispara antes de que ocurra un cambio en
las tablas, como puede ser un INSERT, un UPDATE o un DELETE, brindándonos
alternativas de acción según el criterio que nosotros establezcamos, por lo que
cuando se dispara cancela el resto de las acciones, ejecutando únicamente la que
cumpla el criterio definido, cabe destacar que cuando las tablas contengan llaves
foráneas que indiquen una acción de eliminación en cascada y actualización en
cascada, pues no se pueden crear Triggers instead of delete o instead of update.

14
Por otra parte, los disparadores de tipo after como los ejemplos anteriores, no se pueden
definir sobre vistas creadas.

En el caso de un Trigger instead of insert normalmente se define en una vista para


insertar datos en una o varias tablas bases.

EJEMPLO:

En primer lugar, vamos a crear 3 Tablas y noten que las tres tablas tienen la misma
estructura y el objetivo de este ejemplo es enviar productos a una tienda en particular, por
lo que el Trigger que vamos a definir tendrá que ejecutar una de tres acciones establecidas,
según el destino que nosotros asignemos y de esa forma cancelara las otras acciones al
no cumplir el criterio especificado, que en este caso sería el destino de la tienda hacia donde
se enviaran los productos.

use inventario
go
create table tienda1
(n_envio int,
cod_prod varchar(4),
nombre varchar(100),
Cantidad int)
go

create table tienda2


(n_envio int,
cod_prod varchar(4),
nombre varchar(100),
Cantidad int)
go

create table tienda3


(n_envio int,
cod_prod varchar(4),
nombre varchar(100),
Cantidad int)
go

15
REALICEMOS UNA CONSULTA DE LAS 3 TABLAS CREADAS.

tienda1

tienda2

tienda3

AHORA PROCEDAMOS A CREAR LA VISTA.

create view tiendas


as
select n_envio, cod_prod, nombre, cantidad, 'tienda1' as destino from tienda1
union all
select n_envio, cod_prod, nombre, cantidad, 'tienda2' as destino from tienda2
union all
select n_envio, cod_prod, nombre, cantidad, 'tienda3' as destino from tienda3
go

CONSULTEMOS LA VISTA.

16
AQUÍ SE ESTA OBSERVANDO LA COMBINACION DE LAS 3 TABLAS. LA
COMBINACION QUE HEMOS REALIZADO A DICHAS TABLAS, LA HE DEFINIDO
MEDIANTE union all, ASI DE ESTA FORMA PODRE ENVIAR LOTES DE
PRODUCTOS A UNA TIENDA EN PARTICULAR, POR LO QUE PODRE COLOCAR EL
NUMERO DE ENVIO REPEDITO EN DICHO LOTE DE PRODUCTOS A ENVIAR Y ESTO
ME LO PERMITIRA LA PALABRA CLAVE all, YA QUE, SI LA OMITIMOS, SOLO
PODRIAMOS ENVIAR UN PRODUCTO POR CADA NUMERO DE ENVIO, IMPIDIENDO
QUE SE REPITA. VEAN QUE A LA VISTA LE HE AGREGADO UNA COLUMNA EXTRA
COMO DESTINO, EN DONDE ESTABLECEMOS EL NOMBRE DE CADA UNA DE LAS
TIENDAS, PARA QUE EL TRIGGER QUE DEFINIMOS PUEDA IDENTIICAR CADA
DESTINO Y ASI INSERTAR LOS ENVIOS DONDE CORRESPONDA.

CREAREMOS EL TRIGGER:

create trigger TR_Destinos


on tiendas instead of insert
as
set nocount on
insert into tienda1
select n_envio, cod_prod, nombre, cantidad from inserted where destino='tienda1'
insert into tienda2
select n_envio, cod_prod, nombre, cantidad from inserted where destino='tienda2'
insert into tienda3
select n_envio, cod_prod, nombre, cantidad from inserted where destino='tienda3'
go

INSERTEMOS EL PRIMER REGISTRO.

insert into tiendas values(1, '1001', 'MOUSE OPTICO', 500, 'tienda1')


GO

CONSULTEMOS LAS TABLAS:

17
INSERTEMOS EL SIGUIENTE LOTE DE PRODUCTOS EN UN SOLO NUMERO DE
ENVIOS.

insert into tiendas values(2, '1002', 'Monitor LED 17 pulgadas', 35, 'tienda3')
insert into tiendas values(2, '1003', 'CABLE HDMI', 50, 'tienda3')
insert into tiendas values(2, '1004', 'AIRE COMPRIMIDO', 45, 'tienda3')
insert into tiendas values(2, '1005', 'PASTA TERMICA', 23, 'tienda3')
go

COLSULTEMOS LAS TABLAS BASES:

tienda1
tienda2

tienda3

INSERTEMOS LOS SIGUIENTES REGISTROS, QUE VAN PARA LAS 3 TIENDAS.

insert into tiendas values(3, '1006', 'TECLADO P/TABLET', 100, 'tienda1')


insert into tiendas values(4, '1007', 'FUNDA TECLADO', 230, 'tienda2')
insert into tiendas values(5, '1008', 'MEMORIA MICRO SD 16GB', 700, 'tienda3')
go

CONSULTEMOS LAS TRES TABLAS BASES:

select * from tienda1


select * from tienda2
select * from tienda3
go

18
CONSULTEMOS POR ULTIMO LA VISTA:

select * from tiendas

19

Você também pode gostar