Disparo do disparador apesar de nenhuma linha ser afetada

10

Essa é uma pergunta mais geral, mas a motivação para essa pergunta foi um problema que eu enfrentei ao usar o SQL Server.

Eu tenho esse gatilho anexado a um evento Insert em uma tabela que contém alguma lógica que, como efeito colateral, geraria erro se nenhuma linha fosse inserida. Após uma investigação mais aprofundada, descobri que o gatilho estava disparando, apesar de nenhuma linha ser inserida.

A linguagem usada no Microsoft Docs on DML Triggers parece contradizer esse comportamento:

Os gatilhos DML são um tipo especial de procedimento armazenado que entra em vigor automaticamente quando ocorre um evento DML que afeta a tabela ou exibição definida no gatilho.

Esse é um comportamento padrão nos DBMSs? Existe um motivo específico para disparar um gatilho quando nenhuma linha é afetada?

Luís Gabriel de Andrade
fonte

Respostas:

24

Para ações DML, existem gatilhos baseados em linhas e em instruções.

  • A linha dispara quando (antes, depois ou em vez de) cada linha é afetada (inserida / atualizada / excluída). Portanto, eles serão disparados 100 vezes se 100 linhas forem afetadas e nada se 0 linhas forem afetadas.

  • A instrução dispara quando uma INSERT / UPDATE / DELETEinstrução é executada. Não importa se nenhuma linha é afetada. O nível da instrução dispara de qualquer maneira e apenas uma vez para uma instrução (seja 0, 100 ou um bilhão de linhas afetadas).

Alguns DBMS possuem apenas gatilhos no nível de linha (MySQL).

Outros (como o SQL Server *, que é o seu DBMS), têm apenas gatilhos no nível da instrução.

Alguns outros (DB2, Oracle, Postgres) possuem dois tipos de gatilhos.


* Estado dos CREATE TRIGGERdocumentos do SQL Server :

Os gatilhos DML são executados quando um usuário tenta modificar dados por meio de um evento da linguagem de manipulação de dados (DML). Eventos DML são INSERT, UPDATEou DELETEdeclarações sobre uma tabela ou exibição. Esses gatilhos são acionados quando qualquer evento válido é acionado, independentemente de alguma linha da tabela ser afetada ou não.

ypercubeᵀᴹ
fonte