在Oracle PL / SQL中引用“外部函数”

时间:2014-02-12 13:21:38

标签: oracle plsql oracle11g

我有一堆自动生成的SQL文件,其中包含Oracle存储过程的PL / SQL代码。

问题:我们假设文件sp_myproc中的存储过程file1.sql包含对f_myfunc中函数files2.sql的引用。在file1.sql之前执行file2.sql时,我们会收到错误,因为sp_myproc引用了尚未存在的函数f_myfunc

这些引用可能非常复杂,因此我们需要一种通用的方法来处理这种情况(我们不能只是颠倒文件的顺序)。

解决方案:

  1. 第一个选项是让脚本运行两次。我们第一次得到错误,但第二次他们会运行正常。这就是我们现在的做法,但我们正在寻找一个更好的选择,因为客户抱怨错误。这种方法的另一个缺陷是,如果引用变得更复杂,我们需要运行脚本两次以上。
  2. IF NOT EXISTS CREATE FUNCTION f_myfunc CREATE语句之前插入某种sp_myproc。这将插入一个虚函数f_myfunc,稍后将被真实函数替换。我们尝试了这种方法,但它很难看,因为IF ... THEN CREATE FUNCTION是非法的(PL / SQL中的DDL),所以我们需要动态SQL。
  3. 最好的选择是拥有某种DECLARE EXTERNAL FUNCTION f_myfunc语句,告诉编译器如果它不存在,将在以后创建f_myfunc。这是某种外部函数引用,如C,C#等,它们被编译器接受,后来由链接器解析。我知道PL / SQL的行为不像C或C#,但我希望这里有类似的方法。
  4. PL / SQL是否有类似于选项3中的语句?

    还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

如果您将功能放在包装中,可以减少问题,但很难完全避免它。

如果你使用包,你只需要在实体之前编译规范,你就可以避免这个问题。

请注意,在某些极少数情况下,您无法使用包内的函数,但只要原始函数仅使用打包函数,您仍然可以避免由函数间依赖性引起的编译错误。

建议的编译顺序:

  • 包装规格

  • 功能和程序(外包装)

  • 浏览

  • 包体