- Este tópico contém 30 respostas, 4 vozes e foi atualizado pela última vez 16 anos, 1 mês atrás por
burga.
-
AutorPosts
-
27 de janeiro de 2010 às 2:51 pm #92294
Girino
ParticipanteOlá..!! 8)
Já alterei o BEFORE conforme foi passado..!! 😉
CREATE OR REPLACE TRIGGER T_TERCEIRA
AFTER INSERT ON PCWMSOUTPUTBEGIN
FOR i IN 1 .. pack_estado_tab_1.nt_tab_1.count
LOOP
/*
— BEGIN
INSERT INTO “sh_pcwmsoutput”@logixteste –( tipo, numero, codprod, codcli, codfornec, codfilial,
–qtsep, qtrec, qtava, qtcor, dtemissao, semaforo,
–dtprocessamento, numlote, dtfabricacao,autonumerico)VALUES ( pack_estado_tab_1.nt_tab_1(i).tipo, pack_estado_tab_1.nt_tab_1(i).numero, pack_estado_tab_1.nt_tab_1(i).codprod, pack_estado_tab_1.nt_tab_1(i).codcli, pack_estado_tab_1.nt_tab_1(i).codfornec, pack_estado_tab_1.nt_tab_1(i).codfilial, pack_estado_tab_1.nt_tab_1(i).qtsep, pack_estado_tab_1.nt_tab_1(i).qtrec, pack_estado_tab_1.nt_tab_1(i).qtava, pack_estado_tab_1.nt_tab_1(i).qtcor, pack_estado_tab_1.nt_tab_1(i).dtemissao, pack_estado_tab_1.nt_tab_1(i).semaforo, pack_estado_tab_1.nt_tab_1(i).dtprocessamento, pack_estado_tab_1.nt_tab_1(i).numlote, pack_estado_tab_1.nt_tab_1(i).dtfabricacao, 0); -- END;*/
UPDATE PCWMSOUTPUT SET SEMAFORO = 3 WHERE numero = pack_estado_tab_1.nt_tab_1(i).numero; END LOOP;END;
[url=http://img707.imageshack.us/i/errooracle.jpg/:30qabbla]
💡
Se eu comentar o passo de inserção a trigger funciona e realiza o update.
Porém eu preciso primeiro inserir os dados e depois ralizar o update.Obrigado..!!
Renato
27 de janeiro de 2010 às 3:00 pm #92295burga
ParticipanteNeste caso, como você quer inserir em uma tabela via DBLink aí sim você deve utilizar PRAGMA AUTONOMOUS_TRANSACTION.
Mas o mas correto seria fazer uma procedure com o autonomous_transaction e com o insert dentro dela e chamar esta procedure pela trigger normal.
EDIT:
Dê uma checada também se o seu DBLink está funcionando. Pelo que parece é via HS certo? Veja se o driver ODBC também está ok…
27 de janeiro de 2010 às 3:14 pm #92297Girino
ParticipanteOlá Burga..!!
Tudo Bem? 😀O Erro sumiu após eu colocar novamento o PRAGMA AUTONOMOUS_TRANSACTION, porém está executando apenas o insert e o update ele não tá fazendo.
Nossa, to ficando doidinho 🙄 🙄 🙄Veja:
CREATE OR REPLACE TRIGGER T_TERCEIRA
AFTER INSERT ON PCWMSOUTPUT
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
FOR i IN 1 .. pack_estado_tab_1.nt_tab_1.count
LOOPBEGIN
INSERT INTO “sh_pcwmsoutput”@logixteste –( tipo, numero, codprod, codcli, codfornec, codfilial,
–qtsep, qtrec, qtava, qtcor, dtemissao, semaforo,
–dtprocessamento, numlote, dtfabricacao,autonumerico)VALUES ( pack_estado_tab_1.nt_tab_1(i).tipo, pack_estado_tab_1.nt_tab_1(i).numero, pack_estado_tab_1.nt_tab_1(i).codprod, pack_estado_tab_1.nt_tab_1(i).codcli, pack_estado_tab_1.nt_tab_1(i).codfornec, pack_estado_tab_1.nt_tab_1(i).codfilial, pack_estado_tab_1.nt_tab_1(i).qtsep, pack_estado_tab_1.nt_tab_1(i).qtrec, pack_estado_tab_1.nt_tab_1(i).qtava, pack_estado_tab_1.nt_tab_1(i).qtcor, pack_estado_tab_1.nt_tab_1(i).dtemissao, pack_estado_tab_1.nt_tab_1(i).semaforo, pack_estado_tab_1.nt_tab_1(i).dtprocessamento, pack_estado_tab_1.nt_tab_1(i).numlote, pack_estado_tab_1.nt_tab_1(i).dtfabricacao, 0); END; COMMIT; UPDATE PCWMSOUTPUT SET SEMAFORO = 3 WHERE numero = pack_estado_tab_1.nt_tab_1(i).numero; END LOOP; COMMIT;END;
27 de janeiro de 2010 às 4:48 pm #92301burga
ParticipanteNo seu caso nao utilize o pragma autonomous_transaction na trigger… deixe a trigger sem ele…
Faça uma procedure separada com o insert no dblink e na procedure vc define o pragma, e faz a trigger normal chamar a procedure…
o update continua na trigger, só o insert vai pra procedure…
27 de janeiro de 2010 às 5:01 pm #92302fsitja
ParticipanteA trigger ser before ou after não influencia nesse caso, mas poderia influenciar se houvesse outra trigger before que modificasse os valores de :new. Não há como ordenar a execução de múltiplas triggers com mesmo nível (before each row), a menos que seja no Oracle 11g.
O ideal é usar a After até porque na before não existe o rowid ainda e em alguns casos você vai querer guardar o rowid na package em vez de todas as colunas da tabela.
27 de janeiro de 2010 às 5:15 pm #92303Girino
ParticipanteOlá Burga..!! 8)
Tudo Bem?Ai volta no erro anterior de Mutant Trigger..!! 😥 😥 😥
Veja:
PROCEDURE:
CREATE OR REPLACE PROCEDURE P_ATUALIZA_SH_PCWMSOUTPUT
ISPRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
BEGIN
FOR R IN (SELECT TIPO,
NUMERO,
CODPROD,
CODCLI,
CODFORNEC,
CODFILIAL,
QTSEP,
QTREC,
QTAVA,
QTCOR,
DTEMISSAO,
SEMAFORO,
DTPROCESSAMENTO,
NUMLOTE,
DTFABRICACAO,0
FROM PCWMSOUTPUT
WHERE TIPO = ‘E’AND SEMAFORO = ‘1’)
LOOP
INSERT INTO “sh_pcwmsoutput”@logixteste VALUES (R.TIPO,
R.NUMERO,
R.CODPROD,
R.CODCLI,
R.CODFORNEC,
R.CODFILIAL,
R.QTSEP,
R.QTREC,
R.QTAVA,
R.QTCOR,
R.DTEMISSAO,
R.SEMAFORO,
R.DTPROCESSAMENTO,
R.NUMLOTE,
R.DTFABRICACAO,0);
END LOOP;
COMMIT;
END;EXCEPTION
WHEN OTHERS THEN
ROLLBACK;END;
TRIGGER:
CREATE OR REPLACE TRIGGER T_INSERT_SH_PCWMSOUTPUT
AFTER INSERT ON PCWMSOUTPUT FOR EACH ROWBEGIN
begin
— Call the procedure
p_atualiza_sh_pcwmsoutput;
end;BEGIN
UPDATE PCWMSOUTPUT
SET SEMAFORO = 3
WHERE TIPO = ‘E’ AND SEMAFORO = 1;
COMMIT;
END;EXCEPTION
WHEN OTHERS THEN
ROLLBACK;END;
[url=http://img210.imageshack.us/i/errooracle2.jpg/:21j5suip]
27 de janeiro de 2010 às 6:28 pm #92307burga
ParticipanteSó uma pergunta Renato…
O registro que você está tentando alterar no
UPDATE PCWMSOUTPUT
SET SEMAFORO = 3
WHERE TIPO = 'E' AND SEMAFORO = 1;é o mesmo que foi inserido ou podem ser alterados mais de um registro nesse comando?
ou nesse comando:
UPDATE PCWMSOUTPUT
SET SEMAFORO = 3
WHERE numero = pack_estado_tab_1.nt_tab_1(i).numero;A coluna número é PK da tabela ou tem unique constraint, ou de alguma forma o valor dela nunca se repete?
27 de janeiro de 2010 às 7:28 pm #92309Girino
ParticipanteOlá Burga..!! 8)
Quero alterar apenas o registro que esta sendo inserido.
Ou seja,
Insiro o valor 1 para o semafaro na Tabela PCWMSOUTPUT
Insiro os dados na tabela do dblink que esta no Informix sh_pcwmsoutput
Atualizo para 3 o semafaro da Tabela PCWMSOUTPUT
É isso..!!
Abraços..!! 😀
27 de janeiro de 2010 às 7:46 pm #92310burga
ParticipanteOpa então fica bem mais fácil…
você não precisa de 3 triggers e nem do pacote.
Apenas uma trigger e o procedimento de insert na tabela do dblink bastam.
Faça da seguinte maneira:
CREATE OR REPLACE TRIGGER T_INSERT_SH_PCWMSOUTPUT
AFTER INSERT ON PCWMSOUTPUT FOR EACH ROWBEGIN
p_atualiza_sh_pcwmsoutput;
:NEW.SEMAFORO := 3;
END;
Foi o meu primeiro exemplo desse tópico, e também a sugestão do Ishii…
27 de janeiro de 2010 às 7:56 pm #92311burga
ParticipanteMelhorando:
procedure:
CREATE OR REPLACE PROCEDURE P_ATUALIZA_SH_PCWMSOUTPUT (reg_pcwmsoutput IN pcwmsoutput%ROWTYPE)
ISPRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO "sh_pcwmsoutput"@logixteste VALUES (reg_pcwmsoutput.TIPO,
reg_pcwmsoutput.NUMERO,
reg_pcwmsoutput.CODPROD,
reg_pcwmsoutput.CODCLI,
reg_pcwmsoutput.CODFORNEC,
reg_pcwmsoutput.CODFILIAL,
reg_pcwmsoutput.QTSEP,
reg_pcwmsoutput.QTREC,
reg_pcwmsoutput.QTAVA,
reg_pcwmsoutput.QTCOR,
reg_pcwmsoutput.DTEMISSAO,
reg_pcwmsoutput.SEMAFORO,
reg_pcwmsoutput.DTPROCESSAMENTO,
reg_pcwmsoutput.NUMLOTE,
reg_pcwmsoutput.DTFABRICACAO,
0);
COMMIT;END;
trigger:
CREATE OR REPLACE TRIGGER T_INSERT_SH_PCWMSOUTPUT
BEFORE INSERT ON PCWMSOUTPUT FOR EACH ROW
DECLARE
l_reg_pcwmsoutput PCWMSOUTPUT%ROWTYPE;
BEGINl_reg_pcwmsoutput.TIPO := :NEW.TIPO;
l_reg_pcwmsoutput.NUMERO := :NEW.NUMERO;
l_reg_pcwmsoutput.CODPROD := :NEW.CODPROD;
l_reg_pcwmsoutput.CODCLI := :NEW.CODCLI;
l_reg_pcwmsoutput.CODFORNEC := :NEW.CODFORNEC;
l_reg_pcwmsoutput.CODFILIAL := :NEW.CODFILIAL;
l_reg_pcwmsoutput.QTSEP := :NEW.QTSEP;
l_reg_pcwmsoutput.QTREC := :NEW.QTREC;
l_reg_pcwmsoutput.QTAVA := :NEW.QTAVA;
l_reg_pcwmsoutput.QTCOR := :NEW.QTCOR;
l_reg_pcwmsoutput.DTEMISSAO := :NEW.DTEMISSAO;
l_reg_pcwmsoutput.SEMAFORO := :NEW.SEMAFORO;
l_reg_pcwmsoutput.DTPROCESSAMENTO := :NEW.DTPROCESSAMENTO;
l_reg_pcwmsoutput.NUMLOTE := :NEW.NUMLOTE;
l_reg_pcwmsoutput.DTFABRICACAO := :NEW.DTFABRICACAO;p_atualiza_sh_pcwmsoutput(l_reg_pcwmsoutput);
:NEW.SEMAFORO := 3;
END;
EDITADO:
Na trigger coloquei ela de AFTER… Corrigido pra BEFORE INSERT.EDIT2:
Indo pela sua lógica, você quer inserir um registro na tabela PCWMSOUTPUT com semaforo = 1.Replicar o registro pra tabela do dblink e depois atualizar o semaforo pra 3 para saber que o registro foi replicado com sucesso.
Existe um problema pro caso dessa trigger, ela sempre tentará inserir o registro na tabela do dblink antes de inserir na tabela do oracle então se der algum erro no insert do dblink, o registro também não irá pra tabela do Oracle. Isso tira todo objetivo do semaforo (caso o objetivo seja o mesmo da minha suposição).
Outro problema é no caso de inserir o registro com sucesso mas você efetuar um rollback. Lembrando que na tabela do dblink você já efetuou o commit, o rollback no Oracle vai ocasionar na dessincronização das duas tabelas, ou seja, o registro vai pra tabela do dblink mas nao vai existir na do Oracle.
Este é um dos problemas que pode ocorrer neste caso de sincronização síncrona de dados utilizando dblink e triggers. Você tem que ver se isto não vai gerar problemas futuros pra você…
27 de janeiro de 2010 às 8:10 pm #92312Girino
ParticipanteEntão Burga, to fazendo assim: 😀
Primeiro crio a Procedure:
CREATE OR REPLACE PROCEDURE P_ATUALIZA_SH_PCWMSOUTPUT
ISBEGIN
BEGIN
FOR R IN (SELECT TIPO,
NUMERO,
CODPROD,
CODCLI,
CODFORNEC,
CODFILIAL,
QTSEP,
QTREC,
QTAVA,
QTCOR,
DTEMISSAO,
SEMAFORO,
DTPROCESSAMENTO,
NUMLOTE,
DTFABRICACAO,0
FROM PCWMSOUTPUT
WHERE TIPO = ‘E’AND SEMAFORO = ‘1’)
LOOP
INSERT INTO “sh_pcwmsoutput”@logixteste VALUES (R.TIPO,
R.NUMERO,
R.CODPROD,
R.CODCLI,
R.CODFORNEC,
R.CODFILIAL,
R.QTSEP,
R.QTREC,
R.QTAVA,
R.QTCOR,
R.DTEMISSAO,
R.SEMAFORO,
R.DTPROCESSAMENTO,
R.NUMLOTE,
R.DTFABRICACAO,0);
END LOOP;
COMMIT;
END;EXCEPTION
WHEN OTHERS THEN
ROLLBACK;END;
Depois crio a Trigger:
CREATE OR REPLACE TRIGGER T_INSERT_SH_PCWMSOUTPUT
AFTER INSERT ON PCWMSOUTPUT FOR EACH ROWBEGIN
P_ATUALIZA_SH_PCWMSOUTPUT;
end;:NEW.SEMAFORO := 3;
END;
Mas tá dando erro na compilação da trigger..??? 🙄 🙄
Tenho que setar alguma coisa??? 💡
27 de janeiro de 2010 às 8:16 pm #92313fsitja
ParticipanteVocê tem um begin e 2 END;
BEGIN
P_ATUALIZA_SH_PCWMSOUTPUT;
end;:NEW.SEMAFORO := 3;
END;
Desculpa chover no desfile dos outros, mas eu não acho adequada essa solução com pragma autonomous_transaction na procedure por um motivo bem simples: se a transação der rollback por qualquer motivo de erro que ocorra na transação original, sua tabela “sh_pcwmsoutput”@logixteste ficará tomada de dados incorretos que não deveriam estar nela.
A transação lá é independente e a tabela remota vai ficar inconsistente com o estado da tabela na origem.
Resumindo, acho que o melhor é não fazer isso via trigger e sim controlar no procedimento de origem que está controlando a transação.
27 de janeiro de 2010 às 8:42 pm #92319burga
Participante[quote=”fsitja”:oeosjrse]Você tem um begin e 2 END;
BEGIN
P_ATUALIZA_SH_PCWMSOUTPUT;
end;:NEW.SEMAFORO := 3;
END;
Desculpa chover no desfile dos outros, mas eu não acho adequada essa solução com pragma autonomous_transaction na procedure por um motivo bem simples: se a transação der rollback por qualquer motivo de erro que ocorra na transação original, sua tabela “sh_pcwmsoutput”@logixteste ficará tomada de dados incorretos que não deveriam estar nela.
A transação lá é independente e a tabela remota vai ficar inconsistente com o estado da tabela na origem.
Resumindo, acho que o melhor é não fazer isso via trigger e sim controlar no procedimento de origem que está controlando a transação.[/quote]
Isto que eu falei no post anterior… Sobre o problema de dessincronização das tabelas… =]
Mas não se pode controlar no procedimento de origem, pela utilização do dblink.
O que pode ser feito é não utilizar integração de dados síncrona… Pelo menos não desta forma, com triggers…
27 de janeiro de 2010 às 8:58 pm #92321fsitja
ParticipanteAh foi mal, a página virou e eu não li atrás, agora vi seu post, deve ter sido o edit. Eu tava com a página aberta desde o almoço e não tinha dado tempo de responder. Falou Burga. 😀
27 de janeiro de 2010 às 9:17 pm #92327Girino
ParticipanteOlá Pessoal..!! 8)
Finalmente após as dicas e ajuda de todos consegui chegar a uma solução para o meu problema: 😀 😀
Criei 2 triggers, vejam:
Trigger_1:
CREATE OR REPLACE TRIGGER T_INSERT_SH_PCWMSOUTPUT_1
BEFORE INSERT ON PCWMSOUTPUT FOR EACH ROWBEGIN
:NEW.SEMAFORO := 3;
END;
Trigger_2:
CREATE OR REPLACE TRIGGER T_INSERT_SH_PCWMSOUTPUT_2
AFTER INSERT ON PCWMSOUTPUT FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
BEGIN
INSERT INTO “sh_pcwmsoutput”@logixteste VALUES(:new.tipo, :new.numero, :new.codprod, :new.codcli, :new.codfornec, :new.codfilial,
:new.qtsep, :new.qtrec, :new.qtava, :new.qtcor, :new.dtemissao, 3,
–:new.semaforo,
:new.dtprocessamento, :new.numlote, :new.dtfabricacao,0);COMMIT; — allowed only in autonomous triggers
END;EXCEPTION
WHEN OTHERS THEN
ROLLBACK;END;
Muito Obrigado Mesmo à Todos..!! 😉
Valeu pela Insistência..!! 😉Renato 8)
-
AutorPosts
- Você deve fazer login para responder a este tópico.

