代码之家  ›  专栏  ›  技术社区  ›  Dan Polites

Oracle存储过程/函数加载顺序

  •  0
  • Dan Polites  · 技术社区  · 15 年前

    我在一个文件夹中有许多存储过程和函数。我有一个批处理文件,它循环遍历文件夹中的.sql文件,并将文件名写入单个sql文件以供执行。之后,批处理文件将执行sqlplus中的单个文件。我遇到的问题是存储过程和函数的创建顺序。我遇到编译错误,因为存储过程C需要执行函数A,但存储过程C是在函数A之前创建的。有没有一种方法可以在不排序存储过程和函数的情况下解决这个问题?我的假设是没有,没有,但我想在我开始订购脚本之前确定。

    5 回复  |  直到 15 年前
        1
  •  5
  •   David Aldridge    15 年前

    您可以加载它们,然后遍历Dependencies视图,尝试为下一次确定正确的顺序,或者只加载它们,然后重新编译,但实际上,最佳的工作方式是使用包,而不是独立的过程和函数。

    在这种情况下,您将首先创建所有包规范,然后创建包主体。正是因为这个原因,它们被分为规范和主体。

        2
  •  1
  •   APC    15 年前

    编译错误可能并不重要。第一次调用其中一个无效过程时,它将编译。

    问题是“破窗”综合症,在这种情况下,一个真正的缺失的依赖会在所有的噪音中消失。如果这个想法让你不安,你可以编译所有无效的程序单元。有很多种方法可以做到这一点,但最好的方法是使用 the UTL_RECOMP package (在10g或更高版本中)或使用utlrp.sql脚本,您可以在 %ORACLE_HOME%/rdbms/admin 在早期版本中。

    更新

    Solomon Yakobson编写了一个pl/sql程序来重新编译无效的程序;它不依赖于版本,也不需要sysdba特权。 Download it.

        3
  •  0
  •   dpbradley    15 年前

    只需创建对象(有些对象无效),然后在后续步骤中编译所有对象。

    [编辑]

    我刚看到大卫的回答,在我发布之后,他关于将过程和函数转换为包的建议是一个很好的答案,但是如果你以后将其他对象添加到你的文件夹中,比如视图、类型等,你仍然会有依赖性问题。我使用嵌套循环进行重新编译——内部循环选择所有无效的对象,然后重新编译每个对象。这位于外部循环的内部,当没有无效对象或达到某个最大传递值时,该循环将退出(对于那些需要修复实际编译错误的情况)

        4
  •  0
  •   Juergen Hartelt    15 年前

    您可以在某种程度上增强批处理文件,使其评估依赖关系信息,您可以将其作为特殊注释存储在SQL文件中,或者作为标记或常规注释的一部分存储在版本控制系统中。

    如果您在执行生成的SQL脚本时遇到依赖性问题导致的错误,您知道已经引入了一些新的依赖性,需要对其进行“描述”,以便批处理识别它。

    是的,这是手工操作。但安装SQL脚本仍然会生成,就像现在一样。

        5
  •  0
  •   softveda    15 年前

    我们的方法是创建所有存储过程,然后尝试编译5次。如果仍然有一些存储过程即使在5次之后仍然未能编译,则会导致生成失败。根据我的经验和我们的代码库,5次重复已经证明是足够的。