- Este tópico contém 10 respostas, 4 vozes e foi atualizado pela última vez 9 anos atrás por Renato José Correia Lima.
-
AutorPosts
-
25 de junho de 2015 às 12:35 am #107587Paulo WerneckParticipante
Galera, boa tarde…
Alguém pode me dar uma força com uma trigger, pf…
Na trigger abaixo eu precisava que quando o botão sn fosse atualizado o usuário ficasse registrado.
create or replace trigger teste
after update of sn on testatrigger
FOR EACH ROW
begin
UPDATE testatrigger SET nome = user;
END;
/
vlw, abs!
26 de junho de 2015 às 5:43 pm #107591WenderParticipante@luckzin
Seguinte seu código de exemplo segue um exemplo que funcionaria para o que deseja, porém fiquei em uma dúvida, esta tabela terá apenas um registro. A função da trigger sempre será um update sem where?
De qualquer forma segue abaixo:
create or replace
trigger teste
after update of sn
on testatrigger
beginupdate testatrigger
set nome = sys_context('USERENV','SESSION_USER');end;
/Basta substituir o user pela função sys_context passando o parâmetro. Apenas uma observação que se tentar por exemplo utilizar where pelo sn onde terá que utilizar por exemplo:
referencing new as new old as old
for each rowNeste caso irá retornar o erro “ORA-04091: table name is mutating, trigger/function may not see it.”, para resolver este problema terá que utilizar:
declare
pragma autonomous_transaction;Este irá fazer com que a trigger seja uma transação independente, porém utilize o commit ao final da trigger.
30 de junho de 2015 às 6:12 pm #107603Paulo WerneckParticipante@Wender
Obrigado a ajuda, mas acho que ainda estou errando em alguma coisa.
rodei a trigger da seguinte forma:
CREATE OR REPLACE TRIGGER TESTE
AFTER UPDATE OF SN ON TESTATRIGGER
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE TESTATRIGGER SET NOME = sys_context('USERENV','SESSION_USER');
END;
/
Depois eu tento realizar o seguinte update:
UPDATE TESTATRIGGER SET SN = 'S' WHERE COD = 1;
E me gera o seguinte erro:
ORA-00060: deadlock detected while waiting for resource
ORA-06512: at “DBAMV.TESTE”, line 4
ORA-04088: error during execution of trigger ‘DBAMV.TESTE’
00060. 00000 – “deadlock detected while waiting for resource”
*Cause: Transactions deadlocked one another while waiting for resources.
*Action: Look at the trace file to see the transactions and resources
involved. Retry if necessary.30 de junho de 2015 às 9:43 pm #107604WenderParticipante@luckzin
A forma que esta sendo feito o update não precisa utilizar:
referencing new as new old as old
for each rowe nem a declaração
declare
pragma autonomous_transaction;Apenas crie a trigger da seguinte maneira:
create or replace
trigger teste
after update of sn
on testatrigger
beginupdate testatrigger
set nome = sys_context('USERENV','SESSION_USER');end;
/Ocorre que quando utiliza for each row ele irá tentar fazer a ação no begin para os registros, como um update disparou a trigger, a sessão está com este registro aberto.
30 de junho de 2015 às 10:20 pm #107605rmanParticipante@luckzin
Faltou o COMMIT após o UPDATE.
30 de junho de 2015 às 10:40 pm #107606Paulo WerneckParticipante@Wender
Mas como eu faço pra atualizar pela trigger apenas o campo com o COD = 1 que foi definido no update?
30 de junho de 2015 às 11:26 pm #107607WenderParticipante@rman
Neste caso não é necessário de commit dentro do corpo da trigger a não ser que seja utilizado
declare
pragma autonomous_transaction;Então quem faz o commit? Quando uma sessão executar um comando update a mesma também irá disparar a trigger, logo quando esta sessão fizer o commit automaticamente a trigger será feito o commit, pois faz parte da transacação.
http://bennettgolfcars.ca/upfile/manufile/20130125_22_25_06.pdf
Pagina 457 do livro OCA Oracle Database 11g : Administration I Exam Guide.
Porém colocar o commit dentro do bloco begin da trigger não irá ocorrer qualquer erro, é mais uma forma de organização/construção dos códigos PL/SQL.
🙂1 de julho de 2015 às 12:34 am #107608WenderParticipante@luckzin
Deixa entender, você quer que a trigger seja disparada apenas quando cod=1 ?
1 de julho de 2015 às 12:53 am #107609Paulo WerneckParticipante@Wender
Quero que ela seja disparada apenas para o registro que eu fizer o update.
no exemplo tava usando cod=1, então queria que disparasse para esse registro.
Se fosse cod=2 dispararia para o registro que faz referencia ao código 2.UPDATE TESTATRIGGER SET SN = 'S' WHERE COD = 1;
2 de julho de 2015 às 12:15 am #107610rmanParticipante@Wender
Exatamente, se trabalhar com autonomous_transaction é necessário o uso do COMMIT, caso contrario a transação ficará em aberto, isso causou o DEADLOCK.
Eu não recomendo o uso do autonomous_transaction.Prefiro trabalhar como você apresentou, deixar a transação original fazer o COMMIT/ROLLBACK.
4 de novembro de 2015 às 9:57 pm #107878Renato José Correia LimaParticipanteE porque não tratar no BEFORE e depois atribuir o valor diretamente ao campo.
CREATE OR REPLACE TRIGGER teste
BEFORE UPDATE OF sn
ON testatrigger
FOR EACH ROW
BEGIN
IF NVL (:OLD.sn, 'S') NVL (:NEW.sn, 'S')
THEN
:NEW.nome := USER;
END IF;
END;
/Att.
-
AutorPosts
- Você deve fazer login para responder a este tópico.