Trigger em view

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Pessoal, uma dúvida.

Estive pesquisando sobre triggers "instead of" e vi que as mesmas são aplicadas a views. Porém acho que não compreendi corretamente o conceito, ou implementei algo de forma errada, por isso peço uma ajuda.

Tendo como base a estrutura abaixo:

Selecionar tudo

CREATE TABLE teste1
(
  campo1 VARCHAR2(50)
/
CREATE TABLE teste2
(
  campo2 VARCHAR2(50)
)
/
CREATE OR REPLACE VIEW vw_teste12 aS
SELECT t1.*
  FROM teste1 t1,
       teste2 t2
  WHERE t1.campo1 = t2.campo2
/
CREATE OR REPLACE TRIGGER trg_teste12
  INSTEAD OF INSERT OR UPDATE ON vw_teste12
  FOR EACH ROW
BEGIN
    Raise_Application_Error(-20001,'Disparando a trigger');
END;
)
Explicando melhor o que fiz, tenho duas tabelas e criei uma view que associa o valor entre elas, ou seja, só será exibido na view caso o valor exista em ambas as tabelas.

A minha necessidade é disparar uma trigger quando essa condição for atendida, por isso pensei em criar a trigger na view. Porém consigo inserir normalmente nas duas tabelas, com valores que atendem ao critério para ser exibido na view.

A minha dúvida é se o que quero fazer é possível, e caso sim, o que eu estou fazendo errado.

Obrigado.
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Oi jks1903,

Posso estar errado, mas creio que você não conseguirá efetuar operações DML (DELETE, INSERT, UPDATE) nesta view, uma vez que ela se trata de um JOIN entre duas tabelas ORACLE.

O que você pode fazer é criar uma trigger em cada uma das tabelas. A trigger de uma tabela deve verificar se existe registro correspondente na outra tabela, e talvez possa fazer alguma ação em caso positivo (ex: alimentar uma tabela de log, enviar email para usuário, etc).

Sua view não precisa de nenhuma trigger para funcionar. Basta você fazer um SELECT nesta view. Caso existam registros iguais, a view sempre retornará estes registros na querie.

Espero ter esclarecido sua dúvida,

Sergio Coutinho
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Eu executei aqui seu script e para mim e meu ambiente(10g) funcionou a validação. Levantou a exceção. (Só tive de ajustar os parentes e ponto-e-virgulas).

Não sei qual versão do banco você está utilizando. Segundo o TOM do 8 para trás as versões STANDARD não vinha com esta funcionalidade.

Resuminto o que está em http://psoug.org/reference/instead_of_trigger.html. A sugerida view para o INSTEAD OF NÃO pode ter:
- A set operator
- A DISTINCT operator
- An aggregate or analytic function
- A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
- A collection expression in a SELECT list
- A subquery in a SELECT list
- A subquery designated WITH READ ONLY
- Joins, with some exceptions, as documented in Oracle Database Administrator's Guide
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Pessoal, primeiramente obrigado pelas respostas.

Noctifero, eu estou utilizando a versão 10G, porém quando insiro dados em alguma das tabelas, de forma que a informação passe a ser exibida na view, não dispara a trigger. Como você fez o teste de inserção?

Caso não conseguir, de repente vou tentar criar duas triggers nas tabelas mesmo, como o stcoutinho sugeriu.

Vlw.
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Segui teu script(com ajustes dos parametros e ponto-e-virgula depois:

Selecionar tudo

insert into vw_teste12(campo1) values ('X');
Aí apareceu o erro "'Disparando a trigger'";
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Noctifero escreveu:Segui teu script(com ajustes dos parametros e ponto-e-virgula depois:

Selecionar tudo

insert into vw_teste12(campo1) values ('X');
Aí apareceu o erro "'Disparando a trigger'";
Ahh, então eu acho que minha concepção sobre o funcionamento das triggers INSTEAD OF está errado.

O que eu fiz foi inserir nas tabelas que são a "base" para a view. No momento da inserção nas tabelas, se a condição fosse atendida eu gostaria que disparasse a trigger da view. Dessa forma que eu tentei não é possível então com trigger a nível de view?
BCR
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 25
Registrado em: Qui, 22 Nov 2012 1:40 pm
Localização: Patos de Minas
Breno Cristovão Rocha.

até onde sei.... não é possível trigger em view não...
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Bem, a trigger foi criada para a VIEW.
Se você criou a trigger para view mas fez o insert na base table, a trigger da view não será disparada.
Será necessário criar a trigger da própria table.
O que você pode fazer, já que seria a "mesma trigger" para cada tabela é criar uma procedure e cada trigger chamar ela.
Lembrando que se você realizar consultas nas próprias tabelas durante a trigger , ocorrerá trigger mutante mas há contornos para isso(apesar deu aconselhar evitar ao máximo).
Avatar do usuário
gpilger
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 29
Registrado em: Qua, 21 Abr 2010 3:34 pm
Localização: Novo Hamburgo - RS
Gilson Pilger
"Por não saber que erra impossível, ele foi lá e fez" autor desconhecido

A trigger "instead of" é bem simples rapaziada.

Tu tem uma view com duas tabelas, e entre essa tabelas tu tem o join certo? Então tu tem uma view complexa.

Nesse caso, quando tu criar a trigger "instead of", ao invés de executar o INSERT na tabela, por exemplo, o oracle irá SUBSTITUÍLO pelo algoritimo que tu programou na trigger.

Seria tipo assim, o insert acontece na view MINHA_VIEW, mas como existe a trigger "INSTEAD OF", tu programa para que ela ocorra na tabela MINHA_TABELA.

Just it man! Espero ter me feito entender. =D
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Blza pessoal, eu estava confundindo um pouco o "funcionamento" das triggers instead of.

Ficou claro agora, obrigado pelas respostas.
Avatar do usuário
fbifabio
Moderador
Moderador
Mensagens: 199
Registrado em: Ter, 22 Fev 2011 1:51 pm
Localização: São Paulo - SP
Contato:
Fábio Prado
www.fabioprado.net

Pessoal,

A explicação do @gpilger foi muito boa e deu para entender que o problema do @jks1903 era apenas conceitual. Um trigger INSTEAD OF (que só se aplica em views) só serve para comandos DML executados na própria view, e não na tabela. Ele é uma espécie de gambiarra para contornar uma prática ruim!

É possível fazer INSERT, UPDATE e DELETE em visões, desde que ela seja uma visão simples, ou seja, desde que ela referencie apenas 1 tabelas e obedeça mais algumas regrinhas (por exemplo, não ter funções nos nomes das colunas que serão retornadas). A trigger INSTEAD OF serve p/ permitir INSERT, UPDATE e DELETE em visões complexas, mas não é uma boa prática executar estas operações em visões! A boa prática é só fazer SELECT em visões e se seguirmos essa boa prática nunca precisaremos deste tipo de trigger!

[]s
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 4 visitantes