2

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

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

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

但是,这不起作用,因为动态begin ... endPL/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;
4

1 回答 1

2

PL/SQL 是一种过程语言,并不特别擅长动态执行自身。它没有类似于 Java 的反射功能。因此,实施您的建议充其量是笨拙的。

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

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

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

tl;dr
Large CASE 陈述有点像民主:除了所有其他人之外,它们是最糟糕的解决方案。

于 2013-08-06T14:06:57.803 回答