¿Cómo implementar validaciones en triggers para asegurar la integridad de los datos?
Los triggers son una herramienta poderosa para mantener la integridad de los datos en una base de datos. Con su capacidad para responder a eventos como inserciones y actualizaciones, podemos impulsar su funcionalidad aún más añadiendo validaciones condicionadas. En esta clase, se profundizó en la implementación de validaciones al modificar un trigger de inserción para la tabla de usuarios. Vamos a explorar cómo implementar estas validaciones adicionales y asegurar que solo se procesen ciertos datos.
¿Cómo declarar variables y realizar validaciones específicas?
Cuando se trabaja con triggers, una práctica común es declarar variables para capturar datos específicos que se están inseriendo o actualizando. Este proceso nos permite controlar y validar la información entrante antes de que esta impacte la base de datos.
DECLARE@codigoINT;SET@codigo=(SELECT codigo FROM inserted);
En este ejemplo, se declara una variable @codigo para almacenar el código que se está insertando. Una vez capturado este dato, podemos realizar una validación específica. Por ejemplo, si deseamos que los códigos que se inserten sean menores o iguales a diez:
IF@codigo>10BEGINPRINT'No se realizó el insert';ROLLBACK;RETURN;END
Aquí, si el código es mayor a diez, se cancela la operación de inserción mediante un ROLLBACK, y se muestra un mensaje informativo.
¿Cómo modificar un trigger existente?
Modificar un trigger para agregar validaciones es un proceso relativamente sencillo. Podemos utilizar la declaración CREATE OR ALTER para garantizar que el trigger se modifique adecuadamente.
CREATEORALTERTRIGGER trigger_usuario_insert
ON usuarios_target
AFTERINSERTASBEGINDECLARE@codigoINT;SET@codigo=(SELECT codigo FROM inserted);IF@codigo>10BEGINPRINT'No se realizó el insert';ROLLBACK;RETURN;ENDEND;
El uso de CREATE OR ALTER es útil pues, en caso de que el trigger ya exista, este comando asegura que se actualice en lugar de causar un conflicto.
¿Qué importancia tiene la práctica de incorporar validaciones en triggers?
Incorporar validaciones en triggers no solo refuerza la integridad de los datos, sino que también previene entradas no deseadas o erróneas. En la práctica, esto significa que podemos establecer reglas de negocio directamente en la base de datos, asegurando que solo los datos válidos se procesen.
Como práctica adicional, puedes intentar actualizar el trigger para la función de UPDATE en la misma tabla, aplicando validaciones similares. Por ejemplo, podrías validar un nombre específico o cualquier otra condición que consideres importante para tu base de datos.
¿Qué sigue después de mejorar los triggers?
En clases futuras, el enfoque se desplazará hacia triggers a nivel de base de datos. Estas son más administrativas y permiten validar cambios en la estructura de las tablas, así como su creación. Esta evolución promete profundizar más en la seguridad e integridad estructural de la base de datos. ¡Nos vemos en la siguiente clase, donde se explorará esta fascinante área!
Trigger que valida si el nombre tiene mas de 15 carácteres o si el puntaje es mayor a 100:
ALTERTRIGGER tr_Update ONUsuarioTargetAFTERUPDATEASBEGINIF(ROWCOUNT_BIG()=0)RETURN;DECLARE @NombreNVARCHAR(50)DECLARE @PuntosINTSELECT @Nombre=Nombre, @Puntos=PuntosFROMINSERTEDIFLEN(@Nombre)>15BEGINPRINT'El nombre es muy largo. Máximo 15 carácteres.'ROLLBACKRETURNENDIF @Puntos>100BEGINPRINT'El puntaje máximo es de 100'ROLLBACKRETURNENDPRINT'Se realizó el Update'END
Deben tener en cuenta que en una tabla con Triggers no podemos usar el MERGE.
La información del nombre debe tener al menos 3 caracteres.
SETANSI_NULLSONGOSETQUOTED_IDENTIFIERONGOALTERTRIGGER[dbo].[t_update]ON[dbo].[UsuarioTarget]AFTERUPDATEASBEGINIF(ROWCOUNT_BIG()=0)RETURN;DECLARE @codigo int
SELECT @codigo =len(nombre)FROM inserted
IF @codigo <3BEGINPrint'NO se realizó un update. no es un nombre valido'ROLLBACK;RETURN;END--SELECTCodigo,Nombre,Puntosfrom inserted
Print'Se realizó un update'ENDGO
CREATE OR ALTER TRIGGER t_update
ON UsuarioTarget
AFTER UPDATE
AS
BEGIN
IF(ROWCOUNT_BIG() = 0)
RETURN;
DECLARE @codigo int
SELECT @codigo = codigo from inserted
if @codigo >8BEGIN print 'no se realizo el update'ROLLBACK;RETURN;END--SELECTCodigo,Nombre,Puntos--FROMINSERTEDPrint'Se realizo el UPDATE'END
Hola, no me quedo claro esta condición
IF (ROWCOUNT_BIG() = 0)
RETURN;
Cuando aplicaría esta condición si como tal el número de registros a ajustar es mínimo 1.
Por ejemplo, en el trigger esta la condición AFTER INSERT/DELETE/UPDATE espera un valor o tiene un valor en curso. ¿Cuando un trigger recibe esa condición con ROW en 0?
Gracias
Cómo se puede evitar que se produzca el mensaje “the transaction ended in the trigger. The batch has been aborted” ?
Ese error se muestra cuando hay un error en el proceso del trigger. Debes arreglarlo o minimo capturar el error con try catch.
<code>BEGINTRY....aqui tu código
ENDTRYBEGINCATCHDECLARE @ErrorMsgVARCHAR(MAX), @ErrorNumberINT, @ErrorProc sysname, @ErrorLineINTSELECT @ErrorMsg=ERROR_MESSAGE(), @ErrorNumber=ERROR_NUMBER(), @ErrorProc=ERROR_PROCEDURE(), @ErrorLine=ERROR_LINE();--Aqui puedes tener un control de errores en una tabla log
--INSERTINTOErrorLog(ErrorMsg,ErrorNumber,ErrorProc,ErrorLine)--VALUES(@ErrorMsg, @ErrorNumber, @ErrorProc, @ErrorLine)ENDCATCH
Puedes seguirme en mis redes sociales donde publico regularmente sobre SQL y otros lenguajes. Twitter https://twitter.com/royrojasdev
El comando ROLLBACK en SQL se utiliza para deshacer una transacción que no ha sido confirmada. Cuando se ejecuta, devuelve la base de datos al estado en que se encontraba antes de que comenzara la transacción, eliminando todos los cambios realizados hasta ese momento. Esto es útil para mantener la integridad de los datos en caso de errores o inconsistencias durante la inserción o actualización de datos, como se mencionó en el contexto sobre triggers.
Agrego validación de los puntos
ALTER Trigger [dbo].[t_update]
on [dbo].[UsuarioTarget]
After Update
as
Begin
If (ROWCOUNT_BIG() = 0)
Return;
Declare @Puntos int
Select @Puntos = Puntos from inserted
If @Puntos = 0
Begin
Print 'No se realizó el Update'
Rollback;
Return;
End
--Select Codigo,Nombre,Puntos from INSERTED
Print 'Se realizó el Update'
End
ALTER TRIGGER t_update
ON UsuarioTarget
AFTER UPDATE
AS
BEGIN
IF(ROWCOUNT_BIG() = 0)
RETURN;
DECLARE @tamano int
select @tamano=LEN(Nombre) from INSERTED
if @tamano < 5
BEGIN
Print 'No se modifico'
ROLLBACK;
RETURN;
END
Print 'Se ralizó el update'
END
Este es mi aporte, espero les ayude
--VALIDAR SI EL NOMBRE YA EXISTE Y QUE NO PASE EL CODIGO DE 10
CREATE OR ALTER TRIGGER T_INSERT_NAME
ON UsuarioTarget INSTEAD OF INSERT
AS
BEGIN
DECLARE @Nombre VARCHAR(50)
DECLARE @Codigo INTEGER
DECLARE @Puntos INTEGER
SELECT @Codigo = Codigo FROM INSERTED;
SELECT @Nombre = Nombre FROM INSERTED;
SELECT @Puntos = Puntos FROM INSERTED;
IF EXISTS(SELECT Nombre FROM UsuarioTarget WHERE Nombre = @Nombre)
BEGIN
PRINT('THIS RECORD IS ALREADY EXISTS ' + @Nombre)
ROLLBACK
END;
ELSE IF @Codigo > 10
BEGIN
PRINT('THE CODE MUST BE LESS THAN 10 ' + CAST(@Codigo AS NVARCHAR));
ROLLBACK
END
ELSE
BEGIN
INSERT INTO UsuarioTarget(Codigo, Nombre, Puntos) VALUES(@Codigo,@Nombre,@Puntos)
PRINT('THIS RECORD HAS BEEN INSERT INTO UsuarioTarget');
END;
END
GO
CREATEORALTERTRIGGER t_update
ON usuario_target
after UPDATEASBEGINIF(rowcount_big()=0)RETURN;DECLARE @nombre int
DECLARE @punto int
SELECT @nombre = nombre,@punto =[punto]FROM inserted
IF @punto >200BEGINPRINT'no cargo por puntaje mayor a 200 en el update'ROLLBACK;RETURN;ENDSELECT codigo, nombre, punto
FROM inserted
PRINT'se hizo el update'ENDGO
USE[PlatziSQL];GOCREATEORALTERTRIGGER[t_update_codition]ON[dbo].[UsuarioTarget]AFTERUPDATEASBEGINIF(ROWCOUNT_BIG()=0)RETURN;DECLARE @nombre VARCHAR(100)SELECT @nombre =[nombre]FROMINSERTEDIF @nombre ='Chachito'BEGINPRINT'No se realizo el insert'ROLLBACK;RETURN;END--SELECT[Codigo]--,[Nombre]--,[Puntos]--FROMINSERTED--PRINT'SE REALIZO EL UPDATE'END;UPDATE[dbo].[UsuarioTarget]SET[Nombre]='Chachito Feliz'WHERE[Codigo]=1;
Reto:
--RETO:Crear una condición que no permita hacer un UPDATE/*En este caso no se realizará el UPDATE si se quiere cambiar
el nombre a Carlos Ramirez*/CREATEORALTERTRIGGER t_update
ONUsuarioTargetAFTERUPDATEASBEGINIF(ROWCOUNT_BIG()=0)RETURN;DECLARE @nombre varchar(100)SELECT @nombre =NombreFROM inserted
IF(@nombre ='Carlos Ramirez')BEGINPRINT'No se realizó el UPDATE'ROLLBACK;RETURN;END/*SELECT Codigo,Nombre, Puntos
FROM INSERTED --Se usa el INSERTED*/PRINT'Se realizó el Update'END
La modificación del trigger update.
ALTERTRIGGER[dbo].[t_update]ON[dbo].[UsuarioTarget]AFTERUPDATEASBEGINIF(ROWCOUNT_BIG()=0)RETURN;DECLARE @puntos int
SELECT @puntos = puntos FROM inserted
IF @puntos >=20BEGINPrint'No se realizó un update - Puntos debe ser menor igual a 20'ROLLBACK;RETURN;END--SELECTCodigo,Nombre,Puntosfrom inserted
Print'Se realizó un update'END
create or alter trigger t_update
on dbo.UsuarioSource
after update
as
begin
if(ROWCOUNT_BIG()=0)return;declare @nombre varchar(200)select @nombre =Nombrefrom inserted
if(len(@nombre)=0)begin
print 'Se requiere un Nombre' rollback;return;
end
print 'Nombre actualizado'