Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se a:SQL Server
Banco de Dados SQL do Azure
Instância Gerenciada de SQL do Azure
Cria um gatilho DML, DDL ou de logon. Um gatilho é um tipo especial de procedimento armazenado executado automaticamente quando um evento ocorre no servidor de banco de dados. Os gatilhos DML são executados quando um usuário tenta modificar dados por meio de um evento DML (linguagem de manipulação de dados). Eventos DML são INSERT
, UPDATE
ou DELETE
instruções em uma tabela ou exibição. Esses gatilhos são disparados quando qualquer evento válido é acionado, sejam as linhas da tabela afetadas ou não. Para obter mais informações, consulte DML Triggers.
Os gatilhos DDL são executados em resposta a vários eventos de DDL (linguagem de definição de dados). Esses eventos correspondem principalmente a Transact-SQL CREATE
, ALTER
instruções e DROP
determinados procedimentos armazenados do sistema que executam operações semelhantes a DDL.
O logon dispara o fogo em resposta ao LOGON
evento gerado quando a sessão de um usuário está sendo estabelecida. Crie gatilhos diretamente de instruções Transact-SQL ou de métodos de assemblies criados no CLR (Common Language Runtime) do Microsoft .NET Framework e carregados em uma instância do SQL Server. O SQL Server permite criar vários gatilhos para qualquer instrução específica.
Importante
Um código mal-intencionado dentro de gatilhos pode ser executado sob privilégios escalonados. Para obter mais informações sobre como atenuar essa ameaça, consulte Gerenciar a segurança do gatilho.
Observação
A integração do CLR do .NET Framework ao SQL Server é discutida neste artigo. A integração do CLR não se aplica ao Banco de Dados SQL do Azure.
Convenções de sintaxe de Transact-SQL
Sintaxe
Sintaxe do SQL Server
Disparar em uma instrução ou DELETE
UPDATE
uma instrução INSERT
para uma tabela ou exibição (gatilho DML):
CREATE [ OR ALTER ] TRIGGER [ schema_name . ] trigger_name
ON { table | view }
[ WITH <dml_trigger_option> [ , ...n ] ]
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
[ WITH APPEND ]
[ NOT FOR REPLICATION ]
AS { sql_statement [ ; ] [ , ...n ] | EXTERNAL NAME <method_specifier [ ; ] > }
<dml_trigger_option> ::=
[ ENCRYPTION ]
[ EXECUTE AS Clause ]
<method_specifier> ::=
assembly_name.class_name.method_name
Disparar em uma instrução ou DELETE
instrução INSERT
UPDATE
para uma tabela (gatilho DML em tabelas com otimização de memória):
CREATE [ OR ALTER ] TRIGGER [ schema_name . ] trigger_name
ON { table }
[ WITH <dml_trigger_option> [ , ...n ] ]
{ FOR | AFTER }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
AS { sql_statement [ ; ] [ , ...n ] }
<dml_trigger_option> ::=
[ NATIVE_COMPILATION ]
[ SCHEMABINDING ]
[ EXECUTE AS Clause ]
Gatilho em uma CREATE
instrução , , ALTER
, DROP
, GRANT
, DENY
REVOKE
ou UPDATE
instrução (gatilho DDL):
CREATE [ OR ALTER ] TRIGGER trigger_name
ON { ALL SERVER | DATABASE }
[ WITH <ddl_trigger_option> [ , ...n ] ]
{ FOR | AFTER } { event_type | event_group } [ , ...n ]
AS { sql_statement [ ; ] [ , ...n ] | EXTERNAL NAME < method specifier > [ ; ] }
<ddl_trigger_option> ::=
[ ENCRYPTION ]
[ EXECUTE AS Clause ]
Gatilho em um LOGON
evento (gatilho de logon):
CREATE [ OR ALTER ] TRIGGER trigger_name
ON ALL SERVER
[ WITH <logon_trigger_option> [ , ...n ] ]
{ FOR | AFTER } LOGON
AS { sql_statement [ ; ] [ , ...n ] | EXTERNAL NAME < method specifier > [ ; ] }
<logon_trigger_option> ::=
[ ENCRYPTION ]
[ EXECUTE AS Clause ]
Sintaxe do Banco de Dados SQL do Azure
Disparar em uma instrução ou DELETE
UPDATE
uma instrução INSERT
para uma tabela ou exibição (gatilho DML):
CREATE [ OR ALTER ] TRIGGER [ schema_name . ] trigger_name
ON { table | view }
[ WITH <dml_trigger_option> [ , ...n ] ]
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
AS { sql_statement [ ; ] [ , ...n ] [ ; ] > }
<dml_trigger_option> ::=
[ EXECUTE AS Clause ]
Gatilho em uma CREATE
instrução , , ALTER
, DROP
, GRANT
, DENY
REVOKE
ou UPDATE STATISTICS
instrução (gatilho DDL):
CREATE [ OR ALTER ] TRIGGER trigger_name
ON { DATABASE }
[ WITH <ddl_trigger_option> [ , ...n ] ]
{ FOR | AFTER } { event_type | event_group } [ , ...n ]
AS { sql_statement [ ; ] [ , ...n ] [ ; ] }
<ddl_trigger_option> ::=
[ EXECUTE AS Clause ]
Argumentos
OU ALTER
Aplica-se a: SQL Server 2016 (13.x) SP1 e versões posteriores e Banco de Dados SQL do Azure
Altera condicionalmente o gatilho somente se ele já existir.
schema_name
O nome do esquema ao qual o gatilho DML pertence. Os gatilhos DML são definidos no escopo do esquema da tabela ou na exibição em que são criados. schema_name não pode ser especificado para gatilhos DDL ou de logon.
trigger_name
O nome do gatilho. Um trigger_name deve seguir as regras para identificadores, exceto que trigger_name não pode começar com #
ou ##
.
mesa | vista
A tabela ou a exibição em que o gatilho DML é executado. Essa tabela ou exibição às vezes é referenciada como tabela de gatilho ou exibição de gatilho. Especificar o nome totalmente qualificado da tabela ou da exibição é opcional. Você só pode referenciar uma exibição por um INSTEAD OF
gatilho. Não é possível definir gatilhos DML em tabelas temporárias locais ou globais.
BASE DE DADOS
Aplica o escopo de um gatilho DDL ao banco de dados atual. Se especificado, o gatilho será disparado sempre que event_type ou event_group ocorrer no banco de dados atual.
TODOS OS SERVIDORES
Aplica o escopo de um gatilho DDL ou de logon ao servidor atual. Se for especificado, o gatilho será disparado sempre que event_type ou event_group ocorrer em qualquer local no servidor atual.
COM CRIPTOGRAFIA
Obscurece o texto da CREATE TRIGGER
instrução. O uso WITH ENCRYPTION
impede que o gatilho seja publicado como parte da replicação do SQL Server.
WITH ENCRYPTION
não pode ser especificado para gatilhos CLR.
EXECUTAR COMO
Especifica o contexto de segurança no qual o gatilho é executado. Permite controlar a conta de usuário que a instância do SQL Server usa para validar permissões em quaisquer objetos do banco de dados referidos pelo gatilho.
Essa opção é necessária para os gatilhos em tabelas com otimização de memória.
Para obter mais informações, consulte a Cláusula EXECUTE AS.
COMPILAÇÃO_NATIVA
Indica que o gatilho foi compilado nativamente.
Essa opção é necessária para os gatilhos em tabelas com otimização de memória.
SCHEMABINDING
Garante que as tabelas referenciadas por um gatilho não possam ser removidas nem alteradas.
Essa opção é obrigatória para gatilhos em tabelas com otimização de memória e não é compatível com gatilhos em tabelas tradicionais.
FOR | DEPOIS
FOR
ou AFTER
especifica que o gatilho DML é acionado somente quando todas as operações especificadas na instrução SQL de gatilho foram iniciadas com êxito. Todas as verificações de restrição e ações referenciais em cascata também devem ter êxito para que esse gatilho seja disparado.
Você não pode definir AFTER
gatilhos em exibições.
EM VEZ DE
Especifica que o gatilho DML será iniciado em vez da instrução SQL de gatilho, substituindo as ações das instruções de gatilho. Você não pode especificar INSTEAD OF
para gatilhos de DDL ou logon.
No máximo, você pode definir um INSTEAD OF
gatilho por INSERT
, UPDATE
ou DELETE
instrução em uma tabela ou exibição. Você também pode definir exibições em exibições em que cada exibição tem seu próprio INSTEAD OF
gatilho.
Você não pode definir INSTEAD OF
gatilhos em exibições atualizáveis que usam WITH CHECK OPTION
. Isso resulta em um erro quando um INSTEAD OF
gatilho é adicionado a uma exibição atualizável WITH CHECK OPTION
especificada. Remova essa opção usando ALTER VIEW
antes de definir o INSTEAD OF
gatilho.
{ [ DELETE ] [ , ] [ INSERT ] [ , ] [ UPDATE ] }
Especifica as instruções de modificação de dados que, quando tentadas nessa tabela ou exibição, ativam o gatilho DML. Especifique pelo menos uma opção. Use qualquer combinação dessas opções em qualquer ordem na definição do gatilho.
Para INSTEAD OF
gatilhos, você não pode usar a opção DELETE
em tabelas que têm uma relação referencial, especificando uma ação ON DELETE
em cascata. Da mesma forma, a opção UPDATE
não é permitida em tabelas que têm uma relação referencial, especificando uma ação ON UPDATE
em cascata.
COM ACRÉSCIMO
Aplica-se a: SQL Server (SQL Server 2008 (10.0.x) ao SQL Server 2008 R2 (10.50.x).
Especifica que um gatilho adicional de um tipo existente deve ser adicionado.
WITH APPEND
não pode ser usado com INSTEAD OF
gatilhos ou se um AFTER
gatilho é explicitamente declarado. Para compatibilidade com versões anteriores, use WITH APPEND
somente quando FOR
for especificado, sem INSTEAD OF
ou AFTER
. Você não pode especificar WITH APPEND
se está usando EXTERNAL NAME
(ou seja, se o gatilho for um gatilho CLR).
event_type
O nome de um evento da linguagem Transact-SQL que, após a inicialização, faz com que um gatilho DDL seja acionado. Os eventos válidos para gatilhos DDL são listados em Eventos DDL.
event_group
O nome de um agrupamento predefinido de eventos da linguagem Transact-SQL. O gatilho DDL é disparado após a inicialização de qualquer evento da linguagem Transact-SQL que pertence a event_group. Os grupos de eventos válidos para gatilhos DDL são listados em Grupos de eventos DDL.
Após a conclusão da CREATE TRIGGER
execução, event_group também atua como uma macro adicionando os tipos de evento que ela aborda à exibição do sys.trigger_events
catálogo.
NÃO PARA REPLICAÇÃO
Indica que o gatilho não deve ser executado quando um agente de replicação modifica a tabela envolvida no gatilho.
sql_statement
As condições e as ações do gatilho. As condições de gatilho especificam critérios adicionais que determinam se os eventos DML, DDL ou de logon fazem com que as ações de gatilho sejam executadas.
As ações de gatilho especificadas nas instruções Transact-SQL entram em vigor quando a operação é tentada.
Os gatilhos podem incluir qualquer número e tipo de instruções Transact-SQL, com exceções. Para obter mais informações, consulte Comentários. Um gatilho foi projetado para verificar ou alterar dados com base em uma instrução de definição ou modificação de dados. O gatilho não deve retornar dados ao usuário. As instruções Transact-SQL em um gatilho frequentemente incluem linguagem de controle de fluxo.
Gatilhos de DML usam as tabelas (conceituais) lógicas inseridas e excluídas. Eles são estruturalmente semelhantes à tabela em que o gatilho é definido, ou seja, a tabela em que a ação do usuário é tentada. As tabelas excluídas e inseridas contêm os valores antigos ou novos valores das linhas que podem ser alteradas pela ação do usuário. Por exemplo, para recuperar todos os valores na tabela deleted
, use:
SELECT * FROM deleted;
Para obter mais informações, consulte Usar as tabelas inseridas e excluídas.
Gatilhos de DDL e logon capturam informações sobre o evento de gatilho usando a função EVENTDATA . Para obter mais informações, veja Usar a função EVENTDATA.
O SQL Server permite a atualização de colunas de texto, ntext ou imagem por meio do INSTEAD OF
gatilho em tabelas ou exibições.
Importante
Os tipos de dados ntext, text e image serão removidos em uma versão futura do Microsoft SQL Server. Evite usar esses tipos de dados em novos trabalhos de desenvolvimento e planeje modificar os aplicativos que os utilizam atualmente. Use nvarchar(max), varchar(max)e varbinary(max). Ambos AFTER
e INSTEAD OF
gatilhos dão suporte a dados varchar(max), nvarchar(max) e varbinary(max) nas tabelas inseridas e excluídas.
Para gatilhos em tabelas com otimização de memória, o único sql_statement permitido no nível superior é um ATOMIC
bloco. O T-SQL permitido dentro do ATOMIC
bloco é limitado pelo T-SQL permitido dentro de procs nativos.
<method_specifier>
Para um gatilho CLR, especifica o método de associação de um assembly ao gatilho. O método não deve usar nenhum argumento e deve retornar nulo.
class_name deve ser um identificador válido do SQL Server e deve existir como uma classe no assembly com visibilidade do assembly. Se a classe tiver um nome qualificado para namespace que usa .
para separar partes do namespace, o nome da classe deverá ser delimitado usando delimitadores [ ] ou " " . A classe não pode ser aninhada.
Observação
Por padrão, a capacidade do SQL Server em executar código CLR está desligada. Você pode criar, modificar e remover objetos de banco de dados que fazem referência a módulos de código gerenciado, mas essas referências não são executadas em uma instância do SQL Server, a menos que a opção clr habilitada esteja habilitada com sp_configure.
Comentários sobre gatilhos DML
Os gatilhos DML são usados com frequência para impor as regras de negócio e a integridade dos dados. O SQL Server fornece integridade referencial declarativa (DRI) por meio das instruções e CREATE TABLE
instruçõesALTER TABLE
. Entretanto, DRI não fornece integridade referencial em todos os bancos de dados. A integridade referencial refere-se às regras sobre as relações entre as chaves primárias e estrangeiras de tabelas. Para impor a integridade referencial, use e PRIMARY KEY
FOREIGN KEY
restrições dentro ALTER TABLE
e CREATE TABLE
. Se houver restrições na tabela de gatilho, elas são verificadas após a execução do INSTEAD OF
gatilho e antes da execução do AFTER
gatilho. Se as restrições forem violadas, as ações de INSTEAD OF
gatilho serão revertidas e o AFTER
gatilho não será disparado.
Você pode especificar o primeiro e o último AFTER
gatilhos a serem executados em uma tabela usando sp_settriggerorder
. Você pode especificar apenas um primeiro e um último AFTER
gatilho para cada INSERT
e UPDATE
DELETE
operação em uma tabela. Se houver outros AFTER
gatilhos na mesma tabela, eles serão executados aleatoriamente.
Se uma instrução ALTER TRIGGER
alterar um primeiro ou último gatilho, o primeiro ou último atributo definido no gatilho modificado será descartado e você deverá redefinir o valor da ordem usando sp_settriggerorder
.
Um AFTER
gatilho é executado somente depois que a instrução SQL de gatilho é executada com êxito. Essa execução com êxito inclui todas as verificações de restrição e ações referenciais em cascata associadas ao objeto atualizado ou excluído. Um AFTER
não dispara recursivamente um INSTEAD OF
gatilho na mesma tabela.
Se um INSTEAD OF
gatilho definido em uma tabela executar uma instrução na tabela que normalmente dispararia o INSTEAD OF
gatilho novamente, o gatilho não será chamado recursivamente. Em vez disso, a instrução processa como se a tabela não tivesse gatilho INSTEAD OF
e inicia a cadeia de operações de restrição e AFTER
as execuções de gatilho. Por exemplo, se um gatilho for definido como um INSTEAD OF INSERT
gatilho para uma tabela. E, se o gatilho executar uma instrução INSERT
na mesma tabela, a INSERT
instrução iniciada pelo INSTEAD OF
gatilho não chamará o gatilho novamente. O INSERT
iniciado pelo gatilho inicia o processo de execução de ações de restrição e acionamento de quaisquer AFTER INSERT
gatilhos definidos para a tabela.
Quando um INSTEAD OF
gatilho definido em um modo de exibição executa uma instrução na exibição que normalmente acionaria o INSTEAD OF
gatilho novamente, ele não é chamado recursivamente. Pelo contrário, a instrução será solucionada como as modificações nas tabelas de base subjacentes à exibição. Nesse caso, a definição da exibição deve cumprir todas as restrições de uma exibição atualizável. Para uma definição de exibições atualizáveis, veja Modificar dados por meio de uma exibição.
Por exemplo, se um gatilho for definido como um INSTEAD OF UPDATE
gatilho para uma exibição. E, o gatilho executa uma instrução UPDATE
referenciando a mesma exibição, a UPDATE
instrução iniciada pelo INSTEAD OF
gatilho não chama o gatilho novamente. O UPDATE
inicializado pelo gatilho é processado na exibição como se o modo de exibição não tivesse um INSTEAD OF
gatilho. As colunas alteradas pelo UPDATE
deve ser resolvida para uma única tabela base. Cada modificação em uma tabela base subjacente inicia a cadeia de aplicação de restrições e gatilhos de disparo AFTER
definidos para a tabela.
Testar as ações UPDATE ou INSERT em colunas específicas
Você pode criar um gatilho Transact-SQL para executar determinadas ações com base ou INSERT
modificações em UPDATE
colunas específicas. Use UPDATE ou COLUMNS_UPDATED no corpo do gatilho para essa finalidade.
UPDATE()
UPDATE
testa ou INSERT
tenta em uma coluna.
COLUMNS_UPDATED
testa ou INSERT
ações executadas UPDATE
em várias colunas. Essa função retorna um padrão de bits que indica quais colunas foram inseridas ou atualizadas.
Limitações de gatilho
CREATE TRIGGER
deve ser a primeira instrução no lote e pode ser aplicada a apenas uma tabela.
Um gatilho é criado apenas no banco de dados atual; entretanto, ele pode referenciar objetos fora do banco de dados atual.
Se o nome de esquema do gatilho for especificado para qualificá-lo, qualifique o nome de tabela da mesma maneira.
A mesma ação de gatilho pode ser definida para mais de uma ação de usuário (por exemplo, INSERT
e UPDATE
) na mesma CREATE TRIGGER
instrução.
INSTEAD OF DELETE
/
INSTEAD OF UPDATE
gatilhos não podem ser definidos em uma tabela que tem uma chave estrangeira com uma cascata na DELETE
/UPDATE
ação definida.
Qualquer instrução SET pode ser especificada em um gatilho. A opção SET selecionada permanece em vigor durante a execução do gatilho e depois é revertida para sua configuração anterior.
Quando um gatilho é disparado, os resultados são retornados ao aplicativo de chamada, da mesma forma que com procedimentos armazenados. Para evitar que os resultados sejam retornados a um aplicativo devido a um disparo de gatilho, não inclua instruções SELECT
que retornam resultados ou instruções que executam a atribuição de variável em um gatilho. Um gatilho que inclui instruções SELECT
que retornam resultados para o usuário ou instruções que fazem atribuição de variável requer tratamento especial. Você teria que gravar os resultados retornados em cada aplicativo, para os quais são permitidas modificações na tabela do gatilho. Se a atribuição de variável precisar ocorrer em um gatilho, use uma SET NOCOUNT
instrução no início do gatilho para impedir o retorno de quaisquer conjuntos de resultados.
Embora uma TRUNCATE TABLE
instrução esteja em vigor DELETE
, ela não ativa um gatilho porque a operação não registra exclusões de linhas individuais. No entanto, somente os usuários com permissões para executar uma TRUNCATE TABLE
instrução precisam se preocupar em contornar inadvertidamente um DELETE
gatilho dessa maneira.
A WRITETEXT
instrução, registrada ou não registrada, não ativa um gatilho.
As seguintes instruções Transact-SQL não são permitidas em um gatilho DML:
ALTER DATABASE
CREATE DATABASE
DROP DATABASE
RESTORE DATABASE
RESTORE LOG
RECONFIGURE
Além disso, as instruções Transact-SQL a seguir não são permitidas em um gatilho DML usado em uma tabela ou exibição que seja alvo da ação de gatilho.
-
CREATE INDEX
(incluindoCREATE SPATIAL INDEX
eCREATE XML INDEX
) ALTER INDEX
DROP INDEX
DROP TABLE
DBCC DBREINDEX
ALTER PARTITION FUNCTION
-
ALTER TABLE
quando usado para executar as seguintes ações:- Adiciona, modifica ou descarta colunas.
- Alterna partições.
- Adicionar ou remover
PRIMARY KEY
ouUNIQUE
restrições.
Observação
Como o SQL Server não dá suporte a gatilhos definidos pelo usuário em tabelas do sistema, recomendamos que você não crie gatilhos definidos pelo usuário em tabelas do sistema.
Otimizar gatilhos DML
Os gatilhos funcionam em transações (implícitas ou não) e, enquanto estiverem abertos, bloquearão recursos. O bloqueio permanece em vigor até que a transação seja confirmada (com COMMIT
) ou rejeitada (com um ROLLBACK
). Quanto mais um gatilho é executado, maior a probabilidade de outro processo ser bloqueado. Portanto, escreva gatilhos para diminuir a duração deles sempre que possível. Uma maneira de alcançar uma duração mais curta é liberar um gatilho quando uma instrução DML altera zero linha.
Para liberar o gatilho para um comando que não altera nenhuma linha, empregue a variável de sistema ROWCOUNT_BIG.
O seguinte snippet de código T-SQL mostra como liberar o gatilho para um comando que não altera nenhuma linha. Esse código deverá estar presente no início de cada gatilho DML:
IF (ROWCOUNT_BIG() = 0)
RETURN;
Comentários sobre gatilhos DDL
Os gatilhos DDL, assim como os gatilhos padrão, iniciam procedimentos armazenados em resposta a um evento. Mas, ao contrário dos gatilhos padrão, eles não são executados em resposta a UPDATE
, INSERT
ou DELETE
instruções em uma tabela ou exibição. Em vez disso, eles são executados em resposta a instruções DDL (linguagem de definição de dados). Os tipos de instrução incluem CREATE
, ALTER
, DROP
, GRANT
, , DENY
, REVOKE
e UPDATE STATISTICS
. Determinados procedimentos armazenados do sistema que executam operações do tipo DDL também podem disparar gatilhos DDL.
Importante
Teste os gatilhos DDL para determinar suas respostas à execução de procedimentos armazenados do sistema. Por exemplo, a instrução CREATE TYPE
e os sp_addtype
procedimentos armazenados disparam sp_rename
um gatilho DDL criado em um CREATE_TYPE
evento.
Para obter mais informações sobre gatilhos DDL, consulte gatilhos DDL.
Os gatilhos DDL não são disparados em resposta a eventos que afetem tabelas temporárias locais ou globais e procedimentos armazenados.
Diferentemente dos gatilhos DML, os gatilhos DDL não têm seu escopo definido para esquemas. Portanto, você não pode usar funções como OBJECT_ID
, e OBJECT_NAME
OBJECTPROPERTY
OBJECTPROPERTYEX
para consultar metadados sobre gatilhos DDL. Use as exibições do catálogo em vez disso. Para obter mais informações, veja Obter informações sobre gatilhos DDL.
Observação
Os gatilhos DDL com escopo de servidor aparecem no Pesquisador de Objetos do SQL Server Management Studio na pasta Triggers . Essa pasta está localizada na pasta Server Objects . Os gatilhos DDL com escopo de banco de dados aparecem na pasta Gatilhos de Banco de Dados . Essa pasta fica localizada na pasta Programmability do banco de dados correspondente.
Gatilhos de logon
Os gatilhos de logon realizam procedimentos armazenados em resposta a um LOGON
evento. Esse evento ocorre quando é estabelecida uma sessão de usuário com uma instância do SQL Server. Os gatilhos de logon são acionados após o término da fase de autenticação, mas antes da sessão de usuário ser estabelecida. Portanto, todas as mensagens originadas dentro do gatilho que normalmente alcançariam o usuário, como mensagens de erro e mensagens da PRINT
instrução, são desviadas para o log de erros do SQL Server. Para obter mais informações, consulte gatilhos de Logon.
Os gatilhos de logon não são acionados quando a autenticação falha.
Não há suporte para transações distribuídas em um gatilho de logon. O erro 3969 é retornado quando é disparado um gatilho de logon que contém uma transação distribuída.
Desabilitar um gatilho de logon
Um gatilho de logon pode, efetivamente, impedir conexões com o Mecanismo de Banco de Dados para todos os usuários, incluindo membros da função de servidor fixa sysadmin . Quando um gatilho de logon está impedindo conexões, os membros da função de servidor fixa sysadmin podem se conectar usando a conexão de administrador dedicada ou iniciando o Mecanismo de Banco de Dados no modo de configuração mínimo (-f
). Para obter mais informações, consulte as opções de inicialização do Serviço do Mecanismo de Banco de Dados .
Considerações gerais sobre o gatilho
Retornar resultados
A habilidade de retornar resultados de gatilhos será removida na próxima versão do SQL Server. Gatilhos que retornam conjuntos de resultados podem causar um comportamento inesperado em aplicativos que não foram projetados para trabalhar com eles. Evite retornar conjuntos de resultados de gatilhos em novos trabalhos de desenvolvimento e planeje a modificação de aplicativos que atualmente fazem. Para evitar que os gatilhos retornem conjuntos de resultados, defina a opção proibir resultados de gatilhos como 1.
Os gatilhos de logon sempre impedem o retorno de conjuntos de resultados, e esse comportamento não é configurável. Se um gatilho de logon gerar um conjunto de resultados, o gatilho falhará ao ser iniciado e a tentativa de logon que o disparou será negada.
Vários gatilhos
O SQL Server permite criar vários gatilhos para cada DML, DDL ou LOGON
evento. Por exemplo, se CREATE TRIGGER FOR UPDATE
for executado para uma tabela que já tem um UPDATE
gatilho, um gatilho de atualização adicional será criado. Em versões anteriores do SQL Server, apenas um gatilho para cada INSERT
UPDATE
evento de modificação de dados é DELETE
permitido para cada tabela.
Gatilhos recursivos
O SQL Server também dá suporte à invocação recursiva de gatilhos quando a RECURSIVE_TRIGGERS
configuração está habilitada usando ALTER DATABASE
.
Os gatilhos recursivos permitem que os seguintes tipos de recursão ocorram:
Recursão indireta: com a recursão indireta, um aplicativo atualiza a tabela
T1
. Isso dispara o gatilhoTR1
, atualizando a tabelaT2
. DispareT2
e atualize a tabelaT1
.Recursão direta: na recursão direta, o aplicativo atualiza a tabela
T1
. Isso dispara o gatilhoTR1
, atualizando a tabelaT1
. Como a tabelaT1
foi atualizada, dispareTR1
novamente e assim por diante.
O exemplo a seguir usa a recursão de gatilho indireto e direto pressupõe que dois gatilhos TR1
de atualização e TR2
.T1
Disparar TR1
a tabela T1
de atualizações recursivamente. Uma instrução UPDATE
é executada cada TR1
vez.TR2
Além disso, o início dos TR1
gatilhos é a execução de TR1
(recursivamente) e TR2
. As tabelas inseridas e excluídas de um gatilho específico contêm linhas que correspondem apenas à UPDATE
instrução que invocou o gatilho.
Observação
O comportamento anterior ocorre somente se a RECURSIVE_TRIGGERS
configuração estiver habilitada usando ALTER DATABASE
. Não há nenhuma ordem definida na qual vários gatilhos definidos para um evento específico sejam executados. Cada gatilho deve ser autossuficiente.
Desabilitar a RECURSIVE_TRIGGERS
configuração só impede recursões diretas. Para desabilitar a recursão indireta também, defina a opção de servidor de gatilhos aninhados como 0 usando sp_configure
.
Se qualquer um dos gatilhos executar um ROLLBACK TRANSACTION
, independentemente do nível de aninhamento, não serão executados mais gatilhos.
Gatilhos aninhados
É possível aninhar até no máximo 32 níveis. Se um gatilho alterar uma tabela em que haja outro gatilho, o segundo gatilho será ativado e poderá chamar um terceiro gatilho e assim por diante. Se qualquer gatilho na cadeia iniciar um loop infinito, o nível de aninhamento será excedido e o gatilho será cancelado. Quando um gatilho Transact-SQL inicia um código gerenciado fazendo referência a uma rotina, tipo ou agregação CLR, essa referência também conta como um nível no limite de aninhamento de nível 32. Os métodos invocados a partir do código gerenciado não são contados em relação a esse limite.
Para desabilitar gatilhos aninhados, defina a opção de gatilhos aninhados como sp_configure
0 (desativado). A configuração padrão oferece suporte a gatilhos aninhados. Se os gatilhos aninhados estiverem desativados, os gatilhos recursivos também serão desabilitados, apesar da RECURSIVE_TRIGGERS
configuração definida usando ALTER DATABASE
.
O primeiro AFTER
gatilho aninhado dentro de um INSTEAD OF
gatilho é acionado mesmo se a opção de configuração de servidor de gatilhos aninhados for 0. Mas, nessa configuração, os gatilhos posteriores AFTER
não são acionados. Verifique se há gatilhos aninhados nos seus aplicativos a fim de determinar se os aplicativos seguem as regras de negócio quando a opção de configuração do servidor de gatilhos aninhados está definida como 0. Caso contrário, faça as modificações apropriadas.
Resolução de nomes adiados
O SQL Server permite que Transact-SQL procedimentos armazenados, gatilhos, funções e lotes se refiram a tabelas que não existem no momento da compilação. Essa capacidade é chamada de resolução de nome adiada.
Permissões
Para criar um gatilho DML, ele requer ALTER
permissão na tabela ou exibição na qual o gatilho está sendo criado.
Para criar um gatilho DDL com escopo de servidor (ON ALL SERVER
) ou um gatilho de logon, requer CONTROL SERVER
permissão no servidor. Para criar um gatilho DDL com escopo de banco de dados (ON DATABASE
), requer ALTER ANY DATABASE DDL TRIGGER
permissão no banco de dados atual.
Exemplos
a. Usar um gatilho DML com uma mensagem de lembrete
O gatilho DML a seguir imprime uma mensagem para o cliente quando alguém tenta adicionar ou alterar dados na tabela Customer
do banco de dados AdventureWorks2022.
CREATE TRIGGER reminder1
ON Sales.Customer
AFTER INSERT, UPDATE
AS RAISERROR ('Notify Customer Relations', 16, 10);
GO
B. Usar um gatilho DML com uma mensagem de email de lembrete
O exemplo a seguir envia uma mensagem de email a uma pessoa especificada (MaryM
) quando a tabela Customer
é alterada.
CREATE TRIGGER reminder2
ON Sales.Customer
AFTER INSERT, UPDATE, DELETE
AS
EXECUTE msdb.dbo.sp_send_dbmail
@profile_name = 'AdventureWorks2022 Administrator',
@recipients = 'danw@Adventure-Works.com',
@body = 'Don''t forget to print a report for the sales force.',
@subject = 'Reminder';
GO
C. Usar um gatilho DML AFTER para impor uma regra de negócios entre as tabelas PurchaseOrderHeader e Vendor
Como CHECK
as restrições fazem referência apenas às colunas nas quais a restrição de nível de coluna ou de nível de tabela é definida, você deve definir quaisquer restrições entre tabelas (nesse caso, regras de negócios) como gatilhos.
O exemplo a seguir cria um gatilho DML no banco de dados AdventureWorks2022
. Esse gatilho realiza uma verificação para ter certeza de que a avaliação de crédito do fornecedor é satisfatória (não 5) quando há uma tentativa de inserir uma nova ordem de compra na tabela PurchaseOrderHeader
. Para obter a classificação de crédito do fornecedor, a tabela Vendor
deve ser referenciada. Se a classificação de crédito for muito baixa, uma mensagem será exibida e a inserção não será executada.
USE AdventureWorks2022;
GO
IF OBJECT_ID('Purchasing.LowCredit', 'TR') IS NOT NULL
DROP TRIGGER Purchasing.LowCredit;
GO
-- This trigger prevents a row from being inserted in the Purchasing.PurchaseOrderHeader table
-- when the credit rating of the specified vendor is set to 5 (below average).
CREATE TRIGGER Purchasing.LowCredit
ON Purchasing.PurchaseOrderHeader
AFTER INSERT
AS
IF (ROWCOUNT_BIG() = 0)
RETURN;
IF EXISTS (SELECT 1
FROM inserted AS i
INNER JOIN Purchasing.Vendor AS v
ON v.BusinessEntityID = i.VendorID
WHERE v.CreditRating = 5)
BEGIN
RAISERROR ('A vendor''s credit rating is too low to accept new purchase orders.', 16, 1);
ROLLBACK;
RETURN;
END
GO
-- This statement attempts to insert a row into the PurchaseOrderHeader table
-- for a vendor that has a below average credit rating.
-- The AFTER INSERT trigger is fired and the INSERT transaction is rolled back.
INSERT INTO Purchasing.PurchaseOrderHeader (RevisionNumber, Status, EmployeeID,
VendorID, ShipMethodID, OrderDate, ShipDate, SubTotal, TaxAmt, Freight)
VALUES (2, 3, 261, 1652, 4, GETDATE(), GETDATE(), 44594.55, 3567.564, 1114.8638);
GO
D. Usar um gatilho DDL com escopo de banco de dados
O exemplo a seguir usa um gatilho DDL para evitar que qualquer sinônimo em um banco de dados seja descartado.
CREATE TRIGGER safety
ON DATABASE
FOR DROP_SYNONYM
AS IF (@@ROWCOUNT = 0)
RETURN;
RAISERROR ('You must disable Trigger "safety" to remove synonyms!', 10, 1);
ROLLBACK;
GO
DROP TRIGGER safety
ON DATABASE;
GO
E. Usar um gatilho DDL com escopo de servidor
O exemplo a seguir usa um gatilho DDL para imprimir uma mensagem se algum CREATE DATABASE
evento ocorrer na instância do servidor atual e usa a EVENTDATA
função para recuperar o texto da instrução Transact-SQL correspondente. Para obter mais exemplos que usam EVENTDATA
em gatilhos DDL, consulte Usar a função EVENTDATA.
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS PRINT 'Database Created.';
SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'nvarchar(max)');
GO
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO
F. Usar um gatilho de logon
O exemplo de gatilho de logon a seguir nega uma tentativa de fazer logon no SQL Server como membro do login_test
logon se já houver três sessões de usuário em execução nesse logon. Altere <password>
para uma senha forte.
USE master;
GO
CREATE LOGIN login_test
WITH PASSWORD = '<password>' MUST_CHANGE, CHECK_EXPIRATION = ON;
GO
GRANT VIEW SERVER STATE TO login_test;
GO
CREATE TRIGGER connection_limit_trigger
ON ALL SERVER
WITH EXECUTE AS 'login_test'
FOR LOGON
AS BEGIN
IF ORIGINAL_LOGIN() = 'login_test'
AND (SELECT COUNT(*)
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
AND original_login_name = 'login_test') > 3
ROLLBACK;
END
G. Exibir os eventos que fazem com que um gatilho seja acionado
O exemplo a seguir consulta as exibições do catálogo sys.triggers
e sys.trigger_events
para determinar quais eventos de linguagem Transact-SQL fazem o gatilho safety
ser acionado. O gatilho é safety
criado no exemplo D. Use um gatilho DDL com escopo de banco de dados.
SELECT TE.*
FROM sys.trigger_events AS TE
INNER JOIN sys.triggers AS T
ON T.object_id = TE.object_id
WHERE T.parent_class = 0
AND T.name = 'safety';
GO
Conteúdo relacionado
- ALTERAR TABELA (Transact-SQL)
- ALTER TRIGGER (Transact-SQL)
- COLUMNS_UPDATED (Transact-SQL)
- CREATE TABLE (Transact-SQL)
- DROP TRIGGER (Transact-SQL)
- ENABLE TRIGGER (Transact-SQL)
- DESABILITAR GATILHO (Transact-SQL)
- TRIGGER_NESTLEVEL (Transact-SQL)
- EVENTDATA (Transact-SQL)
- sys.dm_sql_referenced_entities
- sys.dm_sql_referencing_entities
- sys.sql_expression_dependencies
- sp_help
- sp_helptrigger
- sp_helptext
- sp_rename
- sp_settriggerorder
- UPDATE – Funções de gatilho (Transact-SQL)
- Obter informações sobre gatilhos DML
- Obter informações sobre gatilhos DDL
- sys.triggers
- sys.trigger_events
- sys.sql_modules
- sys.assembly_modules
- sys.server_triggers
- sys.server_trigger_events
- sys.server_sql_modules
- sys.server_assembly_modules