我需要创建一个触发器,每当您对表中的列进行更新时,他都会验证是否符合要求。 我创建了这个触发器:
create or replace trigger trg_utente_activo
before update of idestado on utente
for each row
when (new.idestado = 3)
declare
ex_analises_geneticas EXCEPTION;
flag boolean :=true;
/*Vai buscar todas as analises obrigatorias*/
cursor AnObri is
select an_ob.codAnalise
from AnalisesObrigatorias an_ob,analise a, tipoanalise ta
where an_ob.codanalise like a.codanalise
and a.idtipoanalise like ta.idtipoanalise
and ta.TipoAnaliseEnum like 3
order by an_ob.codAnalise;
AnalisesObrig AnObri%rowtype;
/*Vai buscar todas as analises obrigatorias que o utente fez*/
cursor AnObriUtent is
select distinct req_a.codanalise
from analise a,utente u,requisicao req,requisicao_analise req_a,analisesobrigatorias an_obr,tipoanalise ta
where :new.idutente=req.idutente
and :new.idutente=u.idutente
and an_obr.tipoutente=u.tipoutente
and an_obr.codAnalise=a.codAnalise
and req_a.codanalise=a.codanalise
and ta.idtipoanalise=a.idtipoanalise
and ta.TipoAnaliseEnum = 3
order by (req_a.codanalise);
Analise AnObriUtent%ROWTYPE;
begin
open AnObri;
open AnObriUtent;
loop
fetch AnObri into AnalisesObrig;
fetch AnObriUtent into Analise;
if (Analise.codAnalise not like AnalisesObrig.codAnalise) then
dbms_output.put_line(AnalisesObrig.codAnalise);
flag:=false;
dbms_output.put_line('flag ' || sys.diutil.bool_to_int(flag));
else
dbms_output.put_line(AnalisesObrig.codAnalise || '-' || Analise.codAnalise);
dbms_output.put_line('flag ' || sys.diutil.bool_to_int(flag));
end if;
end loop;
if (flag = true) then
update utente ut
set ut.idestado = :new.idestado
where idutente = idutente;
else
raise ex_analises_geneticas;
end if;
close AnObriUtent;
close AnObri;
EXCEPTION
WHEN ex_analises_geneticas THEN
RAISE_APPLICATION_ERROR (-20001,'O utente não realizou todas as analises geneticas');
END;
/
更新查询:
update utente
set idestado=3
where idutente=1;
但是请给我这个错误信息:
ORA-06512: na "BD1415_DK9.TRG_UTENTE_ACTIVO", linha 12
ORA-06512: na "BD1415_DK9.TRG_UTENTE_ACTIVO", linha 27
ORA-04088: erro durante a execução do trigger 'BD1415_DK9.TRG_UTENTE_ACTIVO'
(ORA-04088: error during execution)
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"
我尝试使用 pragma autonomous_transaction 但是给我错误 任何人都可以帮助我吗?
答案 0 :(得分:0)
您的触发器正在更新utente.idestado
,但它包含对同一列的更新,这意味着,如果验证通过,您将进入无限循环,即您的触发器将执行更新将触发触发器,触发器将执行更新,触发触发器等等...
你确定你不需要这样做:
create or replace trigger trg_utente_activo before update of idestado on utente
for each row
when (new.idestado = 3)
declare
ex_analises_geneticas EXCEPTION;
flag boolean :=true;
/*Vai buscar todas as analises obrigatorias*/
cursor AnObri is
select an_ob.codAnalise
from AnalisesObrigatorias an_ob,analise a, tipoanalise ta
where an_ob.codanalise like a.codanalise
and a.idtipoanalise like ta.idtipoanalise
and ta.TipoAnaliseEnum like 3
order by an_ob.codAnalise;
AnalisesObrig AnObri%rowtype;
/*Vai buscar todas as analises obrigatorias que o utente fez*/
cursor AnObriUtent is
select distinct req_a.codanalise
from analise a,utente u,requisicao req,requisicao_analise req_a,analisesobrigatorias an_obr,tipoanalise ta
where :new.idutente=req.idutente
and :new.idutente=u.idutente
and an_obr.tipoutente=u.tipoutente
and an_obr.codAnalise=a.codAnalise
and req_a.codanalise=a.codanalise
and ta.idtipoanalise=a.idtipoanalise
and ta.TipoAnaliseEnum = 3
order by (req_a.codanalise);
Analise AnObriUtent%ROWTYPE;
begin
open AnObri;
open AnObriUtent;
loop
fetch AnObri into AnalisesObrig;
fetch AnObriUtent into Analise;
if (Analise.codAnalise not like AnalisesObrig.codAnalise) then
dbms_output.put_line(AnalisesObrig.codAnalise);
flag:=false;
dbms_output.put_line('flag ' || sys.diutil.bool_to_int(flag));
else
dbms_output.put_line(AnalisesObrig.codAnalise || '-' || Analise.codAnalise);
dbms_output.put_line('flag ' || sys.diutil.bool_to_int(flag));
end if;
end loop;
if (flag = false) then
raise ex_analises_geneticas;
end if;
close AnObriUtent;
close AnObri;
EXCEPTION
WHEN ex_analises_geneticas THEN
RAISE_APPLICATION_ERROR (-20001,'O utente não realizou todas as analises geneticas');
END;
/