从包中动态调用私有过程

时间:2013-08-06 11:28:32

标签: oracle plsql

假设我有一个公开公开一个程序的软件包。但是,此过程的目的是根据传递给它的参数调用包中的私有过程。

理想情况下,我想要定义一个哈希表(例如,一个关联数组甚至一个表),它将参数映射到内部过程,然后执行以下操作:

execute immediate 'begin ' || internalProc(myArgument) || '; end;';

但是,这不起作用,因为动态begin ... end PL / SQL块在包的范围之外执行。我甚至不能'begin myPkg.' || internalProc...,因为内部程序都是私有的。

因此,我能够实现这一目标(没有暴露私人程序)的唯一方法是使用大规模的硬编码交换机吗?

case myArgument
  when 'something' then someProc;
  when 'foo'       then fooProc;
  when 'bar'       then barProc;
  ...
  else raise_application_error('-20001, 'No such process.')
end case;

1 个答案:

答案 0 :(得分:2)

PL / SQL是一种过程语言,并不是特别擅长动态执行。它没有类似于Java的Reflection功能。因此,实施你提出的建议至多是笨重的。

接下来的问题是你的建议是否是一个好主意。这是个人品味的问题。我自己,我更喜欢把控制逻辑放在我面前而不是去别处看。在软编码的某些外部对象中配置控制流:“从源代码中删除应该在源代码中的东西并将它们放在某些外部资源中的做法。” Find out more

充其量,软编码只会将复杂性转移到其他地方,最坏的情况会增加系统的整体复杂性。应用程序完全是由这些东西构建的,但它们使用规则引擎来管理事物(并且传闻一些这样的应用程序似乎超出了人类的理解)。

将参数值链接到内部过程的名称将会中断the Law of Demeter。这是一个非常明智的设计原则,它认为调用程序不应该理解被调用程序的内部结构。违反得墨忒耳法则意味着重新组织被叫程序的内部结构可能会对调用程序产生影响。这对可维护性产生了不利影响(根据我的经验,YMMV)。

<强> TL;博士
大型CASE语句是a bit like democracy:除了所有其他语句之外,它们是最差的解决方案。