10.3 DBMS_DDL: Compiling and Analyzing ObjectsThe DBMS_DDL package provides access from within PL/SQL to two DDL (Data Definition Language) statements. It also offers special administrative services that are not available through DDL syntax (Oracle8 only). 10.3.1 Getting Started with DBMS_DDLThis DBMS_DDL package is created when the Oracle database is installed. The dbmsdesc.sql script (found in the built-in packages source code directory, as described in Chapter 1 ) contains the source code for this package's specification. This script is called by catproc.sql , which is normally run immediately after database creation. The script creates the public synonym DBMS.DDL for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package. DBMS_DDL programs "run as user," which means that they execute with the privileges of the user who calls that program.
10.3.1.1 DBMS_DDL programsTable 10-3 shows the programs defined in DBMS_DDL.
DBMS_DDL does not define any exceptions or nonprogram elements. 10.3.2 Compiling PL/SQL ObjectsYou can recompile PL/SQL objects that are already stored in the database by calling the ALTER_COMPILE procedure. 10.3.2.1 The DBMS_DDL.ALTER_COMPILE procedureHere's the header for this procedure: PROCEDURE DBMS_DDL.ALTER_COMPILE (type IN VARCHAR2 ,schema IN VARCHAR2 ,name IN VARCHAR2); Here are the possible values you can provide for the type parameter (enclosed in single quotes when you pass them to the procedure) and the actions that result:
The schema and name arguments are case-sensitive. In almost every instance, the names of your PL/SQL objects are stored in uppercase (you must enclose those names in double quotes when creating the objects if you want mixed case). You will therefore need to specify the names in uppercase when you call ALTER_COMPILE. Note the following about using this package:
In order to compile a program, you must own that program (in other words, the schema you specify is the owner of the program for which you request compilation) or your schema must have been granted the ALTER ANY PROCEDURE privilege to compile another schema's programs. The following command from a DBA account in SQL*Plus enables the SCOTT account to compile the programs of other schemas: SQL> GRANT ALTER ANY PROCEDURE TO SCOTT; Here are a few examples of usage, assuming that SCOTT has been granted the ALTER ANY PROCEDURE privilege:
10.3.2.1.1 ExceptionsThe ALTER_COMPILE procedure may raise any of the following exceptions:
Notice that these exceptions are not defined in the specification of the package. Instead, ALTER_COMPILE simply calls RAISE_APPLICATION_ERROR with one of the above error numbers. These error numbers may therefore conflict with your own -20NNN error number usages. If you embed calls to ALTER_COMPILE inside your application or utility, watch out for the confusion such conflicts can cause. 10.3.2.1.2 ExampleAt first glance, you might say this of the ALTER_COMPILE procedure: "Why bother? The command is available in SQL*Plus. I'll just execute the ALTER PROCEDURE XXX COMPILE command when I need to recompile." The big difference between that command and the ALTER_COMPILE procedure, of course, is that you can run the latter within a PL/SQL block or program. This allows you to apply the full power and flexibility of a procedural language to make the utility more useful. This technique is demonstrated by my recompile procedure, which follows. This program recompiles all stored PL/SQL objects that are identified by the parameters you provide to it. /* Filename on companion disk: recmpile.sp */* CREATE OR REPLACE PROCEDURE recompile (status_in IN VARCHAR2 := 'INVALID', name_in IN VARCHAR2 := '%', type_in IN VARCHAR2 := '%', schema_in IN VARCHAR2 := USER) IS v_objtype VARCHAR2(100); CURSOR obj_cur IS SELECT owner, object_name, object_type FROM ALL_OBJECTS WHERE status LIKE UPPER (status_in) AND object_name LIKE UPPER (name_in) AND object_type LIKE UPPER (type_in) AND owner LIKE UPPER (schema_in) ORDER BY DECODE (object_type, 'PACKAGE', 1, 'FUNCTION', 2, 'PROCEDURE', 3, 'PACKAGE BODY', 4); BEGIN FOR rec IN obj_cur LOOP IF rec.object_type = 'PACKAGE' THEN v_objtype := 'PACKAGE SPECIFICATION'; ELSE v_objtype := rec.object_type; END IF; DBMS_DDL.ALTER_COMPILE (v_objtype, rec.owner, rec.object_name); DBMS_OUTPUT.PUT_LINE ('Compiled ' || v_objtype || ' of ' || rec.owner || '.' || rec.object_name); END LOOP; END; / Here are a few interesting aspects to this procedure:
So to recompile all invalid programs in my schema, I would enter this command: SQL> exec recompile To recompile only package bodies that are invalid, I would execute the following: SQL> exec recompile (type_in => 'PACKAGE BODY') 10.3.3 Computing Statistics for an ObjectUse the ANALYZE_OBJECT procedure to compute statistics for the specified table, index, or cluster. 10.3.3.1 The DBMS_DDL. ANALYZE_OBJECT procedureHere is the header for this procedure: PROCEDURE DBMS_DDL.ANALYZE_OBJECT (type IN VARCHAR2 ,schema IN VARCHAR2 ,name IN VARCHAR2 ,method IN VARCHAR2 ,estimate_rows IN NUMBER DEFAULT NULL ,estimate_percent IN NUMBER DEFAULT NULL ,method_opt IN VARCHAR2 DEFAULT NULL); Parameters are summarized in the following table.
The schema and name arguments are case-sensitive. In almost every instance, the names of your PL/SQL objects are stored in uppercase. (Enclose those names in double quotes when creating the objects if you want mixed case). You will therefore need to specify the names in uppercase when you call COMPUTE_STATISTICS. This procedure offers a procedural equivalent to the SQL DDL statement: ANALYZE TABLE|CLUSTER|INDEX [<schema>.]<name> [<method>] STATISTICS [SAMPLE <n> [ROWS|PERCENT]] If the type you specify is not one of TABLE, CLUSTER, or INDEX, the procedure returns without taking action.
Here are the valid entries for the method argument, and the resulting activity. (Remember that when you pass one of these values, they must be enclosed in single quotes.)
Here are the valid method_opt entries and the resulting impact:
10.3.3.1.1 ExceptionsDBMS_DDL.ANALYZE_OBJECT may raise any of the following exceptions:
Notice that these exceptions are not defined in the specification of the package. Instead, ANALYZE_OBJECT simply calls RAISE_APPLICATION_ERROR with one of the above error numbers. These error numbers may therefore conflict with your own -20NNN error number usages. If you embed calls to ANALYZE_OBJECT inside your application or utility, watch out for the confusion such conflicts can cause. 10.3.4 Setting Referenceability of TablesWhen you create an object table, it automatically becomes referenceable, unless you use the OID AS clause when creating the table. The OID AS clause allows you to create an object table and to assign to the new table the same embedded object ID (EOID) as another object table of the same type. After you create a new table using the OID AS clause, you end up with two object tables with the same EOID; the new table is not referenceable, the original one is. All references that previously pointed to the objects in the original table still reference the same objects in the same original table. If you execute the ALTER_TABLE_REFERENCEABLE procedure of the DBMS_DDL package on the new table, it will make that table the referenceable table replacing the original one. Any references will then point to the objects in the new table instead of to the objects in the original table. With DBMS_DDL, available only in Oracle8, you can both make a table referenceable and reverse that step. 10.3.4.1 The DBMS_DDL. (Oracle8 only)To make a table referenceable, call the following procedure: PROCEDURE DBMS_DDL.ALTER_TABLE_REFERENCEABLE (table_name IN VARCHAR2 ,table_schema IN VARCHAR2 DEFAULT NULL ,affected_schema IN VARCHAR2 DEFAULT NULL); Parameters are summarized in the following table.
This program alters the specified object table, table_schema.table_name, so it becomes the referenceable table for the specified schema, affected_schema. This program is the equivalent of the following SQL statement, ALTER TABLE [<table_schema>.]<table_name> REFERENCEABLE FOR <affected_schema> which is currently neither supported nor available as a DDL statement. You can obtain this effect only through a call to the ALTER_TABLE_REFERENCEABLE built-in package. Notice that each argument to this program is case-sensitive. ALTER_TABLE_REFERENCEABLE will not automatically convert to uppercase the table name you pass to it. You must make sure that the table and schema names you provide match exactly the case of the objects found inside the database. You will be able to execute this procedure successfully only if you have the appropriate privileges. Here are some rules to keep in mind:
One tricky aspect to the way this built-in is defined: the default affected_schema is PUBLIC. Combine this fact with the previous rules, and you discover that the simplest form of calling the built-in (providing only the table name), EXECUTE DBMS_DDL.ALTER_TABLE_REFERENCEABLE ('EMPOBJTAB'); will quite often fail with this error: ORA-20000: insufficient privileges, invalid schema name or table does not exist You will say to yourself, "But I own the table!" And then you will realize, "Oh, if I don't specify the affected schema, then PUBLIC is used and I do not have ALTER ANY TABLE or any of the other privileges needed." So all I can really do is this, EXECUTE DBMS_DDL.ALTER_TABLE_REFERENCEABLE ('EMPOBJTAB', USER, USER); and make sure that the command is applied only to my schema. 10.3.4.1.1 ExampleGenerally, you will use the ALTER_TABLE_REFERENCEABLE procedure when you want to replace an existing object table with a new table of the same structure. In this scenario, you will want to make sure that all EOIDS point to this new table. Here are the steps you would take to use ALTER_TABLE_REFERENCEABLE to make this "switch." (These steps are collected together using an employee table as an example in tabref.sql on the companion disk.)
10.3.4.1.2 ExceptionsThe ALTER_TABLE_REFERENCEABLE procedure may raise the following exception:
Notice that this exception is not defined in the specification of the package. Instead, this program simply calls RAISE_APPLICATION_ERROR with the previous error number. This error number may therefore conflict with your own -20NNN error number usages. If you embed calls to this procedure inside your application or utility, watch out for the confusion such a conflict can cause. 10.3.4.2 The DBMS_DDL. ALTER_TABLE_NOT_REFERENCEABLE procedure (Oracle8 only)For the affected schema, this procedure simply reverts to the default table referenceable for PUBLIC; that is, it simply undoes the previous ALTER_TABLE_REFERCEABLE call for this specific schema. The header follows: PROCEDURE DBMS_DDL.ALTER_TABLE_NOT_REFERENCEABLE (table_name IN VARCHAR2 ,table_schema IN VARCHAR2 DEFAULT NULL ,affected_schema IN VARCHAR2 DEFAULT NULL); Parameters are summarized in the following table.
This procedure is equivalent to the following SQL statement, ALTER TABLE [<table_schema>.]<table_name> NOT REFERENCEABLE FOR <affected_schema> which is currently neither supported nor available as a DDL statement. 10.3.4.2.1 ExceptionsThe ALTER_TABLE_NOT_REFERENCEABLE procedure may raise the following exception:
Notice that this exception is not defined in the specification of the package. Instead, this program simply calls RAISE_APPLICATION_ERROR with the preceding error number. This error number may therefore conflict with your own -20NNN error number usages. If you embed calls to this procedure inside your application or utility, watch out for the confusion such conflicts can cause.
Copyright (c) 2000 O'Reilly & Associates. All rights reserved. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|