Oracle 生成似乎第一次运行时没有问题的生成顺序

Oracle 生成似乎第一次运行时没有问题的生成顺序,oracle,plsql,dependencies,Oracle,Plsql,Dependencies,:OBJECT\u NAME应该是要跟踪其所有依赖项和生成顺序的根对象。对我来说,这是一个带有单个方法的主包,该方法是系统其余部分的入口点 :OBJECT\u TYPE我主要局限于包体,但包含其他类型(如触发器)应该不会太多 最后一件事是,:object\u NAME指定的对象不会出现在输出中,但它应该是最后一项,因此您必须手动将其添加到生成列表中 更新:我刚刚发现了用户依赖项和所有依赖项,现在这个代码可能会简单得多。从 您不需要构建顺序-只需使用“创建或替换…”来构建包以文件为基础,然后在两级

:OBJECT\u NAME
应该是要跟踪其所有依赖项和生成顺序的根对象。对我来说,这是一个带有单个方法的主包,该方法是系统其余部分的入口点

:OBJECT\u TYPE
我主要局限于
包体
,但包含其他类型(如触发器)应该不会太多

最后一件事是,
:object\u NAME
指定的对象不会出现在输出中,但它应该是最后一项,因此您必须手动将其添加到生成列表中


更新:我刚刚发现了
用户依赖项
所有依赖项
,现在这个代码可能会简单得多。


您不需要构建顺序-只需使用“创建或替换…”来构建包以文件为基础,然后在两级嵌套循环中编译它们-内部循环中的每个过程编译仍然无效的所有内容,外部循环用于检查剩余无效对象的计数,并为内部循环的最大执行设置某种阈值。在实践中,我从未见过传球次数超过三次

如果依赖项中涉及多个架构,请查看运行Oracles utlrp.sql脚本,该脚本跨架构工作,并设置一些基础结构来管理流程-但是,这需要一个特权帐户

此外,如果扩展源代码管理以包含视图,请确保脚本使用“创建或替换强制视图…”来创建在创建时具有未满足依赖关系的视图

我使用的示例脚本:

set serveroutput on
declare
 cursor invalidObjCur is 
  select object_name, object_type
    from user_objects
    where status <> 'VALID'
    ;
 compileStmt varchar2(4000); 
 passCount pls_integer := 0;
 maxPasses pls_integer := 5;
 lastInvalidCount pls_integer := 32000; 
 objectCount pls_integer;
 continue boolean := TRUE;

begin
 dbms_output.enable(1000000);
 while (continue) loop
   passCount := passCount + 1;
   dbms_output.put_line('Pass '||passCount);
   objectCount := 0;
   for curRow in InvalidObjCur loop
    if curRow.object_type = 'PACKAGE BODY' then
        compileStmt := 'alter PACKAGE '||curRow.object_name||' compile body';
    else
        compileStmt := 'alter '||curRow.object_type||' '||
        chr(34)||curRow.object_name||chr(34)||' compile';
    end if;
    begin
      execute immediate compileStmt;
    exception when others then
      null;
    end;
   objectCount := objectCount + 1;
   end loop;
   dbms_output.put_line('Recompilations attempted: '||objectCount);
   continue := (passCount < maxPasses) and (objectCount < lastInvalidCount);
   lastInvalidCount := objectCount;
 end loop;
dbms_output.put_line('***** Remaining Invalid ********');
for curRow in InvalidObjCur loop
 dbms_output.put_line(curRow.object_type||' '||curRow.object_name);
end loop; 
dbms_output.put_line('********************************');
end;    
/
打开服务器输出
声明
游标无效的bjcur为
选择对象名称、对象类型
来自用户对象
其中状态为“有效”
;
编译Mt varchar2(4000);
密码整数:=0;
maxPasses pls_整数:=5;
lastInvalidCount pls_整数:=32000;
objectCount pls_整数;
继续布尔值:=TRUE;
开始
dbms_输出启用(1000000);
while(continue)循环
passCount:=passCount+1;
dbms|u output.put|u行('Pass'| | passCount);
objectCount:=0;
对于InvalidObjCur循环中的curRow
如果curRow.object_type='PACKAGE BODY',则
compileStmt:=“alter PACKAGE”|| curRow.object|u name | | compile body”;
其他的
compileStmt:=“alter'|| curRow.object|u type |”||
chr(34)| curRow.object|u name | | chr(34)| |‘编译’;
如果结束;
开始
立即执行compileStmt;
当其他人
无效的
结束;
objectCount:=objectCount+1;
端环;
dbms_output.put_行('尝试重新编译:'| | objectCount);
继续:=(passCount
如果你真的只处理PL/SQL包,你不需要担心构建顺序。首先构建所有的包规范。然后您可以部署所有的包体,它们将被编译,因为它们的依赖关系是包规范

如果您碰巧有一些依赖于其他规范的包规范-如果您有声明(比如)在打包过程的签名中使用的常量、子类型或引用游标的包-那么您需要首先构建这些包规范。但是应该有足够少的代码,您可以手动将它们安排在构建脚本中

编辑

看起来他们会这样做 增量和“清理”构建, 因此,构建顺序将是最重要的 因为当他们打扫房间的时候 环境和重建

这不会改变任何事情

下面是一个扩展示例。我有一个包含三个包的模式

SQL> select object_name, object_type, status
  2  from user_objects
  3  order by 1, 2
  4  /

OBJECT_NAME     OBJECT_TYPE     STATUS
--------------- --------------- -------
PKG1            PACKAGE         VALID
PKG1            PACKAGE BODY    VALID
PKG2            PACKAGE         VALID
PKG2            PACKAGE BODY    VALID
PKG3            PACKAGE         VALID
PKG3            PACKAGE BODY    VALID

6 rows selected.

SQL>
有趣的是,PKG1中的过程调用PKG2中的过程,PKG2中的过程调用PKG3中的过程,PKG3中的过程调用PKG1中的过程

Q.这种循环依赖关系是如何工作的?
A.这不是循环依赖项

SQL> select name, type, referenced_name, referenced_type
  2  from user_dependencies
  3  where referenced_owner = user
  4  /

NAME            TYPE            REFERENCED_NAME REFERENCED_TYPE
--------------- --------------- --------------- ---------------
PKG1            PACKAGE BODY    PKG1            PACKAGE
PKG1            PACKAGE BODY    PKG2            PACKAGE
PKG2            PACKAGE BODY    PKG2            PACKAGE
PKG2            PACKAGE BODY    PKG3            PACKAGE
PKG3            PACKAGE BODY    PKG3            PACKAGE
PKG3            PACKAGE BODY    PKG1            PACKAGE

6 rows selected.

SQL> 
所有依赖对象都是包体,所有引用对象都是包规格。因此,如果我丢弃并重建模式,我使用的顺序实际上并不重要。首先我们是垃圾

SQL> drop package pkg1
  2  /

Package dropped.

SQL> drop package pkg2
  2  /

Package dropped.

SQL> drop package pkg3
  2  /

Package dropped.

SQL>
然后我们重建

SQL> create or replace package pkg3 is
  2      procedure p5;
  3      procedure p6;
  4  end pkg3;
  5  /

Package created.

SQL> create or replace package pkg2 is
  2      procedure p3;
  3      procedure p4;
  4  end pkg2;
  5  /

Package created.

SQL> create or replace package pkg1 is
  2      procedure p1;
  3      procedure p2;
  4  end pkg1;
  5  /

Package created.

SQL> create or replace package body pkg2 is
  2      procedure p3 is
  3      begin
  4          pkg3.p5;
  5      end p3;
  6      procedure p4 is
  7      begin
  8          dbms_output.put_line('PKG2.P4');
  9      end p4;
 10  end pkg2;
 11  /

Package body created.

SQL> create or replace package body pkg3 is
  2      procedure p5 is
  3      begin
  4          dbms_output.put_line('PKG3.P5');
  5      end p5;
  6      procedure p6 is
  7      begin
  8          pkg1.p1;
  9      end p6;
 10  end pkg3;
 11  /

Package body created.

SQL> create or replace package body pkg1 is
  2      procedure p1 is
  3      begin
  4          dbms_output.put_line('PKG1.P1');
  5      end p1;
  6      procedure p2 is
  7      begin
  8          pkg2.p4;
  9      end p2;
 10  end pkg1;
 11  /

Package body created.

SQL>
单个对象的顺序是不相关的。只需在包体之前构建包规格。尽管这并不重要

SQL> create or replace package pkg4 is
  2      procedure p7;
  3  end pkg4;
  4  /

Package created.

SQL> create or replace package body pkg4 is
  2      procedure p7 is
  3      begin
  4          dbms_output.put_line('PKG4.P7::'||constants_pkg.whatever);
  5      end p7;
  6  end pkg4;
  7  /

Warning: Package Body created with compilation errors.

SQL> show errors
Errors for PACKAGE BODY PKG4:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9      PL/SQL: Statement ignored
4/43     PLS-00201: identifier 'CONSTANTS_PKG.WHATEVER' must be declared
SQL>
PKG4
无效,因为我们尚未构建
CONSTANTS\u PKG

SQL> create or replace package constants_pkg is
  2      whatever constant varchar2(20) := 'WHATEVER';
  3  end constants_pkg;
  4  /

Package created.

SQL> select object_name, object_type, status
  2  from user_objects
  3  where status != 'VALID'
  4  order by 1, 2
  5  /

OBJECT_NAME     OBJECT_TYPE     STATUS
--------------- --------------- -------
PKG4            PACKAGE BODY    INVALID

SQL> 
SQL> set serveroutput on size unlimited
SQL> exec pkg4.p7
PKG4.P7::WHATEVER

PL/SQL procedure successfully completed.

SQL> select object_name, object_type, status
  2  from user_objects
  3  where status != 'VALID'
  4  order by 1, 2
  5  /

no rows selected

SQL>
使用
CREATE或REPLACE
生成的任何内容都将始终被创建,如果出现错误,它将被标记为无效。只要我们直接或间接地执行它,数据库就会为我们编译它。因此,秩序并不重要。真的没有

如果使用无效对象完成构建的想法与您有关——我对此表示同情,我们被告知不要与破碎的窗口共存——您可以使用
utlrp
脚本或11g;这两种方法都需要SYSDBA帐户

编辑2

该过程以构建为基础 由供应商制造的工具 我们正在集成的产品, 这就是为什么我唯一能做的 为构建过程提供一个列表 按需要的顺序排列文件的顺序 内置的。如果有编译器 错误,构建工具失败,我们有 手动提交新项目的请求的步骤 建造

这是一个政治问题,不是技术问题。这并不是说政治问题不能用技术手段解决,而是说
SQL> create or replace package pkg4 is
  2      procedure p7;
  3  end pkg4;
  4  /

Package created.

SQL> create or replace package body pkg4 is
  2      procedure p7 is
  3      begin
  4          dbms_output.put_line('PKG4.P7::'||constants_pkg.whatever);
  5      end p7;
  6  end pkg4;
  7  /

Warning: Package Body created with compilation errors.

SQL> show errors
Errors for PACKAGE BODY PKG4:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9      PL/SQL: Statement ignored
4/43     PLS-00201: identifier 'CONSTANTS_PKG.WHATEVER' must be declared
SQL>
SQL> create or replace package constants_pkg is
  2      whatever constant varchar2(20) := 'WHATEVER';
  3  end constants_pkg;
  4  /

Package created.

SQL> select object_name, object_type, status
  2  from user_objects
  3  where status != 'VALID'
  4  order by 1, 2
  5  /

OBJECT_NAME     OBJECT_TYPE     STATUS
--------------- --------------- -------
PKG4            PACKAGE BODY    INVALID

SQL> 
SQL> set serveroutput on size unlimited
SQL> exec pkg4.p7
PKG4.P7::WHATEVER

PL/SQL procedure successfully completed.

SQL> select object_name, object_type, status
  2  from user_objects
  3  where status != 'VALID'
  4  order by 1, 2
  5  /

no rows selected

SQL>
SQL> drop package constants_pkg
  2  /

Package dropped.

SQL> create or replace package body pkg4 is
  2      procedure p7 is
  3      begin
  4          dbms_output.put_line('PKG4.P7::'||zzz_constants_pkg.whatever);
  5      end p7;
  6  end pkg4;
  7  /

Warning: Package Body created with compilation errors.

SQL> show errors
Errors for PACKAGE BODY PKG4:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9      PL/SQL: Statement ignored
4/43     PLS-00201: identifier 'ZZZ_CONSTANTS_PKG.WHATEVER' must be
         declared

SQL>
SQL> create or replace package zzz_constants_pkg is
  2      whatever constant varchar2(20) := 'WHATEVER';
  3  end zzz_constants_pkg;
  4  /

Package created.

SQL>
SQL> select name, type, referenced_name, referenced_type
  2  from user_dependencies
  3  where referenced_owner = user
  4  /

NAME            TYPE            REFERENCED_NAME   REFERENCED_TYPE
--------------- --------------- ----------------- ---------------
PKG1            PACKAGE BODY    PKG1              PACKAGE
PKG1            PACKAGE BODY    PKG2              PACKAGE
PKG2            PACKAGE BODY    PKG2              PACKAGE
PKG2            PACKAGE BODY    PKG3              PACKAGE
PKG3            PACKAGE BODY    PKG3              PACKAGE
PKG3            PACKAGE BODY    PKG1              PACKAGE
PKG4            PACKAGE BODY    PKG4              PACKAGE

7 rows selected.

SQL>
SQL> alter package pkg4 compile body;

Package body altered.

SQL> select name, type, referenced_name, referenced_type
  2  from user_dependencies
  3  where referenced_owner = user
  4  /

NAME            TYPE            REFERENCED_NAME   REFERENCED_TYPE
--------------- --------------- ----------------- ---------------
PKG1            PACKAGE BODY    PKG1              PACKAGE
PKG1            PACKAGE BODY    PKG2              PACKAGE
PKG2            PACKAGE BODY    PKG2              PACKAGE
PKG2            PACKAGE BODY    PKG3              PACKAGE
PKG3            PACKAGE BODY    PKG3              PACKAGE
PKG3            PACKAGE BODY    PKG1              PACKAGE
PKG4            PACKAGE BODY    PKG4              PACKAGE
PKG4            PACKAGE BODY    ZZZ_CONSTANTS_PKG PACKAGE

8 rows selected.

SQL> 
-- Compile invalid objects
EXEC DBMS_UTILITY.compile_schema(USER, FALSE);