trigger

10
Trigger - É um programa PL/SQL armazenado no banco de dados e que é executado imediatamente antes ou após os comandos INSERT, UPDATE e DELETE. Triggers em PL/SQL Escrevendo triggers de banco de dados Um trigger é usado para escrever a lógica de procedimento que é invocada em resposta a um evento específico. A aplicação criativa dos triggers de banco de dados permite que você realize muitas coisas úteis que, de outra forma, não seriam possíveis. Os exemplos daquilo que você pode fazer com os triggers incluem a replicação de dados, o armazenamento dos dados de forma redundante para evitar associações freqüentes de tabela e a implantação de regras de negócios complexas. O que é um trigger? Um trigger é um bloco PL/SQL que é associado a um evento específico, armazenado em um banco de dados e executado sempre que o evento ocorrer. Oracle8i agora suporta quatro tipos fundamentais de triggers: . Os triggers Data manipulation language (DML) . Os triggers instead-of . Os triggers Data definition language (DDL) . Os triggers de evento de banco de dados Os triggers DML são os triggers tradicionais INSERT, UPDATE e DELETE que a Oracle tem suportado há anos. Os triggers instead-of foram introduzidos com a Oracle8 como um modo de possibilitar a atualização de determinados tipos de visões. Os triggers DDL e os triggers de evento de banco de dados são novos na Oracle8i. Triggers DML

Upload: sergio-marcos

Post on 26-Jun-2015

197 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Trigger

Trigger - É um programa PL/SQL armazenado no banco de dados e que é executado imediatamente antes ou após os comandos INSERT, UPDATE e DELETE.

Triggers em PL/SQLEscrevendo triggers de banco de dados

Um trigger é usado para escrever a lógica de procedimento que é invocada em resposta a um evento específico. A aplicação criativa dos triggers de banco de dados permite que você realize muitas coisas úteis que, de outra forma, não seriam possíveis.

Os exemplos daquilo que você pode fazer com os triggers incluem a replicação de dados, o armazenamento dos dados de forma redundante para evitar associações freqüentes de tabela e a implantação de regras de negócios complexas.

O que é um trigger?

Um trigger é um bloco PL/SQL que é associado a um evento específico, armazenado em um banco de dados e executado sempre que o evento ocorrer.

Oracle8i agora suporta quatro tipos fundamentais de triggers:

. Os triggers Data manipulation language (DML)

. Os triggers instead-of

. Os triggers Data definition language (DDL)

. Os triggers de evento de banco de dados

Os triggers DML são os triggers tradicionais INSERT, UPDATE e DELETE que a Oracle tem suportado há anos.

Os triggers instead-of foram introduzidos com a Oracle8 como um modo de possibilitar a atualização de determinados tipos de visões. Os triggers DDL e os triggers de evento de banco de dados são novos na Oracle8i.

Triggers DML

Os triggers DML são os triggers tradicionais que podem ser definidos em uma tabela e são executados, ou disparados, em resposta aos seguintes eventos:

Uma linha de uma tabela é atualizada. Uma linha de uma tabela é excluída. Não é possível definir um trigger para ser disparado quando uma linha é selecionada.

Uma definição de trigger DML consiste nestas partes básicas:

. O evento que dispara o trigger.

. A tabela do banco de dados no qual o evento deve ocorrer.

. Uma condição opcional que controla a hora em que o trigger é executado.

Page 2: Trigger

Um bloco PL/SQL contendo o código a ser executado quando o trigger é disparado, ou uma declaração CALL para um procedimento armazenado.

Um trigger é um objeto de banco de dados, assim como uma tabela ou um índice.

Quando você define um trigger, ele se torna parte do banco de dados e é sempre executado quando o evento para o qual ele é definido ocorre.

Não importa se o evento é disparado por alguma digitação em uma declaração SQL usando o SQL Plus, executando um programa de cliente-servidor que atualiza o banco de dados, ou executam um utilitário como o SQL"-Loader do Oracle para fazer o bulk-load dos dados.

Por causa disso, um trigger permite que você execute validação crítica ou cálculos em resposta às alterações fitas no banco de dados, seja qual for a fonte.

Um exemplo de trigger DML

Suponhamos que você queira ter certeza de que todos os nomes de departamentos foram armazenados usando letras maiúsculas. Talvez você esteja fazendo isso para facilitar a pesquisa naquele campo.

1: CREATE OR REPLACE TRIGGER department insert update2: BEFORE INSÈRT OR UPDATE ON department3: FOR EACH ROW4: DECLARE 5: dup flag INTEGER;6: BEGIN 7: --Força as maiúsculas em todos os departamentos.8: :NEW.dept name := UPPER(:NEW.dept name);9: END; 10:

A linha 1 diz à Oracle para criar esse trigger com o nome department_insert update para substituir, se preciso, todo trigger existente de mesmo nome. A linha 2 diz que ele será disparado sempre que uma linha nova for inserida na tabela de departamentos ou sempre que um registro de departamento mudar. Na linha 8 há uma linha de código que usa a função incorporada UPPER para forçar o nome do departamento a ser colocado em maiúsculas. Observe a referência a : NEW. Esse é o alias padrão para o novo valor do registro.

O alias :OLD pode ser usado para se referir ao valor antigo de um campo antes que- aconteça unia atualização. A linha 3 diz à Oracle para disparar esse trigger uma vez para cada linha modificada. Se você precisasse emitir uma declaração UPDATE para alterar os nomes de todos os departamentos da tabela, esse trigger seria disparado para cada um daqueles registros.

Para demonstrar o efeito desse trigger, tente emitir as declarações da Listagem

Page 3: Trigger

1: INSERT INTO department (dept id, dept_name) VALUES (10,'marcio');2: 1 row created. 3: INSERT INTO department (dept id, dept_name) VALUES (11,'novelli');4: 1 row created. 5: UPDATE department SET dept_name = 'Payroll' WHERE dept_id = 10;6: 1 row updated.7: SELECT dept_id, dept_name FROM department WHERE dept_id BETWEEN 10 AND 11;8: DEPT ID DEPT NAME9: --------- ------------------------------- 10: 10 MARCIO11: 11 NOVELLI

OBS: Observe que o trigger forçou todos os nomes de departamento a serem colocados em maiúsculas, independentemente do nome ter sido o resultado de um registro novo inserido ou de um registro existente que foi atualizado.

Tipos de triggers DML

Os triggers DML podem ser classificados de duas maneiras diferentes: quando eles são disparados com relação à declaração SQL de trigger, ou se eles disparam ou não para cada linha afetada pela declaração SQL de disparo.

Existem duas opções quando um trigger é disparado com relação a uma declaração SQL: antes ou depois. Os before triggers são executados antes do disparo da declaração SQL. Os after triggers são executados depois do disparo da declaração SQL.

Um trigger DML é um trigger no nível de linha ou um trigger no nível de declaração. Um trigger no nível de linha é executado uma vez para cada linha afetada pelo disparo da declaração SQL, enquanto que um trigger no nível de declaração é executado apenas unia vez. Somente os triggers no nível de linha têm acesso aos valores de dados dos registros afetados.

Os triggers no nível de declaração não. Isso acontece porque a SQL é uma linguagem orientada para o conjunto-as declarações SQL podem afetar muitas ou mesmo todas as linhas de uma tabela.

Os triggers no nível de declaração são disparados apenas uma vez; portanto, não seria possível determinar uma referência de coluna em tal trigger.

Quando são disparados Nível Descrição

Os triggers são executados como resposta a uma declaração SQL e podem ser definidos para as declarações INSERT, UPDATE e DE LETE. Estas são chamadas de insert triggers, update tringgers e delete triggers, respectivamente.

Na próxima matéria vou falar de como usar os triggers para modificar os dados que estão sendo inseridos em uma tabela.

Page 4: Trigger

Usos dos triggers em PL/SQLA sintaxe para definir um trigger de banco de dados

A sintaxe usada para definir um trigger DML tradicional em uma tabela de banco de dados. Partes da sintaxe são meio complexas, mas não se deixe intimidar.

CREATE [OR REPLACE] TRIGGER [schema.]trigger name{BEFORE{AFTER} verb_list ON [schema.]table name[[REFERENCING correlation_names] FOR EACH ROW [WHEN (condition)]] DECLAREdeclarationsBEGINpl/sql codeEND;

Nessa sintaxe os parâmetros são os seguintes:

schema - Refere-se ao proprietário de uni objeto. Quando usado antes de um nome e triger, ele se refere ao proprietário do trigger. Quando usado antes de um nome de tabela ele se refere ao proprietário da tabela.

trigger name - é o nome que você deseja dar ao trigger.

verb_list - identifica os verbos SQL que são disparados por aquele trigger. A sintaxe de verb_list é a seguinte:

{INSERT;DELETE;UPDATE [DF column_list]} [OR verb_list]

Os parâmetros de verb_list são:

column_list - Faz com que uni update, trigger seja disparado apenas quando uma das colunas listadas é alterada. Caso contrário, o trigger dispara sempre que alguma coluna da tabela é alterada.

verb_list - Essa é outra interação de verb_list. Você pode criar um triggerque é disparado por mais de um verbo SQL.

table_name - é a tabela na qual o trigger está definido.

correlation_names - permite especificar os nomes de correlação além do padrão OLD e NEW. Isso é útil quando a tabela na qual o trigger é definido se chama OLD ou NEW, e também pode ser útil para tornar o código do trigger auto documentado. A cláusula de referência se parece com o seguinte:

{OLD AS old alias;NEW AS new alias [corre lation nomes]}

Na sintaxe acima os parâmetros são:

Page 5: Trigger

old_alias - Esse é o nome que você deseja usar quando se referir ao valor de um campo antes que o verbo SQL seja executado.

new_alias - Esse é o nome que você quer usar quando se referir ao valor de uni campo depois que o verbo SQL for executado

correlation_names - Essa é outra iteração do alias_list. Você pode especificar um alias para os valores old e new.

condition - é uma condição opcional colocada na execução do trigger. Ela só pode ser usada nos triggers no nível de linha. Se condition estiver presente, o trigger só será disparado quando a condição for verdadeira.

A condição pode ser qualquer expressão boolean, não pode conter nenhuma consulta e deve usar os nomes de correlação, em outras palavras, NEW e OLD para se referir aos valores de coluna da linha que está sendo alterada.

declarations - consiste em quaisquer declarações de variável, registro ou cursor necessárias para esse bloco PL/SQL.

pl /sgl_code - é o código PL/SQL que é executado quando o trigger é disparado.

DECLARE...END; - Opcionalmente você pode substituir todo o bloco PL/SQI. por uma declaração CALL que se parece com o seguinte:

CALL procedure name;

A declaração CALL é usada para fazer com que o trigger consista em apenas uma chamada de procedimento armazenado.

Os nomes de correlação: OLD e: NEW merecem unia explicação adicional. É comum ao escrever um trigger referenciar os valores do registro que estão sendo inseridos, atualizados ou excluídos. Além disso, no caso de unia atualização, quase sempre é preciso acessar os valores anteriores e posteriores a determinado campo.

Os nomes de correlação: OLD e: NEW são fornecidos para esse fim. Isso funciona como uni registro da PL/SQL: OLD contém os valores de campo antes deles serem atualizados e: NEW contém os valores de campo depois da atualização. Use i notação de ponto padrão, em outras palavras: OLD.field_name para se referir ao valor de determinado campo. Você verá exemplos disso em diversas listagens deste capítulo.

Usos dos triggers

Os usos possíveis para os triggers de banco de dados variam e são limitados apenas pela sua imaginação. Alguns usos comuns são:

-Implantação de regras de negócios-Manutenção da integridade referencial-Implantação de segurança-Manutenção de um registro histórico das alterações

Page 6: Trigger

-Geração de valores de coluna, incluindo valores de chave primária-Replicação de dados

Manutenção da integridade de dados

Os triggers são usados para ajudar na manutenção da integridade dos dados que estão armazenados no banco de dados. Suponhamos que você queira armazenar urna contagem do número de empregados de cada departamento e que você queira armazenar essa contagem na tabela de departamentos. Primeiro você adicionaria um campo de contagem de empregados à tabela de departamentos usando uma declaração como esta:

ALTER TABLE departmentADD (num_emp NUMBER(38));

O campo num_emp é usado para controlar o número de empregados de determinado departamento. Pense em como essa contagem de empregados poderia ser atualizada.

Uma solução possível seria fazer com que todo programa que adicionasse, excluísse ou alterasse a atribuição de departamento de um empregado também atualizasse esse valor apropriadamente. Isso funcionaria se os programas funcionassem corretamente, e se você não se esquecesse de que o valor precisaria ser atualizado.

Infelizmente à medida que novos programadores são adicionados a um projeto e à medida que o número de programas que precisam atualizar esse valor aumenta, a probabilidade de ocorrer um erro também aumenta. Os triggers fornecem um mecanismo para centralizar o código para atualizar um contador como esse.

Como você tem de lidar com inserts, updates e deletes, três triggers são necessários para atualizar a conta de empregado de departamento

Tipo do trigger

Insert - Quando um empregado é adicionado, este trigger precisa incrementar a contagem do departamento apropriado.

Update - Quando o departamento de um empregado muda, este trigger precisa decrementar a contagem dos departamentos anteriores e incrementar a contagem de departamento novo.

Delete - Quando um empregado é excluído, este trigger precisa decrementar a contagem do departamento apropriado.

O exemplo abaixo mostra o código para criar os três triggers necessários para atualizar as contas de empregado de cada departamento.

1: CREATE OR REPLACE TRIGGER emp_dept_ins - INSERIR2: AFTER INSERT ON emp_dept 3: FOR EACH ROW4: BEGIN5: --Incrementa a contagem de empregados do departamento

Page 7: Trigger

6: --referenciada pelo registro que acabou de ser inserido.7: UPDATE department8: SET no_of_emps = NVL(no_of_emps,O)+19: WHERE dept id = :NEW.dept_id; 10: END;11: /12:13: CREATE OR REPLACE TRIGGER emp_dept_del - DELETAR14: AFTER DELETE ON emp_dept 15: FOR EACH ROW16: BEGIN17: --Decrementa a contagem de empregados do departamento18: --referenciada pelo registro que acabou de ser excluído.19: UPDATE department20: SET no_ of+_emps = no_of_emps-121: WHERE dept_id = :OLD.dept_id;22: END;23: /24:25: CREATE OR REPLACE TRIGGER emp_dept_upd - UPDATE26: AFTER UPDATE OF dept id ON emp_dept 27:FOR EACH ROW28: BEGIN29: --Incrementa a contagem de empregados para o departamento novo do empregado 30: UPDATE department31: SET no _of_emps = NVL(no_of_emps,0)+132: WHERE dept_id = :NEW.dept_id;33:34: --Decrementa a contagem de empregados para o departamento 35: --anterior do empregado.36: UPDATE department37: SET no_of_emps = no_of_emps - 138: WHERE dept_id = :OLD.dept_id; 39: END;40: /

Agora que você criou os triggers necessários e inicializou os contadores pode fazer algumas consultas para testar o seu código. Um exemplo de registros de empregados sendo inseridos:

1: --Cria alguns departamentos.2: INSERT INTO department (dept_id, dept_name, no_of_emps)3: VALUES (10,'Márcio Novelli',0);4: 1 row created.