Página 1 de 1

Trigger de Delete

Enviado: Seg, 11 Jun 2012 11:12 pm
por rhicky
Pessoal,
Conforme demonstro abaixo, estou tentando criar uma trigger de exclusão. Já incluí ela no banco de dados. Porém quando executo o procedimento nada acontece, ou seja, o registro não é excluído e também o Oracle não emite mensagens de erro. O que pode estar ocorrendo ?

Selecionar tudo

create or replace trigger trg_exc
  before delete on func
  for each row

begin

delete from func
where registro = :old.registro
and empresa = (select replace(replace(replace(cgc, '.', ''), '/', ''), '-', '') from filial where codfilial =:old.codfilial and codempresa =:old.codempresa);

end trg_exc

Re: Trigger de Delete

Enviado: Ter, 12 Jun 2012 8:13 am
por Jota
Bom dia,

Não entendi essa sua trigger.

Você tem uma trigger na tabela func, para ao deletar um funcionário, disparando um delete novamente na trigger?

Se a trigger já é chamada por um delete, não vejo razão de ela existir.

Re: Trigger de Delete

Enviado: Ter, 12 Jun 2012 9:41 am
por Trevisolli
Bom dia brothers, beleza?
Cara, está realmente meio confuso, ao deletar o registro, disparar um trigger para deletá-lo.

Pelo pouco que vi do código, talvez você só pudesse deixar deletar se o funcionário for da filial da empresa.

Desta forma, o teu trigger de before delete poderia existir apenas um select validando isso e um raise, caso não corresponda ao retorno, pois o delete vai ser feito pela transação na tabela, e não um delete no trigger.

Porém, não sei se é isso que entendi.

qualquer coisa, manda pra gente.

Re: Trigger de Delete

Enviado: Ter, 12 Jun 2012 10:38 am
por rhicky
Esta trigger, na verdade precisa excluir um registro que está em outro schema, através de conexão databaselink. A conexão em si já está pronta e funcionando. O código inicial é apenas uma ilustração. Segue abaixo o código mencionando o databaselink:

Selecionar tudo

create or replace trigger trg_exc
before delete on func
for each row

begin

delete from func@OUTRO_SCHEMA
where registro = :old.registro
and empresa = (select replace(replace(replace(cgc, '.', ''), '/', ''), '-', '') from filial where codfilial =:old.codfilial and codempresa =:old.codempresa);

end trg_exc

Re: Trigger de Delete

Enviado: Ter, 12 Jun 2012 2:55 pm
por Trevisolli
Brother,

Já testou se este trecho traz informação?

Selecionar tudo

 (select replace(replace(replace(cgc, '.', ''), '/', ''), '-', '') from filial where codfilial =:old.codfilial and codempresa =:old.codempresa);
Caso traga, trocando este trecho pelo valor retornado, no delete do dblink, traz algo ??

Selecionar tudo

select * from func@OUTRO_SCHEMA
where registro = ld.registro
and empresa = ValorRetornado;
Você tentou fazer um debug em alguma ferramenta, pra ver se ele passa por ai?

qualquer coisa manda ai.

Re: Trigger de Delete

Enviado: Ter, 12 Jun 2012 10:40 pm
por rhicky
Realizei os testes indicatos e nas duas situações o sistema retorna valor normalmente.
Alguma outra sugestão ?

Referente ao debug com alguma ferramenta, não tenho conhecimento sobre isso. Por favor, poderia indicar o caminho para tal ? há algum post ou site que explique como fazer isso ?

Re: Trigger de Delete

Enviado: Qui, 14 Jun 2012 1:47 pm
por anderson.silva
Boa tarde!

Sua trigger 'before delete' não acusa alguma restrição de integridade?
Tentou 'after delete'?

At,
Anderson A Silva

Re: Trigger de Delete

Enviado: Qui, 14 Jun 2012 2:53 pm
por DanielNN
O usuário que executa os comandos normalmente é o mesmo que dispara a trigger?Possui os grants corretos do DBlink?

Re: Trigger de Delete

Enviado: Sex, 15 Jun 2012 1:57 am
por stcoutinho
Ola Ricky,

Não recomendo muito o método de uma trigger DML disparando um comando via DBLINK. Você sempre estará sujeito à problemas de comunicação entre as duas instâncias.

Imagine o que aconteceria se a instância remota caisse ou a rede ficasse fora do ar. Seu DELETE não funcionaria e isso talvez impactasse em na aplicação que executasse esta operação.

Uma pergunta meio boba: você está executando COMMIT após este comando de DELETE? Porque estamos falando de um DBLINK que acessa uma outra instância. Se você não deu COMMIT, não adiantaria nada você abrir uma sessão na outra instância para verificar se o registro foi deletado lá.

Uma alternatica para evitar estas operações de trigger+dblink pode ser vista em :
http://glufke.net/oracle/viewtopic.php?f=2&t=8573

Abraços e boa sorte,

Sergio Coutinho

Re: Trigger de Delete

Enviado: Sex, 15 Jun 2012 10:43 pm
por rhicky
Pessoal,

Tentei simplificar o teste. Agora estou com a seguinte trigger:

Selecionar tudo

create or replace trigger trg_func_exclui
  after delete on pfunc
  for each row

begin

delete from JR.FPG_FUNCIONARIO@BASEDBLINK
where registro = '9999999'
and empresa = '45384096000509'

end trg_func_exclui;

Ao executar o processo o erro que aparece é o seguinte:


Erro ao excluir os registros da tabela PFUNC.
Verifique as tabelas relacionadas.

ORA-04098: gatilho 'RM.TRG_FUNC_EXCLUI' é inválido e a revalidação falhou
Funcionário: 9999999
O processo de exclusão de funcionário encontrou um erro e não pode continuar.
Todo o processo de exclusão será desfeito.
ORA-04098: gatilho 'RM.TRG_FUNC_EXCLUI' é inválido e a revalidação falhou

O que pode ser isso ?

Re: Trigger de Delete

Enviado: Sex, 15 Jun 2012 11:51 pm
por stcoutinho
Olá Ricardo,

Isso significa que a sua TRIGGER apresenta erros de compilação e se encontra com o status INVALID.
Para constatar isso, basta se conectar como RM e fazer um:

Selecionar tudo

SELECT OBJECT_NAME,OBJECT_TYPE,STATUS 
   FROM USER_OBJECTS 
 WHERE OBJECT_TYPE = 'TRIGGER' 
     AND OBJECT_NAME = 'TRG_FUNC_EXCLUI'  
Este erro postado por você ocorre porque, quando executa o DELETE, o ORACLE tenta revalidar a trigger antes de completar a operação DML. Como se trata de algum erro fatal, daí o motivo da mensagem de erro ORA-04098.

Você pode tentar recompilar a TRIGGER e verificar as mensagens de erro.
Conecte-se como RM e execute :

Selecionar tudo

ALTER TRIGGER TRG_FUNC_EXCLUI  COMPILE;

SHOW ERRORS;


Estes comandos devem lhe mostrar a mensagem de erro durante a compilação.

Poste ela aqui no FORUM, caso não saiba como proceder.

E se identificar o erro e souber corrigir, não se esqueça de postar aqui.

Abraços,

Sergio Coutinho

Re: Trigger de Delete

Enviado: Seg, 18 Jun 2012 11:28 am
por rhicky
Segui as orientações recomendadas, porém, na linha "SHOW ERRORS;", o oracle apresenta a seguinte mensagem:

ORA-00900: instrução SQL inválida

Como resolver isso ?

Re: Trigger de Delete

Enviado: Seg, 18 Jun 2012 10:55 pm
por stcoutinho
Ricardo,

Você executou o comando "SHOW ERRORS" no SQL*Plus?

Só pra ter certeza, abra novamente uma sessão no SQL*Plus com o usuário RM (tem que ser o SQL*Plus) e execute os comandos abaixo:

Selecionar tudo

ALTER TRIGGER TRG_FUNC_EXCLUI  COMPILE;

SHOW ERRORS TRIGGER TRG_FUNC_EXCLUI;
Se continuar o mesmo erro, esclareço que ORA-09000 indica um comando não reconhecido pelo PL/SQL.

Não sei se a TRIGGER que você monstra no tópico corresponde 100% à existente na sua base de dados, mas informo que instruções dentro do PL/SQL sempre terminam com PONTO-E-VIRGULA. O seu comando DELETE parece não finalizar com ";".

Algumas verificações adicionais que você pode fazer para verificar se não é nenhum problema de DBLINK.

Selecionar tudo

SELECT SYSDATE FROM DUAL@BASELINK;

SELECT COUNT(*) FROM JR.FPG_FUNCIONARIO@BASEDBLINK;
Abraços e boa sorte,

Sergio Coutinho

Re: Trigger de Delete

Enviado: Sex, 22 Jun 2012 11:23 pm
por rhicky
ok, problema resolvido.

Faltava o ; no final