Instrução CREATE TRIGGER

O gatilho define um conjunto de ações a serem executadas quando ocorre um evento de banco de dados em uma determinada tabela. O evento de banco de dados é uma operação de exclusão, inserção ou de atualização. Por exemplo, se for definido um gatilho para exclusão em uma determinada tabela, a ação do gatilho ocorre sempre que se remove uma ou mais linhas da tabela.

Junto com as restrições, os gatilhos podem ajudar a impor regras de integridade com ações como exclusões ou atualizações em cascata. Os gatilhos também podem realizar várias funções como emitir alertas, atualizar outras tabelas, enviar e-mail, e outras ações úteis.

Pode ser definido qualquer número de gatilhos para uma única tabela, inclusive vários gatilhos para a mesma tabela para o mesmo evento.

Pode ser criado gatilho em qualquer esquema, exceto os começados por SYS. O gatilho não precisa residir no mesmo esquema da tabela para a qual é definido.

Se for especificado um nome de gatilho qualificado, o nome do esquema não poderá começar por SYS.

Sintaxe

CREATE TRIGGER nome-do-gatilho
{ AFTER | NO CASCADE BEFORE }
{ INSERT | DELETE | UPDATE } [ OF nome-da-coluna [, nome-da-coluna]* ]
ON nome-da-tabela
[ CláusulaReferência ]
FOR EACH { ROW | STATEMENT } MODE DB2SQL
Instrução-SQL-engatilhada

Antes ou depois: quando os gatilhos disparam

Os gatilhos são definidos para BEFORE (antes) ou AFTER (depois).
  • Os gatilhos BEFORE disparam antes das modificações da instrução serem aplicadas, e antes de qualquer restrição ser aplicada. Os gatilhos para antes podem ser tanto de linha quanto de instrução (consulte Gatilhos de instrução versus gatilhos de linha).
  • Os gatilhos AFTER disparam após todas as restrições terem sido satisfeitas, e após todas as alterações terem sido aplicadas à tabela de destino. Os gatilhos AFTER podem ser tanto de linha quanto de instrução (consulte Gatilhos de instrução versus gatilhos de linha).

Inserção, exclusão e atualização: o que faz o gatilho disparar

O gatilho é disparado por um dos seguintes eventos do banco de dados, dependendo de como foi definido (consulte Sintaxe acima):
  • INSERT
  • UPDATE
  • DELETE

Pode ser definido qualquer número de gatilhos para um determinado evento em uma determinada tabela. No caso de gatilho para atualização podem ser especificadas as colunas.

Referência a valores antigos e novos: a cláusula de referência

Muitas instruções-SQL-engatilhadas necessitam fazer referência aos dados que estão sendo alterados no momento pelo evento de banco de dados que causou o disparo do gatilho. A instrução-SQL-engatilhada pode necessitar fazer referência aos valores novos (pós-alteração ou "após").

O Derby fornece várias maneiras para fazer referência aos dados que estão sendo alterados no momento pelo evento do banco de dados que fez o gatilho disparar. Os dados alterados podem ser referenciados pela instrução-SQL-engatilhada utilizando variáveis de transição ou tabelas de transição. A cláusula de referência permite o fornecimento do nome da correlação ou aliás para estas variáveis de transição especificando OLD/NEW AS nome-da-correlação.

Por exemplo, se for adicionada a seguinte cláusula à definição do gatilho:
REFERENCING OLD AS LINHA_APAGADA
pode-se então fazer referência a este nome de correlação na instrução-SQL-engatilhada:
DELETE FROM DISPONIBILIDADE_HOTEL WHERE ID_HOTEL = LINHA_APAGADA.ID_HOTEL
As variáveis de transição OLD e NEW são mapeadas a um java.sql.ResultSet de uma única linha.
Nota: Somente os gatilhos de linha (consulte Gatilhos de instrução versus gatilhos de linha) podem utilizar variáveis de transição. Os gatilhos de linha para INSERT não podem fazer referência à linha antiga. Os gatilhos de linha para DELETE não podem fazer referência à linha nova.

Para os gatilhos de instrução, as tabelas de transição servem como identificador de tabela para a instrução-SQL-engatilhada ou para a qualificação do gatilho. A cláusula de referência permite fornecer um nome de correlação ou aliás para estas tabelas de transição especificando OLD_TABLE/NEW_TABLE AS nome-da-correlação

Por exemplo:
REFERENCING OLD_TABLE AS HOTÉIS_EXCLUÍDOS
permite utilizar este novo identificador (HOTÉIS_EXCLUÍDOS) na instrução-SQL-engatilhada:
DELETE FROM DISPONIBILIDADE_HOTEL WHERE ID_HOTEL IN
(SELECT ID_HOTEL FROM HOTÉIS_EXCLUÍDOS)
As tabelas de transição antiga e nova são mapeadas a um java.sql.ResultSet com cardinalidade equivalente ao número de linhas afetadas pelo evento do gatilho.
Nota: Somente os gatilhos de instrução (consulte Gatilhos de instrução versus gatilhos de linha) podem utilizar tabelas de transição. Os gatilhos para a instrução INSERT não podem fazer referência à tabela OLD. Os gatilhos para a instrução DELETE não podem fazer referência à tabela NEW.

A cláusula REFERENCING pode designar apenas uma correlação ou identificador para novo, e apenas uma correlação ou identificador para antigo. Os gatilhos de linha não podem designar um identificador para a tabela de transição, e os gatilhos de instrução não podem designar uma correlação para as variáveis de transição.

Gatilhos de instrução versus gatilhos de linha

Deve ser especificado se o gatilho é um gatilho de instrução ou um gatilho de linha:
  • gatilho de instrução

    O gatilho de instrução dispara uma vez por evento de gatilho, independentemente de alguma linha ser modificada pelo evento de inserção, atualização ou exclusão.

  • gatilho de linha

    O gatilho de linha dispara uma vez para cada linha afetada pelo evento de gatilho. Se nenhuma linha for afetada, o gatilho não vai disparar.

Nota: Uma atualização que define o valor da coluna como o valor originalmente contido (por exemplo, UPDATE T SET C = C) faz com que o gatilho de linha dispare, embora o valor da coluna seja o mesmo que era antes do evento de gatilho.

Instrução-SQL-engatilhada

A ação definida pelo gatilho é chamada de instrução-SQL-engatilhada (na Sintaxe acima, veja a última linha). Possui as seguintes limitações:
  • Não pode conter parâmetros dinâmicos (?).
  • Não pode criar, alterar ou remover a tabela para a qual o gatilho está definido.
  • Não pode adicionar ou remover um índice na tabela para a qual o gatilho está definido.
  • Não pode adicionar ou remover um gatilho na tabela para a qual o gatilho está definido.
  • Não pode efetivar ou desfazer a transação corrente, ou mudar o nível de isolamento.
  • Não pode executar a instrução CALL.
  • Os gatilhos para antes não podem possuir instruções INSERT, UPDATE ou DELETE como sua ação.

A instrução-SQL-engatilhada pode fazer referência a outros objetos do banco de dados além da tabela para a qual o gatilho é declarado. Se algum destes objetos for removido, o gatilho será invalidado. Se na próxima execução a recompilação do gatilho não for bem-sucedida, a chamada lançará uma exceção e a instrução que causou o disparo será desfeita.

Para obter mais informações sobre instrução-SQL-engatilhada deve ser consultado o Guia do Desenvolvedor do Derby.

Ordem de execução

Quando ocorre um evento de banco de dados que dispara um gatilho, o Derby realiza ações nesta ordem:
  • Dispara os gatilhos NO CASCADE BEFORE.
  • Realiza a verificação das restrições (verifica chave primária, chave única e chave estrangeira).
  • Realiza a inserção, atualização ou exclusão.
  • Dispara os gatilhos AFTER.

Quando são definidos vários gatilhos para o mesmo evento de banco de dados, para a mesma tabela, e para o mesmo instante (antes ou depois), os gatilhos são disparados na ordem em que foram criados.

-- Instruções e gatilhos:

CREATE TRIGGER T1 NO CASCADE BEFORE UPDATE ON X
  FOR EACH ROW MODE DB2SQL
  values app.notifyEmail('Jerry', 'A tabela x está para ser atualizada');

CREATE TRIGGER EXCLUI_VÔOS
  AFTER DELETE ON VÔOS
  REFERENCING OLD_TABLE AS VÔOS_EXCLUÍDOS
  FOR EACH STATEMENT MODE DB2SQL
  DELETE FROM VÔOS_DISPONIBILIDADE WHERE ID_VÔO IN
  (SELECT ID_VÔO FROM VÔOS_EXCLUÍDOS);

CREATE TRIGGER EXCLUI_VÔOS3
  AFTER DELETE ON VÔOS
  REFERENCING OLD AS OLD
  FOR EACH ROW MODE DB2SQL
  DELETE FROM VÔOS_DISPONIBILIDADE WHERE ID_VÔO = OLD.ID_VÔO;

Nota: Podem ser encontrados mais exemplos no Guia do Desenvolvedor do Derby.

Recursividade de gatilho

A profundidade de recursividade máxima de gatilho é 16.

Informações relacionadas

As funções de sistema especiais que retornam informação sobre a hora corrente ou o usuário corrente são avaliadas quando o gatilho dispara, e não quando o gatilho é criado. Estas funções incluem:
Referências relacionadas
Instrução CREATE FUNCTION
Instrução CREATE INDEX
Instrução CREATE PROCEDURE
Instrução CREATE SCHEMA
Instrução CREATE SYNONYM
Instrução CREATE TABLE
Instrução CREATE VIEW