Primeiramente, aviso que sou novo em PL SQL, então nem engatinhando ainda estou.
Peguei um teste por aqui na empresa onde estou que me pediu para resolver o seguinte problema, uma trigger.
Esta trigger, dispara quando eu deleto informações de uma linha.
Esse problema, eu já consegui resolver via view, utilizando
INSTEAD OF
.Consegui deletar a linha sem problemas.
O que acontece agora é que meu superior disse que ainda há 3 formas de resolver isso.
A primeira seria essa via view.
A segunda, eu pesquisei e encontrei uma função chamada
PRAGMA AUTONOMOUS_TRANSACTION
.Vi em vários fóruns que depende para o que eu vou utilizar, e depende muito, melhor utilizar de outra forma.
De qualquer forma, é uma base de teste que estou utilizando aqui e gostaria de ver o que realmente acontece e o que realmente faz esse comando.
Minha trigger está desta forma:
CREATE OR REPLACE TRIGGER rcf_trg_exc_lin_decl
AFTER DELETE
ON imp_declaracoes_lin
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
CURSOR cur_linha_decl (pn_declaracao_lin_id
imp_declaracoes_lin.declaracao_lin_id%TYPE) IS
SELECT qtde
FROM imp_declaracoes_lin
WHERE declaracao_lin_id = pn_declaracao_lin_id;
vn_tp_declaracao_id imp_declaracoes.tp_declaracao_id%TYPE;
você_dsi imp_declaracoes.dsi%TYPE;
vn_antigo_consumo_id rcf_consumos.consumo_id%TYPE;
vn_novo_consumo_id rcf_consumos.consumo_id%TYPE;
vn_qtde imp_declaracoes_lin.qtde%TYPE;
BEGIN
IF (cmx_fnc_profile ('zzz') = 'S') OR (cmx_fnc_profile (yyy') = 'S' ) THEN
SELECT tp_declaracao_id,
dsi
INTO vn_tp_declaracao_id,
você_dsi
FROM imp_declaracoes
WHERE declaracao_id = :old.declaracao_id;
IF (cmx_pkg_tabelas.codigo (vn_tp_declaracao_id) IN ('16','17')) AND (você_dsi = 'N') THEN
BEGIN
OPEN cur_linha_decl(:old.declaracao_lin_id);
FETCH cur_linha_decl
INTO vn_qtde;
CLOSE cur_linha_decl;
SELECT antigo.consumo_id,
novo.consumo_id
INTO vn_antigo_consumo_id,
vn_novo_consumo_id
FROM rcf_consumos antigo,
rcf_consumos novo
WHERE antigo.nr_referencia = :old.declaracao_id
AND novo.estoque_movimento_id = antigo.estoque_movimento_id
AND novo.saida_movimento_id = antigo.saida_movimento_id
AND novo.nr_referencia IS NULL;
UPDATE rcf_lancamentos
SET consumo_id = vn_novo_consumo_id
WHERE consumo_id = vn_antigo_consumo_id;
DELETE FROM rcf_consumos
WHERE consumo_id = vn_antigo_consumo_id;
UPDATE rcf_consumos
SET quantidade = quantidade+vn_qtde
WHERE consumo_id = vn_novo_consumo_id;
END;
END IF;
END IF;
COMMIT;
END rcf_trg_exc_lin_decl;
vn_tp_declaracao_id
e o você_dsi = S
.Como nem todas as linhas passam por essa parte e menos ainda pelos profiles zzz e yyy, então a maioria das linhas são deletadas normalmente, mas, algumas ficam travadas por estarem utilizando esses profiles e acabam entrando no cursor.
Quando eu tento deletar estas linhas, me dá erro de dados não encontrados(
ORA-01403: no data found
), mas, a linha está lá na tabela.Minhas dúvidas:
1) Está certo a forma de colocar o PRAGMA AUTONOMOUS_TRANSACTION?
2) Isso eu vou descobrir depois que colocar no lugar certo, mas, esse PRAGMA resolve o problema?
Obrigado pela ajuda,
Freidinger