我希望在删除以下方法失败的数据后使用相同的表数据。
我遇到的问题是在触发器完成之前,最新的更改没有得到提交。
create table test_tbl(id_ number, type_ varchar2(100) , count_ number);
create table test_count_tbl(type varchar2(100), count_ number) ;
begin
insert into test_tbl(id_ , type_ , count_ ) values (1,'type1', 10 );
insert into test_tbl(id_ , type_ , count_ ) values (2,'type1', 20 );
insert into test_tbl(id_ , type_ , count_ ) values (3,'type2', 10 );
insert into test_tbl(id_ , type_ , count_ ) values (4,'type2', 40 );
insert into test_tbl(id_ , type_ , count_ ) values (5,'type3', 10 );
insert into test_tbl(id_ , type_ , count_ ) values (6,'type3', 60 );
commit;
end;
create or replace procedure test_count_update_p( p_type_ in varchar2)
is
begin
MERGE INTO test_count_tbl D
USING (select type_, sum(count_) count_sum_
from test_tbl
where type_ = p_type_
group by type_ ) S ON (D.type = S.count_sum_)
WHEN MATCHED THEN UPDATE SET D.count_ = S.count_sum_
-- DELETE WHERE (S.salary > 8000)
WHEN NOT MATCHED THEN INSERT (D.type, D.count_)
VALUES (S.type_, S.count_sum_);
commit;
end ;
CREATE OR REPLACE TRIGGER test_tbl_trigger
AFTER INSERT OR DELETE OR UPDATE ON test_tbl
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
L_TYPE VARCHAR2(100);
BEGIN
if DELETING THEN
L_TYPE := :OLD.TYPE_;
end if;
IF UPDATING OR INSERTING THEN
L_TYPE := :NEW.TYPE_;
end if;
test_count_update_p(L_TYPE);
COMMIT;
END;
执行以下操作以查看确切问题..
begin
insert into test_tbl(id_ , type_ , count_ ) values (7,'type4', 60 );
commit;
end;
select * from test_tbl ;
记录被插入到表中。
select * from test_count_tbl ;
记录在此表中尚未计入。
begin
delete test_tbl where id_ = 7;
commit ;
end;
select * from test_tbl ;
删除了记录。
select * from test_count_tbl ;
计算表test_tbl;
中没有的记录答案 0 :(得分:2)
你不能。
正常的行级触发器无法查询定义触发器的表,因为这会引发变异表异常。我假设这就是为什么你声明你的触发器使用自治事务(除了持久性日志之外的任何事情的自治事务几乎肯定是一个错误)。但是,如果这样做,则触发器无法看到触发事务所做的未提交更改。这就是你现在遇到的问题。
另一种方法是使用compound trigger。您将声明一个test_table.type_%type
的集合,您将在触发器的行级部分中添加更改为此集合的值,然后您将在after语句中迭代集合中的元素触发器的一部分。允许语句级触发器查询定义了触发器的表,以便可以从复合触发器的后语句部分调用过程。
答案 1 :(得分:0)
您的最佳操作是完全删除TEST_COUNT_TBL表。只需按名称创建一个视图:
create view TEST_COUNT_TBL as
select type_ Type, sum( count_ ) Count
from test_tbl
group by type_;
然后,您将始终掌握准确,最新的信息,但不必担心使用触发器做一些奇怪而美妙的事情。
答案 2 :(得分:0)
使用复合触发并删除PRAGMA AUTONOMOUS_TRANSACTION;以及删除的commit语句。仍然提交的数据可以在外部函数中访问和执行计算,并写入单独的表。