当我';在PL/SQL中插入子记录?

当我';在PL/SQL中插入子记录?,sql,oracle,plsql,Sql,Oracle,Plsql,我有一个包,它将在一个表中插入单个父记录,在另一个表中插入父id上带有FK的从属子记录。这些函数中的每一个都将由外部程序调用,并且插入子记录的所有调用可能不包含在同一事务中 我想知道是否有任何方法可以避免手动跟踪父id并在每个过程的参数列表中传递它。我已经考虑过使用sys_上下文,但我认为这不会奏效,因为它不会出现在单个事务中 是否有其他的策略,或者我只需要接受它并将父id传递给每个方法?您可以使用如下包变量: package body mypackage is g_parent_id

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

我想知道是否有任何方法可以避免手动跟踪父id并在每个过程的参数列表中传递它。我已经考虑过使用sys_上下文,但我认为这不会奏效,因为它不会出现在单个事务中


是否有其他的策略,或者我只需要接受它并将父id传递给每个方法?

您可以使用如下包变量:

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来保持过程模块化。这样就不会发生意外情况。

您可以使用如下包变量:

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来保持过程模块化。这样就不会发生意外情况。

关键问题是调用应用程序中的会话是池式的还是“粘性的”

如果外部程序在每个事务中重复使用相同的连接/会话,则可以将parentId存储在包变量中

如果您有连接池,那么使用包变量开始变得棘手/非常危险

如果插入子事务的调用在另一个事务中,并且您有连接池,那么我认为您无法避免将所需的parentId告诉第二个事务

警告:如果您更关心的是简化API到包中,而不是性能,并且您有一些类似的东西

对于外部应用程序中的每个数据库调用,在SYS_上下文或包变量中设置唯一标识调用进程的内容(我们有类似的内容,以便我们可以派生调用方法和“real”而不是池式d/b用户)

基于此唯一标识符和时间,在父表上创建一个辅助键/索引

创建一个函数来检索当前会话的最新ParentId(假定唯一标识符设置正确)


在插入子项中使用此函数。

关键问题是调用应用程序中的会话是池式的还是“粘性的”

如果外部程序在每个事务中重复使用相同的连接/会话,则可以将parentId存储在包变量中

如果您有连接池,那么使用包变量开始变得棘手/非常危险

如果插入子事务的调用在另一个事务中,并且您有连接池,那么我认为您无法避免将所需的parentId告诉第二个事务

警告:如果您更关心的是简化API到包中,而不是性能,并且您有一些类似的东西

对于外部应用程序中的每个数据库调用,在SYS_上下文或包变量中设置唯一标识调用进程的内容(我们有类似的内容,以便我们可以派生调用方法和“real”而不是池式d/b用户)

基于此唯一标识符和时间,在父表上创建一个辅助键/索引

创建一个函数来检索当前会话的最新ParentId(假定唯一标识符设置正确)


在插入子项中使用此函数。

我以前没有使用过包变量,但从我所读到的内容来看,它们会在会话长度内保持不变。由一个会话设置为包变量的值是否对任何其他会话可见,或者它们是否完全隔离?基本上,每个会话都会有这个变量的副本来做它想做的事情,或者一个会话可以为另一个会话更改这个变量的值吗?每个会话都有自己的副本,它们彼此看不见。因此,只要在整个事务中维护一个会话,即在“有状态”环境中,这就可以正常工作。我以前没有使用过包变量,但从我所读到的内容来看,它们会在会话长度内保持不变。由一个会话设置为包变量的值是否对任何其他会话可见,或者它们是否完全隔离?基本上,每个会话都会有这个变量的副本来做它想做的事情,或者一个会话可以为另一个会话更改这个变量的值吗?每个会话都有自己的副本,它们彼此看不见。因此,只要在整个事务中维护一个会话,即在“有状态”环境中,这就可以正常工作。