Dicas para evitar "Update sem Where" | Café ++
Publicado: 01/03/2018 - Rômulo Soares

Dicas para evitar "Update sem Where"

3 formas de evitar acidentes com Updates

Quem nunca fez um “update sem where”, que atire a primeira pedra.
Esse erro é bastante comum para iniciantes, mas os veteranos no assunto não estão livres de tal “deslize”. Momentos de estresse e pressão acabam colaborando com esse “F5” indesejado.
Confira 3 dicas/práticas que, apesar de simples, podem ajudar e muito na prevenção contra alterações indesejadas em nossas queridas tabelas.

Dica 1

Faça primeiro um select com as condições desejadas:

   select top (1) nome from usuarios
where
    nome = 'Diogo Barizon'

Depois de validar se as condições foram satisfatórias, substitua a parte do select pelo update:
   update usuarios
set idade = 21
where
    nome = 'Diogo Barizon'


Dica 2

Escreva o where logo após o update, pulando a etapa do set:

   update usuarios
where
    nome = 'Diogo Barizon'

Após validar as condições, insira o comando set:
   update usuarios
set idade = 21
where
    nome = 'Diogo Barizon'


Dica 3

Crie um TRIGGER que bloqueie “updates sem where “ não intencionais.
Esse TRIGGER inibe updates/deletes cujo número de linhas a serem afetadas é equivalente ao total de linhas da tabela.
Sabemos que em alguns momentos é necessário fazer update de dados em todas as linhas, então não se preocupe, pois mostraremos também como desabilitar ou excluir o bloqueio.

Comando:
   CREATE TRIGGER no_update_sem_where --Nome do TRIGGER
ON minha_tabela --Tabela que será "protegida" pelo TRIGGER
FOR UPDATE AS --Tipo de comando que acionará a TRIGGER (INSERT , DELETE ou UPDATE)
BEGIN
     DECLARE @Count int --Declarando a variável que guardará a quantidade de linhas
     SET @Count = @@ROWCOUNT; --Setando o valor da variável com a quantidade de linhas afetadas
          
     IF @Count >= (SELECT SUM(row_count) --Se o valor da variavel for igual ou maior que a quantidade de linhas da tabela, executa o comando....
         FROM sys.dm_db_partition_stats --A DMV "dm_db_partition_stats" trás informações sobre numero de linhas das tabelas
         WHERE
            OBJECT_ID = OBJECT_ID('minha_tabela' ) --Trazendo o id da tabela para localizá-la na "dm_db_partition_stats"
            and index_id = 0) --id do indice na "dm_db_partition_stats' ( 0 = Heap | 1 = Índice clusterizado | >1 = Índice não clusterizado )
     BEGIN
         RAISERROR('UPDATE sem where? Ou tu toma jeito, ou te retiro o acesso interno!',16,1) --Mensagem que será exibida ao infrator. Hehe 
         ROLLBACK TRANSACTION --Finaliza a transação e descarta tudo que foi feito, ou seja, elimina o maldito update sem where
         RETURN; --Saindo...
     END
END
GO
    

Ao tentar realizar o update sem where, será exibida a seguinte mensagem:



Para desabilitar o TRIGGER:
   DISABLE TRIGGER no_update_sem_where ON minha_tabela; 
    
Para reabilitar o TRIGGER:
   ENABLE TRIGGER no_update_sem_where ON minha_tabela;
    
Para excluir o TRIGGER:
   DROP TRIGGER no_update_sem_where;
    

Vale reforçar que absolutamente nada substutui o bom e velho backup do banco de dados. Quer ter paz em sua consciência? Faça backup de seus dados.

Enfim, que o “update sem where” seja apenas parte de nossas piadas, não de nossos pesadelos.

Rômulo Soares
Analista Programador no setor de contact center em Belo Horizonte