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: • The user who executes this procedure must own the new table, and the affected schema must be the same as the user or PUBLIC; alternatively, the user must have ALTER ANY TABLE, SELECT ANY TABLE, and DROP ANY TABLE privileges. • If the affected schema is PUBLIC (and the user does not have ALTER ANY TABLE, SELECT ANY TABLE, and DROP ANY TABLE privileges), then the user must own the old mapping table (the table upon which the new table is based) for PUBLIC as well. 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 Example Generally, 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.) 1. First, you must have an object table already in place. Here is the code to create an employee object and then an object table for that object: CREATE TYPE empobj AS OBJECT (ename VARCHAR2(100), empno INTEGER); / CREATE TABLE emp OF empobj / 2. Now I will create a new object table based on the same object as the original table like this: [Appendix A] What's on the Companion Disk? 10.3.4 Setting Referenceability of Tables 511 CREATE TABLE empNew OF empobj OID AS emp / 3. Next, I transfer the contents of the original emp table to the empNew table. In Oracle8, unique object identifiers are automatically assigned to objects when they are stored as "table objects." It turns out that this identifier is stored in a hidden 16−byte RAW field, SYS_NC_OID$. This ID or OID can be referenced from columns in other tables, much like a foreign key. I use this in my INSERT to make sure the new table has the same identifier as the old. I also must use aliases for my table names for this process to work correctly. INSERT INTO empNew en (SYS_NC_OID$, en) SELECT SYS_NC_OID$, VALUE (eo) FROM emp eo / 4. Now I make the new table referenceable. Notice that the name of the table is passed in upper case and I explicitly pass USER as the schema to avoid the inadvertent usage of PUBLIC. EXECUTE DBMS_DDL.ALTER_TABLE_REFERENCEABLE ('EMPNEW', USER, USER); 5. For my final trick, I swap the names of the tables so that I end up with a new emp table. RENAME emp TO empOld; RENAME empNew TO emp; 10.3.4.1.2 Exceptions The ALTER_TABLE_REFERENCEABLE procedure may raise the following exception: ORA−20000 Insufficient privileges; invalid schema name, or table does not exist. 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. Parameter Description table_name The name of the table to be made nonreferenceable. You cannot use a synonym. The argument is case−sensitive. table_schema [Appendix A] What's on the Companion Disk? 10.3.4 Setting Referenceability of Tables 512 The schema containing the table to be made nonreferenceable. If NULL, then the current schema is used. The argument is case−sensitive. affected_schema The schema that is to be affected by this change. If NULL, then the current schema is used. PUBLIC may not be specified. The argument is case−sensitive. 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 Exceptions The ALTER_TABLE_NOT_REFERENCEABLE procedure may raise the following exception: ORA−20000 Insufficient privileges; invalid schema name or table does not exist. 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. 10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only) Copyright (c) 2000 O'Reilly & Associates. All rights reserved. [Appendix A] What's on the Companion Disk? 10.3.4 Setting Referenceability of Tables 513 Chapter 10 Miscellaneous Packages 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only) The DBMS_RANDOM package provides a built−in random number generator utility. Oracle Corporation suggests that this package will run faster than generators written in PL/SQL itself because DBMS_RANDOM calls Oracle's internal random number generator. Oracle describes this package as a relatively simple interface for a random number generator, limited to returning an 8−digit number. They recommend that you use the DBMS_CRYPTO_TOOLKIT package if you need a more sophisticated engine with more options. This package is available with Trusted Oracle.[3] [3] I must point out that DBMS_RANDOM is built on top of DBMS_CRYPTO_TOOLKIT, which is not documented in this book. As with any random number generator, before you can obtain any random numbers from DBMS_RANDOM, you must first initialize the package by providing a seed number with DBMS_RANDOM's INITIALIZE procedure. You can later reseed the random number generator via RANDOM_SEED. When you need a random number, issue a call to the RANDOM, which returns a random number for your use. Finally, when you no longer need to use the random number generator, terminate DBMS_RANDOM via the TERMINATE procedure. 10.4.1 Getting Started with DBMS_RANDOM The DBMS_RANDOM package is created when the Oracle database is first installed. The dbmsrand.sql script found in the built−in packages source code directory (described in Chapter 1) contains the source code for this package's specification. This script is called by catoctk.sql, which contains the scripts needed to use the PL/SQL Cryptographic Toolkit Interface. The scripts create the public synonym DBMS_RANDOM for the package and grant EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package. NOTE: If you are running Oracle8 Release 8.0.3, DBMS_RANDOM may not have been installed in your database. In this case, you need to execute the following scripts in the specified order from within your SYS account: dbmsoctk.sql, prvtoctk.plb, and finally dbmsrand.sql (it contains both the package specification and body for DBMS_RANDOM). Table 10.4 summarizes the DBMS_RANDOM programs. Table 10.4: DBMS_RANDOM Programs Name Description Use in SQL INITIALIZE Initializes the random number generator with a seed value No RANDOM Returns a random number No 514 SEED Resets the seed number used to generate the random number No TERMINATE Terminates the random number generator mechanism No DBMS_RANDOM does not declare any exceptions or nonprogram elements. 10.4.2 DBMS_RANDOM Interface This section describes the DBMS_RANDOM programs in the order in which they are typically used. 10.4.2.1 The DBMS_RANDOM.INITIALIZE procedure Before you can use the DBMS_RANDOM package, you must initialize it with this program, PROCEDURE DBMS_RANDOM.INITIALIZE (seed IN BINARY_INTEGER); where seed is the seed number used in the algorithm to generate a random number. You should provide a number with at least five digits to ensure that the value returned by the DBMS_RANDOM.RANDOM function will be sufficiently, well, random. The INITIALIZE procedure does not assert a purity level with the RESTRICT_REFERENCES pragma. 10.4.2.1.1 Example Here is an example of a call to initialize the DBMS_RANDOM package: SQL> exec DBMS_RANDOM.INITIALIZE (309666789); 10.4.2.2 The DBMS_RANDOM.SEED procedure (Oracle8 only) Once the random number generator has been initialized, you can change the seed value used by DBMS_RANDOM with the SEED procedure. The specification is, PROCEDURE DBMS_RANDOM.SEED(seed IN BINARY_INTEGER); where seed is the seed number used in the algorithm to generate a random number. As with INITIALIZE, you should provide a number with at least five digits to ensure that the value returned by the DBMS_RANDOM.RANDOM function will be sufficiently random. The SEED procedure does not assert a purity level with the RESTRICT_REFERENCES pragma. 10.4.2.2.1 Example Here is an example of a call to reseed the DBMS_RANDOM package: SQL> exec DBMS_RANDOM.SEED (455663349); 10.4.2.3 The DBMS_RANDOM.RANDOM function (Oracle8 only) Call the RANDOM function to retrieve a random number. FUNCTION DBMS_RANDOM.RANDOM RETURN BINARY_INTEGER; The RANDOM runction does not assert a purity level with the RESTRICT_REFERENCES pragma. [Appendix A] What's on the Companion Disk? 10.4.2 DBMS_RANDOM Interface 515 . Packages 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only) The DBMS_RANDOM package provides a built−in random number generator utility. Oracle Corporation suggests that this package will. 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. faster than generators written in PL/SQL itself because DBMS_RANDOM calls Oracle& apos;s internal random number generator. Oracle describes this package as a relatively simple interface for a random