¡Hola, chicos!
Una necesidad común de los DBA's es evitar accesos y operaciones inadecuadas o erróneas, que incluso el propio DBA puede terminar siendo descuidado y realizando una operación equivocada. Mi idea en esta publicación es demostrar algunas soluciones utilizando disparadores.
Creación de la mesa de prueba.
IF (OBJECT_ID('dbo.Teste_Trigger') IS NOT NULL) DROP TABLE dbo.Teste_Trigger
CREATE TABLE dbo.Teste_Trigger (
Id INT IDENTITY(1, 1) NOT NULL,
Nome VARCHAR(100) NOT NULL
)
INSERT INTO dbo.Teste_Trigger
VALUES ( 'Dirceu Resende' ), ( 'Teste' ), ( 'Teste 2')
SELECT * FROM dbo.Teste_Trigger
Evite comandos DML en la tabla (tabla de solo lectura)
Si no desea permitir operaciones DML (INSERT, UPDATE y DELETE) en su tabla, transformándola así en una tabla de solo lectura, simplemente cree el siguiente activador:
IF (OBJECT_ID('[dbo].[trgBloqueia_Dml_Teste]') IS NOT NULL) DROP TRIGGER [dbo].[trgBloqueia_Dml_Teste]
GO
CREATE TRIGGER [dbo].[trgBloqueia_Dml_Teste] ON [dbo].[Teste_Trigger]
FOR INSERT, UPDATE, DELETE AS
BEGIN
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)
BEGIN
ROLLBACK TRANSACTION;
RAISERROR ('Operações de INSERT não são permitidas na tabela "Teste_Trigger"', 15, 1);
RETURN;
END
IF EXISTS (SELECT * FROM deleted) AND NOT EXISTS (SELECT * FROM inserted)
BEGIN
ROLLBACK TRANSACTION;
RAISERROR ('Operações de DELETE não são permitidas na tabela "Teste_Trigger"', 15, 1);
RETURN;
END
IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
ROLLBACK TRANSACTION;
RAISERROR ('Operações de UPDATE não são permitidas na tabela "Teste_Trigger"', 15, 1);
RETURN;
END
END;
GO
Evite BORRAR o ACTUALIZAR sin dónde
Un error muy común en la vida diaria de un DBA es cuando un analista o desarrollador envía un script ACTUALIZAR o ELIMINAR para que el DBA lo ejecute y se olvida de poner la cláusula WHERE. Imagine el daño que esto podría causar a la base de datos. Una forma de evitar esto es mediante el uso de complementos y complementos, como Redgate SQL Prompt y ApexSQL Complete, que alertan al DBA cuando esto ocurrirá.
Otra forma (y más confiable) es crear un desencadenante para esto:
IF (OBJECT_ID('[dbo].[trgEvita_Acidentes]') IS NOT NULL) DROP TRIGGER [dbo].[trgEvita_Acidentes]
GO
CREATE TRIGGER [dbo].[trgEvita_Acidentes] ON [dbo].[Teste_Trigger]
FOR UPDATE, DELETE AS
BEGIN
DECLARE
@Linhas_Alteradas INT = @@ROWCOUNT,
@Linhas_Tabela INT = (SELECT SUM(row_count) FROM sys.dm_db_partition_stats WHERE [object_id] = OBJECT_ID('Teste_Trigger') AND (index_id <= 1))
IF (@Linhas_Alteradas >= @Linhas_Tabela)
BEGIN
ROLLBACK TRANSACTION;
RAISERROR ('Operações de DELETE e/ou UPDATE sem cláusula WHERE não são permitidas na tabela "Teste_Trigger"', 15, 1);
RETURN;
END
END;
GO
Solo permita 1 registro modificado a la vez en la tabla
Otra necesidad que puede ocurrir en algunas tablas es requerir que solo se cambie 1 registro en la tabla a la vez mediante una operación DELETE/UPDATE:
IF (OBJECT_ID('[dbo].[trgEvita_Dml_Muitos_Registros]') IS NOT NULL) DROP TRIGGER [dbo].[trgEvita_Dml_Muitos_Registros]
GO
CREATE TRIGGER [dbo].[trgEvita_Dml_Muitos_Registros] ON [dbo].[Teste_Trigger]
FOR UPDATE, DELETE AS
BEGIN
DECLARE
@Linhas_Alteradas INT = @@ROWCOUNT,
@MsgErro VARCHAR(MAX)
IF (@Linhas_Alteradas > 1)
BEGIN
ROLLBACK TRANSACTION;
SET @MsgErro = 'Operações de DELETE e/ou UPDATE só podem atualizar 1 registro por vez na tabela "Teste_Trigger", e você tentou atualizar ' + CAST(@Linhas_Alteradas AS VARCHAR(50))
RAISERROR (@MsgErro, 15, 1);
RETURN;
END
END;
GO
Al intentar actualizar más de un registro, el disparador bloqueará la operación:

Habiendo presentado las soluciones anteriores, espero haber respondido sus preguntas sobre la restricción DML en SQL Server mediante activadores. Esta es una característica muy antigua del DBMS, odiada por algunos, amada por otros y que es útil cuando se aplica bien y su uso está justificado.
Espero que te haya gustado este post y si tienes alguna duda déjala aquí en los comentarios.
¡Un abrazo y nos vemos en el próximo post!




Comentários (0)
Carregando comentários…