SQL Server: Trigger para Bloquear Alterações ou Exclusões em Registros de Endereços 🔍

⚙ Visão Geral

Esta trigger (“gatilho”) no SQL Server foi criada para evitar que registros de endereços sejam alterados ou excluídos indevidamente, seguindo regras de negócio específicas.

A trigger é aplicada à tabela PessoaEndereco e intercepta as operações DELETE e UPDATE. Ela pertence ao banco de dados D2D_endereco e está definida como [dbo].[PessoaEnderecoclb_i_u].

⚖️ Funcionalidade

Essa trigger é do tipo INSTEAD OF DELETE, UPDATE, o que significa que substitui diretamente essas operações na tabela PessoaEndereco. O código segue a seguinte lógica:

  1. Declaração de Variáveis:

    • @Action: Determina se a operação é uma inserção, atualização ou exclusão.

    • @TipoPessoa: Armazena o tipo da pessoa associada ao endereço.

    • @Count: Conta o número de registros ativos com o mesmo tipo de endereço.

    • @PE_TipoEnderecoCod: Define o tipo de endereço de acordo com a categoria da pessoa (PJ, PF, PE).

    • @NomePessoa: Registra o nome da pessoa associada ao endereço.

  2. Obtenção dos Valores Originais e Novos:

    • A trigger utiliza as tabelas temporárias deleted e inserted para recuperar os valores antes e depois da operação.

  3. Regras de Bloqueio:

    • Se houver apenas um registro ativo do tipo de endereço PJ ou PF, ele não pode ser excluído ou alterado.

    • A trigger verifica o tipo da pessoa (PF, PJ ou PE) antes de aplicar a regra.

⚠️ Nota Importante

✅ Algumas partes do código estão comentadas (--) e podem precisar ser ativadas dependendo das necessidades do ambiente.

Essa trigger foi projetada para garantir integridade e consistência nas informações de endereço. Antes de implementá-la, certifique-se de que as regras de negócio aplicadas são adequadas ao seu cenário.


💻 Código SQL da Trigger

USE [D2D_endereco]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Autor: Cleber Machado
-- Data de criação: 07/01/2016
-- Descrição: Bloqueia a alteração ou exclusão de registros de endereços, conforme regras:
-- 1. Se PJ, deve existir ao menos um endereço ativo do tipo 1 (não pode ser excluído ou alterado).
-- 2. Se PF, deve existir ao menos um endereço ativo do tipo 2 (não pode ser excluído ou alterado).
-- =============================================
CREATE TRIGGER [dbo].[PessoaEnderecoclb_i_u]
ON [dbo].[PessoaEndereco]
INSTEAD OF DELETE, UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @Msg_Retorno VARCHAR(MAX),
            @Pessoa_Codigo INT,
            @PessoaEndereco_TipoEnderecoCod SMALLINT,
            @PessoaEndereco_Status BIT,
            @TipoPessoa CHAR(3),
            @PE_TipoEnderecoCod CHAR(2),
            @Count INT,
            @Action CHAR(1),
            @NomePessoa VARCHAR(100);

    -- Obtém os dados do registro antes da operação
    SELECT @Pessoa_Codigo = Pessoa_Codigo,
           @PessoaEndereco_TipoEnderecoCod = PessoaEndereco_TipoEnderecoCod,
           @PessoaEndereco_Status = PessoaEndereco_Status
    FROM deleted;
    
    -- Verifica o tipo da pessoa
    SELECT @TipoPessoa = p.Pessoa_TipoPessoa
    FROM [dbo].[Pessoa] p
    WHERE p.Pessoa_Codigo = @Pessoa_Codigo;

    -- Define a categoria de endereço conforme o tipo de pessoa
    IF @TipoPessoa IN ('F') SET @PE_TipoEnderecoCod = 'PF';
    ELSE IF @TipoPessoa IN ('E') SET @PE_TipoEnderecoCod = 'PE';
    ELSE SET @PE_TipoEnderecoCod = 'PJ';
    
    -- Conta a quantidade de endereços ativos para a pessoa
    SELECT @Count = COUNT(*)
    FROM dbo.PessoaEndereco pe
    WHERE pe.PessoaEndereco_Status = 1
          AND pe.Pessoa_Codigo = @Pessoa_Codigo
          AND pe.PessoaEndereco_TipoEnderecoCod = @PessoaEndereco_TipoEnderecoCod;
    
    -- Identifica a ação realizada (U = Update, D = Delete)
    SET @Action = (CASE
                      WHEN EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted) THEN 'U'
                      WHEN EXISTS(SELECT * FROM inserted) THEN 'I'
                      WHEN EXISTS(SELECT * FROM deleted) THEN 'D'
                      ELSE NULL
                   END);
    
    -- Obtém o nome da pessoa
    SELECT @NomePessoa = p.Pessoa_NomeFantasia
    FROM pessoa p
    WHERE p.Pessoa_Codigo = @Pessoa_Codigo;
    
    -- Regras de Bloqueio
    IF (@Count = 1 AND @Action = 'D' AND @PE_TipoEnderecoCod IN ('PJ', 'PF'))
    BEGIN
        RAISERROR ('⛔️ Exclusão não permitida: %s possui apenas um endereço ativo.', 16, 1, @NomePessoa);
        ROLLBACK TRAN;
        RETURN;
    END;
    
    IF (@Count = 1 AND @Action = 'U' AND @PE_TipoEnderecoCod IN ('PJ', 'PF') AND @PessoaEndereco_Status = 0)
    BEGIN
        RAISERROR ('⛔️ Alteração não permitida: %s possui apenas um endereço ativo.', 16, 1, @NomePessoa);
        ROLLBACK TRAN;
        RETURN;
    END;
END;
GO

🛠️ Conclusão

Essa trigger desempenha um papel essencial no controle de integridade dos registros de endereços. Ao impedir alterações indevidas, ela preserva a consistência dos dados no banco de dados.

Antes de ativar a trigger, revise suas regras de negócio e realize testes para garantir que ela funcione corretamente no ambiente desejado.

Se precisar de ajustes ou explicações adicionais, estou à disposição! ✨

Data de Publicação: 26-10-2023

Categoria: SQL Server