Untitled

mail@pastecode.io avatar
unknown
sqlserver
a year ago
6.7 kB
1
Indexable
Never
 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