PL/SQL - 调用包过程的新实例

Posted

技术标签:

【中文标题】PL/SQL - 调用包过程的新实例【英文标题】:PL/SQL - Call new instance of package procedure 【发布时间】:2016-12-08 10:16:21 【问题描述】:

我有使用全局变量的包。 从其中一个程序中,我需要调用“新实例”或另一个程序(同一个包)。我需要第二个过程来使用它自己的全局变量版本,完成后我需要第一个过程来像以前一样使用变量。 我做了一个快速而肮脏的修复,在第二个过程开始时,我创建备份变量并将全局变量值放入其中,然后将全局变量设置为 NULL,最后我将备份值放回全局变量。 但我希望有比这个更好的解决方案,一种启动该过程/包的新实例的方法

编辑

详细的场景是这样的: 包有多个使用在包级别定义的变量的过程和函数。我调用包的第一个过程,该过程调用当前操作所需的所有内容。在某些情况下,从第二个程序开始,我需要启动必须执行的新任务(动作)。在那种情况下,我想重新开始包中的第一个过程,但要让它使用自己的全局变量(不要与原始变量混淆),因为原始过程尚未完成并且仍然需要它的变量 一些包全局变量是自定义类型(确切地说是 custom_type 表),所以它给我带来了额外的问题。

希望现在清楚我有什么问题以及我正在尝试做什么 所以是这样的

Package 1
 global_var 1
 global_var 2
 global_var 3

 Procedure 1
     some code
     call to function 1
     some code
     call to procedure 2
     and so on...
 Procedure 2
     some code
     call function 3
     some code
     call to procedure 1 (start new process)
     some code
     call procedure 3
     and so on....
 Procedure 3
 Procedure 4
 Function 1
 Function 2
 Function 3
 Function 4

而变量是这样的

type type1 is record (x NUMBER, y VARCHAR2(1024), z NUMBER);
type type2 is table of type1;

global_var_1 NUMBER;
global_var_2 type2;
...

【问题讨论】:

类型有实例,包没有。也许您可以将值放在数组或全局临时表中,并使用一些键来区分值集,或者将逻辑放在对象类型中。 按包模拟对象实例在概念上没有不同的方法。您可以使用全局关联记录数组通过实例 id 访问实例状态,并使用 getter 和 setter 进行包装。 也许如果您更详细地解释您正在处理的场景,本论坛中的某人可能会提出更简单(且可行)的替代方案。 无论你做什么都是错的,伙计。如果程序一次需要不同的值 - 将它们分成不同的包。如果业务逻辑需要不同值的相同过程,那么最好在过程中修改一个逻辑 “将它们分成不同的包”是什么意思?第二次调用使用与第一次调用相同的程序。我该如何拆分它们? 【参考方案1】:

在阅读了您的整个帖子(以及附加说明)后,我得出的结论是,您的问题始于对所需流程的错误构想。事实上(以及借用其他编程语言的话)你需要你的包来生成具有自己数据上下文的新线程。

我看到了两种可能的解决方案(在 Oracle 中):

    用 JAVA 编写你的包(这里我假设这个选项确实允许创建线程,但从未检查过它),

    不要使用全局变量。

对于第一个选项,我无话可说,只是可能值得您进一步调查。

至于第二个选项,您可以(实际上很容易):

    定义一个包级别的类型,该类型将包含您当前在全局级别使用的所有变量,并且:

    在包中的所有函数中添加一个新类型的参数(我会将其作为最后一个),默认值为 NULL。在需要时,可以将新参数的定义设置为IN OUT(适用于结构中的一个或多个字段在函数内更新并且更新需要“冒泡”到调用代码的情况) .

现在,让我们分析两个场景(第一次调用 FIRST 过程和第二次从包中调用):

    FIRST INVOCATION(来自外部包):新参数将为空(NULL),并且该过程将分配在其他函数/过程的其他调用中级联所需的任何值;

    第二次调用(来自包内):可以为新参数包含一个非空值(取决于您的需要);然后,代码将能够准备一组新值(用于上述类型的新变量),然后将通过其他函数和过程的附加调用进行级联。

此方法完全满足您的需求,而(据我所知)所需的代码更改将是最小的。

希望这可以解决您发布的问题,并且建议的方法对您有用。

【讨论】:

好主意,我从来没有想过我可以创建新的包级别类型,然后将其作为单个变量传递。我相信这效率有点低(因为我正在传递我没有使用的变量),但会导致更简洁的代码更容易让我的同事理解。谢谢,会采取这个解决方案

以上是关于PL/SQL - 调用包过程的新实例的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL:调用包时找不到被调用的程序单元

从 Java 调用 PL/SQL Web Toolkit 过程

使用带有布尔输入参数的 PL/SQL 在 oracle 中调用 java 存储过程

PL/SQL - 如何检查是不是正在使用包/过程/函数?

PL/SQLPL/SQL过程

PL/SQL练习命名块: 存储过程函数触发器包