# 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:

- CURRENT_DATE
- CURRENT_TIME
- CURRENT_TIMESTAMP
- CURRENT_USER
- SESSION_USER
- USER

- CláusulaReferência

Tópico pai: Instruções CREATE
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