我有一个包将在一个表中插入单个父记录,而在另一个表中的依赖子记录在parent_id上具有FK。这些函数中的每一个都将由外部程序调用,并且所有插入子代的调用可能不包含在同一事务中。
我想知道我是否有办法避免手动跟踪parent_id并在每个过程的参数列表中传递它。我考虑过使用sys_context,但不认为这样可行,因为它不会出现在单个事务中。
是否还有其他策略或我是否需要将其吸收并将parent_id传递给每个方法?
答案 0 :(得分:3)
您可以使用这样的包变量:
package body mypackage is
g_parent_id integer;
procedure insert_parent (...)
is
begin
insert into parent (...) values (...)
returning id into g_parent_id;
end;
procedure insert_child (...)
is
begin
insert into child (parent_id, ...) values (g_parent_id, ...);
end;
end;
只要数据库连接存在,包变量就会一直存在。这在像web应用程序这样的无状态环境中不起作用。
那就是说,我赞成通过每次传递ID来保持程序模块化。这样就不会发生任何意外情况。
答案 1 :(得分:1)
关键问题是您的呼叫应用程序中的会话是否合并,或“粘性”。
如果外部程序为每个事务重用相同的连接/会话,那么将parentId存储在包变量中就可以了。
如果你有连接池,那么使用包变量开始变得棘手/危险。
如果插入子项的调用是在另一个事务中,并且您有连接池,我看不出您可以避免告诉第二个事务所需的parentId。
警告:如果你更关心的是简化包的API而不是性能,那么你就有了这些方面的东西。 。 。
对于外部应用程序中的每个数据库调用,将唯一标识调用进程的内容设置为SYS_CONTEXT或包变量(我们有这样的东西,以便我们可以派生调用方法和'真实'而不是池化d / b用户)。
根据此唯一标识符和时间在父表上创建辅助键/索引。
创建一个函数来检索当前会话的最新ParentId(假设将正确设置唯一标识符)。
在插入子项中使用此功能。