create or replace
trigger addpagamento
after insert on marcacoes_refeicoes
for each row
declare
nmarcacaoa number;
ncartaoa number;
begin
select nmarcacao into nmarcacaoa from marcacoes_refeicoes where rownum < (select count(*) from marcacoes_refeicoes);
select ncartao into ncartaoa from marcacoes_refeicoes where rownum < (select count(*) from marcacoes_refeicoes);
insert_pagamentos(nmarcacaoa, ncartaoa); --this is a procedure
exception when others then
raise_application_error(-20001, 'Error in Trigger!!!');
end addpagamento;
当我尝试将insert语句运行到表“marcacoes_refeicoes”时,此过程会出错:就像表正在变异
create or replace
procedure insert_pagamentos
(nmarcacaoa in number, ncartaoa in number)
AS
BEGIN
insert into pagamentos (nmarcacao, datapagamento, ncartao) values (nmarcacaoa, sysdate, ncartaoa);
commit;
END INSERT_PAGAMENTOS;
答案 0 :(得分:1)
简短(过度简化)回答:
您无法修改更改表格的触发器中的表格。
答案很长:
http://www.oracle-base.com/articles/9i/mutating-table-exceptions.php有更深入的解释,包括如何解决问题的建议。
答案 1 :(得分:1)
你正在遇到变异表问题,因为你正在从同一个表中选择触发器,但你似乎想要做的事情没有意义。获取nmarcacaoa
和ncartaoa
值的查询将返回no_data_found
或too_many_rows
错误,除非在插入之前表格中只有2行:
select nmarcacao from marcacoes_refeicoes
where rownum < (select count(*) from marcacoes_refeicoes);
将返回除一个之外的所有行;因为你没有订购,被排除的那个将是随机的。虽然状态在触发器中是不确定的,但是你实际上并不存在多少行,并且它无论如何也不会让你进行此查询。无论如何,您通常无法获得单一价值,而且您实际想要的价值并不明显。
我只能想象您正在尝试使用当前插入的行中的值,并将它们放入单独的付款(pagamentos
)表中。如果是这样,有一个内置机制可以使用correlation names来执行此操作,这使您可以将新插入的行称为:new
(默认情况下):
create or replace
trigger addpagamento
after insert on marcacoes_refeicoes
for each row
begin
insert_pagamentos(:new.nmarcacaoa, :new.ncartaoa);
end addpagamento;
:new
指的是当前行,因此:new.nmarcacaoa
是要插入的nmarcacaoa
。您不需要(也不能)从表本身获取该值。 (即使使用建议的自治pragma,这将是一个单独的事务,并且无法看到新插入和未提交的数据)。
或者你可以直接插入;不确定程序在这里添加了什么:
create or replace
trigger addpagamento
after insert on marcacoes_refeicoes
for each row
begin
insert into pagamentos(nmarcacao, datapagamento, ncartao)
values (:new.nmarcacaoa, sysdate, :new.ncartaoa);
end addpagamento;
我已经删除了异常处理程序,因为它所做的只是屏蔽了真正的错误,这是无用的。
答案 2 :(得分:0)
根据以下评论编辑此答案:
您可以使用PRAGMA AUTONOMOUS_TRANSACTION来消除错误,但不要使用它,因为它不会解决任何目的。
使用PRAGMA AUTONOMOUS_TRANSACTION:
create or replace
trigger addpagamento
after insert on marcacoes_refeicoes
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION;
nmarcacaoa number;
ncartaoa number;
begin
select nmarcacao into nmarcacaoa from marcacoes_refeicoes where rownum < (select count(*) from marcacoes_refeicoes);
select ncartao into ncartaoa from marcacoes_refeicoes where rownum < (select count(*) from marcacoes_refeicoes);
insert_pagamentos(nmarcacaoa, ncartaoa); --this is a procedure
exception when others then
raise_application_error(-20001, 'Error in Trigger!!!');
end addpagamento;
但是在这种情况下,select count(*) from marcacoes_refeicoes
会在当前插入表格后为您提供新的计数。