Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Prezados, boa tarde. Estou começando a criar as minhas primeiras triggers e estou tendo algumas dificuldades. Na trigger abaixo, estou tentando atualizar uma tabela com dados que estou incluindo na tabela validada pela trigger, e é por isso que o oracle me apresenta o erro ORA-06512. Peço a juda de vocês para me orientar a como proceder nesse caso. Fico no aguardo. Desde já agradeço.
CREATE OR REPLACE TRIGGER dbamv.hfr_atualiza_previsao_alta
AFTER INSERT OR UPDATE ON dbamv.registro_resposta
REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
DECLARE
Documento NUMBER;
Atendimento NUMBER;SELECT
Count(*) INTO Documento
FROM
dbamv.registro_documento
WHERE cd_documento = 903
AND cd_registro_documento = Nvl(:NEW.cd_registro_documento,
:OLD.cd_registro_documento);
SELECT cd_atendimento INTO AtendimentoIF ( Documento > 0 ) THEN
UPDATE dbamv.atendime
SET dt_prevista_alta = (SELECT To_Date(ds_resposta, 'dd/mm/rrrr')
FROM dbamv.registro_resposta
WHERE cd_pergunta_doc = 36860
AND cd_registro_documento =
Nvl(:NEW.cd_registro_documento,
:OLD.cd_registro_documento))
WHERE cd_atendimento = Atendimento;
END IF;
END;ORA-04091: table DBAMV.REGISTRO_RESPOSTA is mutating, trigger/function may not see it
ORA-06512: at "DBAMV.HFR_ATUALIZA_PREVISAO_ALTA", line 28
ORA-04088: error during execution of trigger 'DBAMV.HFR_ATUALIZA_PREVISAO_ALTA'
É essa aí a lista completa do erro.
table DBAMV.REGISTRO_RESPOSTA is mutating, trigger/function may not see it
A tabela "mutante" , a tabela que é alvo da trigger tem restrições de sua leitura.
Pq a leitura
SELECT To_Date(ds_resposta, 'dd/mm/rrrr')
FROM dbamv.registro_resposta
WHERE cd_pergunta_doc = 36860
AND cd_registro_documento = Nvl(:NEW.cd_registro_documento, :OLD.cd_registro_document
é feita ? O registro posicionado (new/old) não atende ?
caso precise ler existem soluções para este problema
Porque essa tabela possui chave primária composta, então são inseridos vários registros de uma só vez. Eu preciso pegar apenas o valor de um dos registros. Sabe me dizer como faço?
Não entendi mas faz um chinês do que precisa, quem sabe te ajudo.
Deixa eu tentar te explicar. A tabela registro_documento grava todos os documentos criados no sistema. E a tabela registro_resposta, é a tabela onde armazeno os valores das perguntas da tabela registro_documento. Como tenho várias perguntas em um mesmo documento, quando crio um documento, o sistema faz vários inserts na tabela registro_resposta sendo que o campo cd_registro_documento é o mesmo, alterando somente o código da pergunta(cd_pergunta_doc). Eu preciso de pegar o valor de uma das perguntas e atualizar em outra tabela. Conseguir explicar???
CREATE OR REPLACE TRIGGER dbamv.hfr_atualiza_previsao_alta
AFTER INSERT OR UPDATE ON dbamv.registro_resposta
REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
DECLARE
Documento NUMBER;
Atendimento NUMBER;SELECT cd_atendimento INTO Atendimento
FROM
dbamv.registro_documento
WHEREcd_documento = 903
AND cd_registro_documento = Nvl(:NEW.cd_registro_documento,
:OLD.cd_registro_documento);
IF ( Documento > 0 ) THEN
UPDATE dbamv.atendime
SET dt_prevista_alta = NEW.ds_resposta
WHERE cd_atendimento = Atendimento;
END IF;
END;Não resolve. Não vai saber de qual pergunta ele vai pegar a resposta. Precisaria setar o campo, aí sim daria certo.
Ainda não entendi o motivo de ser a mesma tabela que está se alterando, este é problema da trigger.
Você tem os dados do registro corrente (old e new).
Motta, informo que consegui resolver. Era só setar o cd_pergunta_doc no if. Vacilo de iniciante mesmo. No final a trigger ficou assim.
CREATE OR REPLACE TRIGGER dbamv.hfr_atualiza_previsao_alta
AFTER INSERT OR UPDATE
ON dbamv.registro_resposta
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
CURSOR cDocumento IS
SELECT
cd_documentoCURSOR cAtendimento IS
SELECT
cd_atendimentoCURSOR cConfiguracao IS
SELECT
valor cd_configuracao = 3353;
Valor VARCHAR2(4000);
Documento NUMBER;
Atendimento NUMBER;
BEGIN
OPEN cDocumento;
FETCH cDocumento INTO Documento;
CLOSE cDocumento;
OPEN cAtendimento;
FETCH cAtendimento INTO Atendimento;
CLOSE cAtendimento;
OPEN cConfiguracao;
FETCH cConfiguracao INTO Valor;
CLOSE cConfiguracao;
IF ( Valor = 'S' AND Documento = 903 AND Nvl(:NEW.cd_pergunta_doc,:OLD.cd_pergunta_doc) = 36860) THEN
UPDATE dbamv.atendime SET dt_prevista_alta = To_Date(Nvl(:NEW.ds_resposta,:OLD.ds_resposta),'dd/mm/rrrr') WHERE cd_atendimento = Atendimento;
END IF;
END;
/
A parte em ítalico que foi o "X" da questão. Cara muito obrigado pela ajuda. Prometo que trarei problemas mais difíceis da próxima vez... rsrs.
Vlw.
Beleza.
Passe a lista completa do erro.