Oracle触发器自治事务缺少行

Oracle触发器自治事务缺少行,oracle,triggers,Oracle,Triggers,我有两个表格:交货记录和交货总结。我简化了表格来演示 select * from delivery_records FILTERLIST PRICE_DATE PRICE_VALUE ------------------------------------- FL_1 1/1/2015 1 FL_1 1/1/2015 2 FL_1 1/1/2015 3 FL_2 1/1/2015 8 FL_

我有两个表格:交货记录和交货总结。我简化了表格来演示

select *
from delivery_records

FILTERLIST   PRICE_DATE   PRICE_VALUE
-------------------------------------
FL_1         1/1/2015     1
FL_1         1/1/2015     2
FL_1         1/1/2015     3
FL_2         1/1/2015     8
FL_2         1/1/2015     9
我在插入或更新delivery_records上的每一行后都有一个触发器,它触发过程summary_records,以便在每次修改delivery_records表后立即更新delivery_摘要表

CREATE OR REPLACE TRIGGER SNAPSHOT_TRIG
  AFTER INSERT OR UPDATE ON DELIVERY_RECORDS FOR EACH ROW

Declare

    PRAGMA AUTONOMOUS_TRANSACTION;

BEGIN

    dbms_output.put_line('Starting trigger');

    SUMMARIZE_RECORDS(:new.filterlist, trunc(sysdate));

    COMMIT;

    dbms_output.put_line('Trigger ended');


EXCEPTION
    WHEN OTHERS THEN
            dbms_output.put_line('SQL Error: ' || SQLCODE || ' - ' || SUBSTR(SQLERRM, 1, 100));


END DELIV_SNAPSHOT_UPDATE;
过滤器列表是一组相关的交付记录。summary_records存储过程通过在delivery_records表上运行select,然后将结果插入delivery_summary表中,来汇总每个过滤器列表在每个日期的交付计数,我希望这会导致以下结果:

select * from delivery_summary

FILTERLIST DATE       DELIVERY_COUNT
------------------------------------
FL_1       1/1/2015   3
FL_2       1/1/2015   2
这正按预期工作,但触发器似乎缺少为每个filterlist插入的最后一条记录。就好像扳机没响一样。我做了一些研究,有人暗示自治事务无法查看当前事务的记录。这就是我看到的表,除非我运行某种不做任何更新来导致触发器再次触发

select * from delivery_summary

FILTERLIST DATE       DELIVERY_COUNT
------------------------------------
FL_1       1/1/2015   2
FL_2       1/1/2015   1
我的理解是,作为“after”触发器,该行对于我的摘要过程应该是可见的。我必须将该过程设置为pragma autonomy,因为我要在正在触发的表上进行选择。我知道这是禁忌,但这似乎是满足实时汇总表要求的唯一方法


有没有更好的方法来实现这一点?这似乎是触发器的完美用例

在这种情况下,我认为使用
自治\u事务
注释是错误的,因为:

在一次交易中,您正在更新
交货记录
和 您正在将该事务标记为已分离(使用pragma) 从中读取数据的自治(事务)
交货记录
,在中


因此,我不希望使用AUTONOMOUS_TRANSACTION,而是将过程代码放在触发器中,在触发器中直接计算所需的值并将其插入到
delivery_summary

中。在这种情况下,我认为使用
AUTONOMOUS_TRANSACTION
注释是错误的,因为:

在一次交易中,您正在更新
交货记录
和 您正在将该事务标记为已分离(使用pragma) 从中读取数据的自治(事务)
交货记录
,在中


因此,我不希望使用AUTONOMOUS_TRANSACTION,而是将过程代码放在触发器中,在触发器中直接计算所需的值并将其插入到
delivery_summary

中。在这种情况下,我认为使用
AUTONOMOUS_TRANSACTION
注释是错误的,因为:

在一次交易中,您正在更新
交货记录
和 您正在将该事务标记为已分离(使用pragma) 从中读取数据的自治(事务)
交货记录
,在中


因此,我不希望使用AUTONOMOUS_TRANSACTION,而是将过程代码放在触发器中,在触发器中直接计算所需的值并将其插入到
delivery_summary

中。在这种情况下,我认为使用
AUTONOMOUS_TRANSACTION
注释是错误的,因为:

在一次交易中,您正在更新
交货记录
和 您正在将该事务标记为已分离(使用pragma) 从中读取数据的自治(事务)
交货记录
,在中


因此,我不希望使用自治事务,而是将过程代码放在触发器中,直接计算所需的值并将其插入到
delivery\u summary
您可以使用语句触发器,即跳过每行的

在触发器中,您必须这样做(仅考虑更新):


但是,更好的解决方案是将所有这些放在存储过程中并调用此过程,而不是使用触发器。

您可以使用语句触发器,即跳过每行的

在触发器中,您必须这样做(仅考虑更新):


但是,更好的解决方案是将所有这些放在存储过程中并调用此过程,而不是使用触发器。

您可以使用语句触发器,即跳过每行的

在触发器中,您必须这样做(仅考虑更新):


但是,更好的解决方案是将所有这些放在存储过程中并调用此过程,而不是使用触发器。

您可以使用语句触发器,即跳过每行的

在触发器中,您必须这样做(仅考虑更新):


但是,更好的解决方案是将所有这些放在存储过程中,并调用此过程,而不是使用触发器。

使用视图可能比使用触发器维护摘要状态更容易。我支持使用视图或可能的物化视图的建议。这取决于delivery_records表的更新频率与delivery_summary表的查看频率。不幸的是,我遗漏了很多外围功能,所以这不是一个荒谬的长问题。在一个视图中,交付记录的数量与要报告和汇总的列数之间的差异无法提供所需的性能。并且某些列被冻结(未更新)为历史日期,以提供审核日志。一个视图不能提供这一点。@AndyIngraham-一个具体化的视图可以,但是是的,它取决于
摘要\u记录
正在做什么。当然,触发器有其自身的性能损失,特别是当您最终有多个插入试图更新同一个摘要时。无论如何,不,您插入的数据对于自治事务来说是不可见的,即使在后触发器中也是如此——这就是为什么它是自治的,就像
UPDATE delivery_summary
SET (FILTERLIST, DATE, DELIVERY_COUNT) = 
    (SELECT FILTERLIST, DATE, COUNT(*) 
    FROM delivery_records
    GROUP BY FILTERLIST, DATE);