当我在PL / SQL中插入子记录时,如何保留指向父记录的指针?

时间:2010-06-28 14:57:25

标签: sql oracle plsql

我有一个包将在一个表中插入单个父记录,而在另一个表中的依赖子记录在parent_id上具有FK。这些函数中的每一个都将由外部程序调用,并且所有插入子代的调用可能不包含在同一事务中。

我想知道我是否有办法避免手动跟踪parent_id并在每个过程的参数列表中传递它。我考虑过使用sys_context,但不认为这样可行,因为它不会出现在单个事务中。

是否还有其他策略或我是否需要将其吸收并将parent_id传递给每个方法?

2 个答案:

答案 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(假设将正确设置唯一标识符)。

在插入子项中使用此功能。