Trigger de Delete

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
rhicky
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 20 Jul 2007 9:48 am
Localização: S. J. do Rio Preto/SP
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
Jota
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 77
Registrado em: Qua, 17 Jun 2009 3:18 pm
Localização: Blumenau - SC
Jonatas Jaqmam Pereira
Analista Desenvolvedor de Sistemas

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.
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

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.
rhicky
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 20 Jul 2007 9:48 am
Localização: S. J. do Rio Preto/SP
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
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

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.
rhicky
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 20 Jul 2007 9:48 am
Localização: S. J. do Rio Preto/SP
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 ?
anderson.silva
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 35
Registrado em: Sex, 20 Abr 2012 10:51 am

Boa tarde!

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

At,
Anderson A Silva
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

O usuário que executa os comandos normalmente é o mesmo que dispara a trigger?Possui os grants corretos do DBlink?
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

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
rhicky
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 20 Jul 2007 9:48 am
Localização: S. J. do Rio Preto/SP
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 ?
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

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
rhicky
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 20 Jul 2007 9:48 am
Localização: S. J. do Rio Preto/SP
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 ?
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

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
rhicky
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 20 Jul 2007 9:48 am
Localização: S. J. do Rio Preto/SP
Rhicky

ok, problema resolvido.

Faltava o ; no final
Responder
  • Informação
  • Quem está online

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