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

发布于 2024-09-07 03:52:08 字数 248 浏览 4 评论 0原文

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

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

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

I have a package that will be inserting a single parent record in one table, and dependent child records in another table with a FK on the parent_id. Each of these functions will be called by an external program, and all calls to insert children may not be contained within the same transaction.

I'm wondering if there is any way for me to avoid having to track the parent_id manually and pass it along in every procedure's parameter list. I've considered using the sys_context, but don't think that will work because it won't be in a single transaction.

Are there any other strategies for this or do I just need to suck it up and pass the parent_id to every method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

农村范ル 2024-09-14 03:52:08

您可以像这样使用包变量:

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

You could just use a package variable like this:

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;

The package variable persists as long as your database connection exists. This would not work in a stateless environment like a web application.

That said, I'd be in favour of keeping the procedure modular by passing the ID in each time. That way nothing unexpected can happen.

失去的东西太少 2024-09-14 03:52:08

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

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

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

如果插入子项的调用位于不同的事务中,并且您有连接池,那么我认为您无法避免告诉第二个事务所需的parentId。

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

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

根据此唯一标识符和时间在父表上创建辅助键/索引。

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

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

The key question is whether sessions in your calling application are pooled, or 'sticky'.

If the same connection / session is re-used by your external program for each transaction, then storing the parentId in a package variable will be fine.

If you have connection pooling then using package variables starts to become tricky / positively dangerous.

If the call to insert the children is in a different transaction, and you have connection pooling, I can see no way you can avoid telling the second transaction the required parentId.

Caveat : If you are more concerned with simplifying the API to the package than performance, and you have something along these lines . . .

For each database call in the external application, set something that uniquely identifies the calling process into the SYS_CONTEXT or a package variable (we have something like this, so that we can derive the calling method and 'real' rather than pooled d/b user).

Create a secondary key / index on the parent table, based on this unique identifier and time.

Create a function to retrieve the most recent ParentId for the current session (presuming that the unique identifier will be set correctly).

Use this function in your insert child.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文