Untitled
unknown
sqlserver
2 years ago
6.7 kB
5
Indexable
1) Hacer un trigger que al eliminar un Agente su estado Activo pase de True a False.
create trigger TR_BajaLogicaAgente ON Agentes
instead of delete
as
begin
declare @IdAgente int
select @IdAgente = IdAgente from deleted
update Agentes set Activo = 0 where IdAgente = @IdAgente
end
2) Modificar el trigger anterior para que al eliminar un Agente
y si su estado Activo ya se encuentra previamente en False entonces
realice las siguientes acciones:
->Cambiar todas las multas efectuadas por ese agente y establecer el valor NULL al campo IDAgente.
->Eliminar físicamente al agente en cuestión.
*Utilizar una transacción
alter trigger TR_BajaLogicaAgente ON Agentes
instead of delete
as
begin
begin try
begin transaction
declare @IdAgente int
declare @Estado bit
select @IdAgente = IdAgente, @Estado = Activo from deleted
if @Estado = 1
begin
update Agentes set Activo = 0 where IdAgente = @IdAgente
end
else
begin
update Multas set IdAgente = NULL where IdAgente = @IdAgente
delete Agentes where IdAgente = @IdAgente
end
commit transaction
end try
begin catch
rollback transaction
raiserror('No se pudo procesar correctamente la eliminación', 16, 1)
end catch
end
*ejemplo de GPT que no emplea bloque try/catch y que valida primero errores para hacer un rollback y luego recién el commit
ALTER TRIGGER TR_BajaLogicaAgente ON Agentes
INSTEAD OF DELETE
AS
BEGIN
BEGIN TRANSACTION; Iniciar transacción
DECLARE @IdAgente INT;
DECLARE @Estado BIT;
SELECT @IdAgente = IdAgente, @Estado = Activo FROM deleted;
IF @Estado = 1
BEGIN
UPDATE Agentes SET Activo = 0 WHERE IdAgente = @IdAgente;
END
ELSE
BEGIN
UPDATE Multas SET IdAgente = NULL WHERE IdAgente = @IdAgente;
DELETE FROM Agentes WHERE IdAgente = @IdAgente;
END
Verificar si hay errores y deshacer cambios si es necesario
IF @@ERROR <> 0
BEGIN
ROLLBACK TRANSACTION; Deshacer transacción en caso de error
END
ELSE
BEGIN
COMMIT TRANSACTION; Confirmar transacción si no hay errores
END
END
3) Hacer un trigger que al insertar una multa realice las siguientes acciones:
- No permitir su ingreso si el Agente asociado a la multa no se encuentra Activo. Indicarlo con un mensaje claro que sea considerado una excepción.
- Establecer el Monto de la multa a partir del tipo de infracción.
- Aplicar un recargo del 20% al monto de la multa si no es la primera multa del vehículo en el año.
- Aplicar un recargo del 25% al monto de la multa si no es la primera multa del mismo tipo de infracción del vehículo en el año.
- Establecer el estado Pagada como False.
-
alter trigger TR_InsertarMulta ON Multas
after insert
as
begin
begin transaction
declare @EstadoAgente bit
select @EstadoAgente = A.Activo from Agentes as A inner join Multas as M on A.IdAgente = M.IdAgente
where A.IdAgente = (Select IdAgente from inserted)
validación para impedir la carga, si corresponde
if @EstadoAgente = 0
begin
rollback transaction
raiserror('El agente asociado a la multa no se encuentra activo. Revise los datos e intente nuevamente', 16, 1)
end
declaración de variables y contadores
declare @MontoXTipo money
select @MontoXTipo = TI.ImporteReferencia from TipoInfracciones as TI
inner join Multas as M on TI.IdTipoInfraccion = M.IdTipoInfraccion
where TI.IdTipoInfraccion = (select IdTipoInfraccion from inserted)
declare @ContadorMultasXAnio int
select @ContadorMultasXAnio = COUNT(*) from Multas
where Multas.Patente = (select Patente from inserted) and YEAR(Multas.FechaHora) = YEAR(GETDATE())
declare @ContadorMultasXTipo int
select @ContadorMultasXTipo = COUNT(distinct IdTipoInfraccion) from Multas
where Multas.Patente = (select Patente from inserted) and YEAR(Multas.FechaHora) = YEAR(GETDATE())
and Multas.IdTipoInfraccion = (select IdTipoInfraccion from inserted)
condicionales para aumentar el Monto, si corresponde
if @ContadorMultasXAnio > 0 begin
select @MontoXTipo = @MontoXTipo * 1.2
end
if @ContadorMultasXTipo > 0 begin
select @MontoXTipo = @MontoXTipo * 1.25
end
update Multas set Multas.Monto = @MontoXTipo, Multas.Pagada = 0
where Multas.IdMulta = (select IdMulta from inserted)
commit transaction
end
*Testeado con patentes 'A111AAA', la cual tiene más de una en el año, pero todas del mismo tipo ($12.000)
y con 'AB123CD', la cual tiene más de una en el año y de distintos tipos ($15.000)
4) Hacer un trigger que al insertar un pago realice las siguientes verificaciones:
- Verificar que la multa que se intenta pagar se encuentra no pagada.
- Verificar que el Importe del pago sumado a los importes anteriores de la misma multa no superen el Monto a abonar.
En ambos casos impedir el ingreso y mostrar un mensaje acorde.
- Si el pago cubre el Monto de la multa ya sea con un pago único o siendo la suma de pagos
anteriores sobre la misma multa. Además de registrar el pago se debe modificar el estado Pagada de la multa relacionada.
alter trigger TR_InsertarPago on Pagos
after insert
as
begin
begin transaction
declare @MultaPagada bit
select @MultaPagada = M.Pagada from Pagos as P inner join Multas as M on M.IdMulta = P.IDMulta where M.IdMulta = (select IdMulta from inserted)
declare @SumaDePagos money
select @SumaDePagos = sum(Importe) from Pagos as P where P.IDMulta = (select IDMulta from inserted)
declare @MontoMulta money
select @MontoMulta = M.Monto from Pagos as P inner join Multas as M on P.IDMulta = M.IdMulta where M.IdMulta = (select IdMulta from inserted)
if @MultaPagada = 1
begin
rollback transaction
raiserror('La multa ya se encuentra pagada en su totalidad', 16, 1)
end
if @SumaDePagos > @MontoMulta
begin
rollback transaction
raiserror('El pago que intenta ingresar, ya sea parcial o total, excede el monto de la multa', 16, 1)
end
if @SumaDePagos = @MontoMulta
begin
update Multas set Multas.Pagada = 1 where Multas.IdMulta = (select IdMulta from inserted)
end
insert into Pagos(IDMulta, Importe, Fecha, IDMedioPago) select i.IDMulta, i.Importe, i.Fecha, i.IDMedioPago from inserted as i
el insert no va, porque es un after inster, así que ya fue ingresado. Y no tiene sentido un instead of insert en Pagos para
finalmente hace un insert en Pagos
commit transaction
end
Editor is loading...