r_lower := UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('a'), UTL_RAW.CAST_TO_RAW('z')); /* Create a raw string of uppercase followed by lowercase letters */ r_upper_lower := UTL_RAW.CONCAT(r_upper , r_lower); /* Create a raw string of lowercase followed by uppercase letters */ r_lower_upper := UTL_RAW.CONCAT(r_lower , r_upper); /* Translate upper to lower and lower to upper for the input string */ r_out := UTL_RAW.TRANSLATE(r_in , r_upper_lower , r_lower_upper ); /* Convert the result back to varchar2 and return the result */ return(UTL_RAW.CAST_TO_VARCHAR2(r_out)); END; / Sample output follows: SQL> select switch_case('This Is A Test') from dual; SWITCH_CASE('THISISATEST') −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− tHIS iS a tEST 9.2.3.16 The UTL_RAW.TRANSLITERATE function The TRANSLITERATE function translates bytes in the input raw sting r, substituting bytes found in from_set with positionally corresponding bytes in to_set. The translated string is returned. Bytes in r that do not appear in from_set are not modified. If from_set is longer than to_set, then the unmatched bytes in from_set are right−padded with the pad byte. The return string is always the same length as the input string r. The specification follows: FUNCTION UTL_RAW.TRANSLITERATE (r IN RAW ,to_set IN RAW DEFAULT NULL ,from_set IN RAW DEFAULT NULL ,pad IN RAW DEFAULT NULL) RETURN RAW; TRANSLITERATE is similar to TRANSLATE, but it differs in that the return string is always the same length as the input string (r). TRANSLITERATE is just like TRANSLATE if to_set and from_set are the same length. If from_set is longer than to_set, then to_set is right−padded with the pad byte. TRANSLITERATE allows NULL from_set, to_set, and pad parameters. Parameters are summarized in the following table. Parameter Description r Input string to be translated from_set The list of bytes to be translated; the default is 0x00 through 0xFF to_set The list of bytes that from_set bytes are translated to; the default is NULL pad If from_set is shorter than to_set, then this pad byte is the translation character for any unmatched bytes in from_set; the default is 0x00 9.2.3.16.1 Exceptions The VALUE_ERROR exception (ORA−6502) is raised if r is null or has 0 length. The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged. [Appendix A] What's on the Companion Disk? 9.2.3 The UTL_RAW Interface 461 9.2.3.16.2 Restrictions This program asserts the following purity level with the RESTRICT_REFERENCES pragma: PRAGMA RESTRICT_REFERENCES(TRANSLITERATE, WNDS, RNDS, WNPS, RNPS); 9.2.3.16.3 Example An example use of TRANSLITERATE is a make_lower function that switches uppercase characters in a text string to lowercase characters, converting spaces, dashes, and dots to underscores. This function also makes use of other UTL_RAW functions: CAST_TO_RAW, XRANGE, and CONCAT. This method may not be the most efficient technique for this conversion, but it serves to demonstrate some UTL_RAW functions in an easily understandable context. CREATE OR REPLACE FUNCTION make_lower(c_in IN VARCHAR2) RETURN VARCHAR2 IS r_in RAW(2000); r_out RAW(2000); r_upper RAW(48); r_lower RAW(32); r_underscore RAW(1); BEGIN −− convert the input to raw r_in := UTL_RAW.CAST_TO_RAW(c_in); r_underscore := UTL_RAW.CAST_TO_RAW('_'); −− start the from characters with the uppercase letters r_upper := UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('A'),UTL_RAW.CAST_TO_RAW('Z')); −− space, dash and dot to the from list of characters r_upper := UTL_RAW.CONCAT(r_upper,UTL_RAW.CAST_TO_RAW(' ') ,UTL_RAW.CAST_TO_RAW('−'),UTL_RAW.CAST_TO_RAW('.')); −− set the to characters to be lowercase letters r_lower := UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('a'),UTL_RAW.CAST_TO_RAW('z')); −− convert the uppercase to lowercase and punctuation marks to underscores r_out := UTL_RAW.TRANSLITERATE(r_in , r_lower , r_upper, r_underscore); −− return the character version return(UTL_RAW.CAST_TO_VARCHAR2(r_out)); END; Sample output follows: SQL> exec DBMS_OUTPUT.PUT_LINE (make_lower('This.is−A tEst')); this_is_a_test 9.2.3.17 The UTL_RAW.XRANGE function The XRANGE function returns a raw string containing all bytes in order beginning with the start_byte parameter and ending with end_byte. If start_byte is greater than end_byte, then the return string wraps from 0XFF to 0X00. FUNCTION UTL_RAW.XRANGE (start_byte IN RAW DEFAULT 0x00 ,end_byte IN RAW DEFAULT 0xFF) RETURN RAW; The parameters for this program are summarized in the following table. Parameter Description [Appendix A] What's on the Companion Disk? 9.2.3 The UTL_RAW Interface 462 start_byte Start byte; the default is 0x00. end_byte End byte; the default is 0xFF. 9.2.3.17.1 Restrictions This program asserts the following purity level with the RESTRICT_REFERENCES pragma: PRAGMA RESTRICT_REFERENCES(XRANGE, WNDS, RNDS, WNPS, RNPS); 9.2.3.17.2 Example For an example of XRANGE, see the example for TRANSLATE or TRANSLITERATE. 9.2.4 UTL_REF: Referencing Objects (Oracle8.0.4) The UTL_REF package provides a PL/SQL interface that allows you to select and modify objects (instances of an object type) in an object table without having to specify or know about the underlying database table. With UTL_REF, you only need a reference to the object in order to identify it in the database and perform the desired operations. With UTL_REF, you can do any of the following: • Select or retrieve an object from the database • Lock an object so that no other session can make changes to the object • Select and lock an object in a single operation (similar to SELECT FOR UPDATE) • Update the contents of an object • Delete an object You will typically use UTL_REF programs when you have references to an object and one of the following is true: • You do not want to have to resort to an SQL statement to perform the needed action. • You do not even know the name of the table that contains the object, and therefore cannot rely on SQL to get your job done. Before getting into the details, let's start with an initial example of how you might use the UTL_REF packages. You will be able to use UTL_REF programs only to select or modify objects in an object table. An object table is a table in which each row of the table is an object. Here are the steps one might take to create an object table. First, create an object type: CREATE TYPE hazardous_site_t IS OBJECT ( [Appendix A] What's on the Companion Disk? 9.2.3 The UTL_RAW Interface 463 name VARCHAR2(100), location VARCHAR2(100), dixoin_level NUMBER, pcb_level NUMBER, METHOD FUNCTION cleanup_time RETURN NUMBER); Now you can create a table of these objects: CREATE TABLE hazardous_sites OF hazardous_site_t; As you will see in the headers for the UTL_REF programs, Oracle has provided a special parameter−passing syntax called ANY. This syntax allows us to pass references and objects of any object type in and out of the programs. This behavior is not otherwise available in Oracle8 built−in packages or the code that you yourself can write using object types. 9.2.4.1 Getting Started with UTL_REF The UTL_REF package is created when the Oracle8.0.4 (or later) database is installed. The utlref.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. The script is called by catproc.sql, which is normally run immediately after the database is created. The script creates the public synonym UTL_REF for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of the package. Every program in this package runs as "owner." This means that programs in the UTL_REF package operate within the privileges of the session running those programs. You will be able to select and modify only objects to which your session has been granted the necessary privileges. 9.2.4.1.1 UTL_REF programs Table 9.5 lists the programs defined for the UTL_REF packages. Table 9.5: UTL_REF Programs Name Description Use in SQL DELETE_OBJECT Deletes an object from the underlying object table No LOCK_OBJECT Locks an object so that another session cannot change the object No SELECT_OBJECT Selects an object based on its reference, returning that object as an OUT argument No UPDATE_OBJECT Updates the object specified by the reference by replacing it with the object you pass to the program No UTL_REF does not declare any nonprogram elements. 9.2.4.1.2 UTL_REF exceptions UTL_REF does not declare any exceptions. However, you may encounter any of the following Oracle exceptions when running the UTL_REF programs: ORA−00942 Insufficient privileges. You must have the appropriate privileges on the underlying database table. ORA−01031 [Appendix A] What's on the Companion Disk? 9.2.4 UTL_REF: Referencing Objects (Oracle8.0.4) 464 Insufficient privileges. You attempted to update an object table on which you have only SELECT privileges. You must have the appropriate privileges on the underlying database table. ORA−08177 Cannot serialize access for this transaction. You have tried to change data after the start of a serialized transaction. ORA−00060 Deadlock detected while waiting for resource. Your session and another session are waiting for a resource locked by the other. You will need to wait or ROLLBACK. ORA−01403 No data found. The REF is NULL or otherwise not associated with an object in the database. 9.2.5 UTL_REF Interface This section describes the programs available through the UTL_REF package. A single, extended example at the end of the chapter shows how you might be able to take advantage of the UTL_REF programs in your own applications. 9.2.5.1 The UTL_REF.DELETE_OBJECT procedure Use the DELETE_OBJECT procedure to delete an object (actually, the row containing that object) specified by the given reference. The header is, PROCEDURE UTL_REF.DELETE_(reference IN REF ANY); where reference identifies the object. This program effectively substitutes for the following kind of SQL statement: DELETE FROM the_underlying_object_table t WHERE REF (t) = reference; In contrast to this SQL statement, with DELETE_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object. 9.2.5.1.1 Restrictions Note the following restrictions on calling DELETE_OBJECT: • The program does not assert a purity level with the RESTRICT_REFERENCES pragma. • You cannot call this program from within an SQL statement, either directly or indirectly. 9.2.5.2 The UTL_REF.LOCK_OBJECT procedure Use the LOCK_OBJECT procedure to lock or lock and retrieve an object for a given reference. The header is overloaded as follows: PROCEDURE UTL_REF.LOCK_OBJECT (reference IN REF ANY); PROCEDURE UTL_REF.LOCK_OBJECT (reference IN REF ANY [Appendix A] What's on the Companion Disk? 9.2.5 UTL_REF Interface 465 . otherwise available in Oracle8 built−in packages or the code that you yourself can write using object types. 9.2.4.1 Getting Started with UTL_REF The UTL_REF package is created when the Oracle8 .0.4 (or. of XRANGE, see the example for TRANSLATE or TRANSLITERATE. 9.2.4 UTL_REF: Referencing Objects (Oracle8 .0.4) The UTL_REF package provides a PL/SQL interface that allows you to select and modify. TABLE hazardous_sites OF hazardous_site_t; As you will see in the headers for the UTL_REF programs, Oracle has provided a special parameter−passing syntax called ANY. This syntax allows us to pass