我有一个Oracle触发器,它调用一个定义了PRAGMA AUTONOMOUS_TRANSACTION的存储过程。从触发器传递的值已经提交但似乎存储过程中的值不可用?我不是很肯定,因为调试/记录/提交的能力很难,输出的时间让我感到困惑。我想知道是否预期任何传递的值都可以在存储过程中使用,而不管AUTONOMOUS_TRANSACTION? 感谢
答案 0 :(得分:5)
作为参数传入存储过程的值始终可用于存储过程。使用自治事务声明过程无关紧要。
在自治事务中运行的代码无法查看调用事务所做的更改。 10次中有9次,当人们描述看到他们期望的数据的问题时,这就是问题的根源。
如果您的存储过程正在执行除了向日志表写入内容之外的任何操作,我将非常谨慎地使用自治事务。如果您使用自动事务来执行除日志记录之外的任何操作,则几乎肯定会错误地使用它们。而且你可能会引入一系列与竞争条件和交易完整性相关的错误。
答案 1 :(得分:0)
“触发逻辑是有条件的 更新表B调用 存储过程从中选择 表A中的值使表B可以 用计算值更新。 “
也许表B真的应该是从表A派生的物化视图?我们可以在填充MView的查询的WHERE子句中构建很多复杂性。 Find out more.
答案 2 :(得分:0)
如果table_x上有行级触发器,那么该触发器可以被同一语句多次触发,因为不同的行会受到该语句的影响。
这些行受影响的顺序是不确定的。因此,table_x的状态在行级触发器的执行期间是不确定的。这就是引发MUTATING TABLE异常的原因。
通过查看表的提交状态(即排除该语句所做的所有更改以及事务中的其他语句),自治事务“欺骗”。
如果您希望存储过程查看table_x的状态以响应该表上的活动,则需要在完成所有行更改后(即在语句级别触发器中,而不是行级别)完成触发)。
此设计模式通常是在行级别触发器中设置标志(包级别变量),检查AFTER语句级别触发器中的标志,并在必要时对其进行操作并重置它。