Suponha que eu queira excluir um usuário chamado 'abc cba' do banco de dados. Então eu executo a seguinte consulta:
DELETE FROM table WHERE fname = 'abc' AND last name = 'cba'; commit;
Agora, pode haver mais usuários com esse nome que eu não conheço. A escolha óbvia seria executar a instrução select de antemão e verificar se estou excluindo o que realmente queria excluir, mas ainda sou humano e posso esquecer isso e acabar procurando backups para recuperar dados perdidos.
Minha pergunta é: existe uma maneira de impor certas regras às instruções após as quais elas não executarão a instrução DML (por exemplo, não execute a exclusão se o número de linhas excluídas exceder determinado limite)?
Só posso falar pelo SQL Server, mas a única maneira de fazer isso é por meio de um gatilho DML (tanto quanto sei). Veja abaixo como exemplo:
Porém, existem alguns problemas com essa abordagem e não acredito que seja um bom design. Em primeiro lugar, você tem requisitos codificados dentro do gatilho (se você está fazendo uma contagem de linhas definida ou uma porcentagem de linhas... ainda é codificado). Um aplicativo teria que ser projetado de acordo para garantir a repetição com uma lógica diferente.
O que realmente importa é ter um banco de dados projetado corretamente e instruções DML construídas corretamente para garantir que os dados que estão sendo modificados sejam os dados que você deseja, em vez de ter que verificar uma contagem de linhas das linhas excluídas.
Na minha opinião, você deve gastar tempo de design para descobrir como redesenhar para não precisar dessa verificação.
A imposição de tais regras no nível do banco de dados pode ser muito cara em termos de recursos, então não acho que exista uma maneira padrão que funcione em todos os lugares.
Não posso sugerir nada melhor do que gerar um erro dentro do corpo da
BEFORE DELETE
trigger (ouAFTER DELETE
, masBEFORE
trigger parece ser mais apropriado nesse caso). Infelizmente, é bastante dependente do RDMS. Por exemplo, no Oracle, se você deseja acessar a mesma tabela dentro do gatilho, você precisa usar o gatilho de nível de instrução; SQLServer chama tais gatilhosINSTEAD OF
, nãoBEFORE
.