INSERT 触发器的替代方案

Joh*_*ohn 5 trigger oracle plsql

在 Oracle 中寻找示例代码来做同样的事情。IE

删除表 T1 上的插入触发器,其工作是基于派生数据在 T2 中创建一行。这个 PL-SQL api 会是什么样子?

通过替换插入触发器,我会在现实世界的应用程序中丢失什么?

基于以下响应的更多说明:我们不希望远程客户端同时写入表 T1 和 T2。这是一个高吞吐量的数据和性能将受到影响。因此远程客户端将只写入 T1。从 T1 转移到 T2 应该在本地发生。

Bil*_*hor 10

如果 T2 是基于 T1 内容的派生数据,那么您可能希望用物化视图替换 T2。如果 T2 很少被访问,并且快速派生,那么您可能只想使用视图。

在应用端,如果停止维护表T2,那么它得到的值将变得不正确。这可以通过重新计算派生值并用新值更新 T2 来部分纠正。


Lei*_*fel 8

这是替换触发器的 API 结构示例。通过调用包中的 AddEntry 过程,数据被插入到两个表中。

CREATE OR REPLACE PACKAGE MyPackage IS
   Procedure AddEntry (pValue1 IN Number, pValue2 IN Number);
END;
/


CREATE OR REPLACE PACKAGE BODY MyPackage IS
   Procedure AddEntry (pValue1 IN Number, pValue2 IN Number)
   As
   Begin
      INSERT INTO T1 ("ID1") VALUES (pValue1);
      INSERT INTO T2 ("ID2") VALUES (pValue2);
   End;
END;
/
Run Code Online (Sandbox Code Playgroud)

即使您认为视图或物化视图比将此数据复制到第二个普通表中更好,通过触发器切换到 API 也是一个好主意。

更新:

基于对问题的更改,表明希望提高插入 T1 表的性能,这里有一些选项。

  1. 按照 BillThor 的建议对 T2 使用物化视图。
  2. 创建 T2 作为 T1 的视图。
  3. 创建一个定期从 T1 合并到 T2 的作业。

一个更复杂的解决方案是使用具有缓冲消息传递功能的高级消息传递在队列中创建消息,而不是插入到表中。然后,您可以有一个作业定期将一堆消息出列并批量插入它们,或者在调用包以插入数据的队列上有一个回调。此解决方案可能具有最佳性能,但对于消息在内存中存储很短时间的服务器故障也最敏感。


Sco*_*her 6

似乎人们并没有真正解决您问题的第二部分,所以我想我会插话。

首先,我喜欢你问题的第 1 部分的两个答案。我认为物化视图或创建存储过程来管理插入到第二个表中是令人满意的(+1 对他们)。但是,我更喜欢使用存储过程的灵活性,并且相信对CRUD操作使用包/过程应该是处理与数据库结构的大多数交互的方式。您远离触发器的本能是一个很好的方法,换句话说 - 它们有其用途,但我认为它们倾向于通过将其放置在直接方法调用堆栈之外来模糊业务逻辑(如果您不知道触发器在那里,你可能没有意识到它的功能来自哪里)。

话虽如此,我继续你的问题的第二部分 - “在现实世界的应用程序中,我会在替换插入触发器时丢失什么?”

如果您将触发器替换为 CRUD 包,并且您没有控制所有用于插入数据库的输入路径,以便它们都使用该 CRUD 包,则您无法保证先前嵌入在插入触发器中的逻辑将在插入。

或者,如果您的触发器逻辑足够简单,可以替换为设置为在提交时更新的物化视图,那么您就不会遇到上述问题,并且可能根本看不到任何区别。