关于 utlirplscope.sql 脚本

现在,您可能已经意识到这不是 Oracle 11.1.0.6 PL/Scope 文档中承诺的 utlirplscope.sql 脚本。这是有原因的。我们想首先澄清一些有关此种脚本有用的误解并确保您真的需要执行此类操作,而不是仅提供一个脚本来为 PL/Scope 重新编译 STANDARD 和 DBMS_STANDARD。

什么是 utlirplscope.sql?

曾有人提出使用 utlirplscope.sql 脚本来允许 DBA 以安全的方式用 PL/Scope 标识符数据重新编译 STANDARD 和 DBMS_STANDARD。遗憾地是,在文档发布之后,大家认为记录以安全的方式重新编译 STANDARD 和 DBMS_STANDARD 的过程要更为简单,因此,从未有人编写过 utlirplscope.sql,因而也就不存在该脚本。对于 Oracle 11.1.0.6 的用户,本文结尾处给出了以安全的方式编译 STANDARD 和 DBMS_STANDARD(建议使用的 utlirplscope.sql 脚本的实质内容)的过程。

Utlirplscope.sql 并不一定是 PL/Scope 安装脚本。PL/Scope 内置于 PL/SQL 编译器内,并不需要进行安装。

尽管 Oracle 11.1.0.6 中没有附带任何 PL/Scope 标识符数据,但正如 PL/Scope 文档中所述,您可以随时为您的代码库收集并使用 PL/Scope 标识符数据,无论您的数据库是否包含 STANDARD 和 DBMS_STANDARD PL/Scope 标识符数据。

只有 Oracle 11.1.0.6 用户需要用 PL/Scope 标识符数据重新编译 STANDARD 和 DBMS_STANDARD。默认情况下,Oracle 11.1.0.7 的用户(从 Oracle 11.1.0.6 升级的用户除外)的数据库中具有 STANDARD 和 DBMS_STANDARD 标识符数据,不必执行本文所述过程。Oracle 11.1.0.7 PL/Scope 文档也包含该过程,以帮助从 Oracle 11.1.0.6 升级的用户。

什么是 STANDARD 和 DBMS_STANDARD 标识符数据?

STANDARD 和 DBMS_STANDARD 标识符数据可用于跟踪在代码库的 STANDARD 或 DBMS_STANDARD 中声明的标识符的使用。这些标识符包含基类(如 VARCHAR2 和 NUMBER)和过程(如 raise_application_error())。

我是否需要 STANDARD 和 DBMS_STANDARD 标识符数据?

很有可能您并不需要 STANDARD 或 DBMS_STANDARD PL/Scope 标识符数据,因此也无需执行以下过程。如果您不需要知道代码库中何处引用了 VARCHAR2 或 NUMBER 等标识符,则您可能不需要 STANDARD 或 DBMS_STANDARD 标识符数据。然而,如果在特定情况下需要搜索 STANDARD 或 DBMS_STANDARD 标识符,如查找代码库中所有对 BINARY_INTEGER 的引用以使用 PLS_INTEGER 进行替换,则您需要 STANDARD 和 DBMS_STANDARD 标识符数据并可能需要执行该过程。

我们始终强调使用 PL/Scope 并不一定需要 STANDARD 和 DBMS_STANDARD 标识符数据。 请勿执行以下过程,除非知道需要搜索在 STANDARD 或 DBMS_STANDARD 中声明的标识符。如果您的特定 PL/Scope 应用只需要在代码库中声明的标识符的 PL/Scope 标识符数据,您可以按照 PL/Scope 文档中的说明收集该标识符数据。

我的数据库中是否已经具有 STANDARD 和 DBMS_STANDARD 标识符数据?

您的数据库中可能已包含 STANDARD 和 DBMS_STANDARD PL/Scope 标识符数据。新建的 Oracle 11.1.0.7 数据库或从 Oracle 10.2 或更低版本升级至 11.1.0.7 的数据库已经包含了 STANDARD 和 DBMS_STANDARD 标识符数据。然而,Oracle 11.1.0.6 数据库用户或从 11.1.0.6 升级的 Oracle 11.1.0.7 数据库的用户可能不具备 STANDARD 和 DBMS_STANDARD 标识符数据。

要确定您的数据库是否已包含 PL/Scope STANDARD 和 DBMS_STANDARD 标识符数据,可执行以下查询:

SQL> SELECT UNIQUE OBJECT_NAME FROM ALL_IDENTIFIERS

2 WHERE OBJECT_NAME IN ('STANDARD', 'DBMS_STANDARD')

3 AND OWNER='SYS' ;

OBJECT_NAME

------------------------------

DBMS_STANDARD

STANDARD

2 rows selected.

如果选定了 2 行,则您的数据库已包含 STANDARD 和 DBMS_STANDARD 标识符数据。您无需执行该过程,不必阅读本文其余部分的内容。

如果没有选定任何行,则您的数据库未包含 STANDARD 和 DBMS_STANDARD 的 PL/Scope 标识符数据,您必须执行以下过程以收集此数据。

好的,我已经确定我没有所需的 STANDARD 和 DBMS_STANDARD PL/Scope 标识符数据。现在该怎么办?

如果您确定需要 STANDARD 和 DBMS_STANDARD 标识符数据,那么您可以执行以下过程来收集此数据。

请注意,DBA 或其他具有 SYSDBA 权限的用户必须执行该过程,数据库中的所有 PL/SQL 单元都将失效并需进行重新编译。对于开发环境而言,这样做的一次性成本不会成为问题。如果是在生产环境中,请确定是否真的需要 STANDARD 和 DBMS_STANDARD PL/Scope 标识符数据并了解执行该过程的后果,然后再继续。

  1. 连接至数据库,将其关闭,然后以 UPGRADE 模式启动:

SQL> CONNECT / AS SYSDBA;

SQL> SHUTDOWN IMMEDIATE;

SQL> STARTUP PFILE= parameter_initialization_file UPGRADE;

  1. STANDARD 和 DBMS_STANDARD 都在 utlirp.sql 中进行了重新编译。因此,将生成以下更改会话,为这些程序包收集 PL/Scope 标识符数据:

SQL> ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';

  1. 使数据库失效并进行重新编译:

SQL> @?/rdbms/admin/utlirp.sql

现在,数据库中的所有 PL/SQL 对象都已失效(STANDARD 和 DBMS_STANDARD 除外,它们使用 PLSCOPE_SETTINGS='IDENTIFIERS:ALL' 进行重新编译)。

  1. 关闭数据库,然后以 NORMAL 模式启动:

SQL> SHUTDOWN IMMEDIATE;

SQL> STARTUP PFILE= parameter_initialization_file;

  1. 对于任何剩余的无效 PL/SQL 对象,执行以下操作之一:
    • 允许在对其进行引用时,自动进行重新编译
    • 运行脚本 utlrp.sql 强制使用以下过程对所有无效 PL/SQL 对象进行重新编译:

a) 以 SYS 身份连接至数据库:

             SQL> CONNECT / AS SYS;

b) 运行  utlrp.sql

SQL> @?/rdbms/admin/utlrp.sql

如果脚本显示任何指示,则按照这些指示执行,然后再次运行脚本。

如果脚本异常终止而未显示任何指示,则再次运行脚本。