Suppose that my formula for calculating total compensation for an employee is "salary plus commission." Here is that formula implemented in PL /SQL: CREATE OR REPLACE FUNCTION totcomp (sal_in IN NUMBER, comm_in IN NUMBER) RETURN NUMBER IS BEGIN RETURN sal_in + NVL (comm_in, 0); END; / Once this program is stored in the database, I can call it from within a query as follows: SQL> SELECT ename, totcomp (sal, comm) total_compensation FROM emp; ENAME TOTAL_COMPENSATION −−−−−−−−−− −−−−−−−−−−−−−−−−−− SMITH 800 MILLER 1300 You can also call a packaged function from within a SQL statement. In this case, however, you must also provide a special statement, the RESTRICT_REFERENCES pragma, to enable that function for use inside SQL. Here, for example, is the code you would have to write to place totcomp inside a package and still call it from a query: CREATE OR REPLACE PACKAGE empcomp IS FUNCTION totcomp (sal_in IN NUMBER, comm_in IN NUMBER) RETURN NUMBER; PRAGMA RESTRICT_REFERENCES (total, WNDS, RNDS, WNPS, RNPS); END; / CREATE OR REPLACE PACKAGE BODY empcomp IS FUNCTION totcomp (sal_in IN NUMBER, comm_in IN NUMBER) RETURN NUMBER IS BEGIN RETURN (sal_in + NVL (comm_in, 0)); END; END; / The line in bold is the statement asserting that the empcomp.total function does not violate any of the restrictions on functions in SQL. Here is how you would call this packaged function inside SQL: SQL> SELECT ename, empcomp.total (sal, comm) total_comp from emp; ENAME TOTAL_COMP −−−−−−−−−− −−−−−−−−−− SMITH 800 MILLER 1300 The same rules apply for built−in packaged programs callable from SQL. Oracle Corporation itself must provide a RESTRICT_REFERENCES pragma in its own package specifications for any procedure or function that is to be used from within SQL. And since Oracle did not pragmatize built−in packages prior to Oracle 7.3.3, you will not be able to call built−in packaged programs from SQL (directly or indirectly) until you [Appendix A] What's on the Companion Disk? 1.3.7 Accessing Built−in Packaged Technology from Within SQL 31 install Oracle 7.3.4 or later. If you try to call a packaged function in SQL that does not have such a pragma, you will receive this error: SQL> SELECT utl_file.fopen ('/tmp', ename || '.dat', 'R') 2 FROM employee; select utl_file.fopen ('a', 'b', 'r') from employee * ERROR at line 1: ORA−06571: Function FOPEN does not guarantee not to update database Don't you hate those double negatives? You will also encounter this same error if you try to execute a function in SQL that, in turn, calls a packaged procedure that does not have a pragma. For example, the DBMS_JOB.SUBMIT procedure is not "pragma−tized" for use in SQL. Consequently, the following function (exactly the same as that shown earlier, except for the addition of the procedure call) will not be executable within SQL: CREATE OR REPLACE FUNCTION totcomp (sal_in IN NUMBER, comm_in IN NUMBER) RETURN NUMBER IS myjob INTEGER; BEGIN DBMS_JOB.SUBMIT (myjob, 'calc_totals;'); RETURN (sal_in + NVL (comm_in, 0)); END; / Here is the error I get when I try to execute my new and "improved" function: SQL> SELECT totcomp (salary, NULL) FROM employee; SELECT totcomp (salary, NULL) FROM employee * ERROR at line 1: ORA−06571: Function TOTCOMP does not guarantee not to update database 1.3.7.1 Calling a packaged function in SQL If you want to use a packaged function in a SQL statement, it must have a RESTRICT_REFERENCES pragma. If that is the case, you are all set! Just call the function as you would call a built−in function such as SUBSTR or TO_CHAR. Suppose that I am working on the large objects stored in files. The DBMS_LOB package includes several RESTRICT_REFERENCES pragmas. Here is the pragma for the GETLENGTH function: PRAGMA RESTRICT_REFERENCES (getlength, WNDS, RNDS, WNPS, RNPS); Here are the meanings for each of those purity levels: WNDS Writes No Database State. In other words, does not make any changes to database structures by calling an INSERT, UPDATE, or DELETE. WNPS Writes No Package State. In other words, does not change the values of any package data structures. RNDS [Appendix A] What's on the Companion Disk? 1.3.7 Accessing Built−in Packaged Technology from Within SQL 32 Read No Database State. In other words, does not SELECT from any database tables or other database objects. RNPS Reads No Package State. In other words, does not reference any package data structures. The absolute minimum purity level required to allow a program to be used (directly or indirectly) inside SQL is WNDS. You can never update the database. In some situations, such as when you want to call a function from within a WHERE clause, the program will also need to have asserted the WNPS purity level. Since DBMS_LOB.GETLENGTH asserts all four purity levels, I can use it in SQL, both in the SELECT list of a query and even in the WHERE clause. Here is an example; in it, I display the length of each photograph stored in the archives for my family: SELECT DBMS_LOB.GETLENGTH (portrait_lob_loc) FROM photo_archive WHERE family = 'FEUERSTEIN' AND DBMS_LOB.GETLENGTH (portrait_lob_loc) < 1000; Table 1−4 provides a complete list of all packaged programs that can be called (directly or indirectly) from within a SQL statement, the purity levels for each, and the Oracle versions in which these purity levels become available (thus enabling you to call the programs from within SQL). The rest of this section explains how to use packaged functions and procedures, and the meaning of the various purity levels. Table 1.4: Purity Levels for Oracle Built−in Package Programs Package Program WNDS WNPS RNDS RNPS DBMS_LOB COMPARE a X X X X FILEEXISTS a X X X X FILEISOPEN X X X X GETLENGTH X X X X INSTR X X X X SUBSTR X X X X DBMS_OUTPUT DISABLE b X X ENABLE b X X GET_LINE b X X GET_LINES b X X NEW_LINE b X X PUT b X X [Appendix A] What's on the Companion Disk? 1.3.7 Accessing Built−in Packaged Technology from Within SQL 33 PUT_LINE b X X DBMS_PIPE CREATE_PIPE b X X NEXT_ITEM_TYPE b X X PACK_MESSAGE b X X PACK_MESSAGE_RAW b X X PACK_MESSAGE_ROWID b X X PURGE b X X RECEIVE_MESSAGE b X X REMOVE_PIPE b X X RESET_BUFFER b X X SEND_MESSAGE b X X UNIQUE_SESSION_NAME b X X X UNPACK_MESSAGE b X X UNPACK_MESSAGE_RAW b X X UNPACK_MESSAGE_ROWID b X X DBMS_ROWID ROWID_BLOCK_NUMBER a X X X X ROWID_CREATE a X X X X ROWID_INFO a X X X X ROWID_OBJECT a X X X X ROWID_RELATIVE_FNO a X X X ROWID_ROW_NUMBER a X X X X ROWID_TO_ABSOLUTE a X X X X [Appendix A] What's on the Companion Disk? 1.3.7 Accessing Built−in Packaged Technology from Within SQL 34 ROWID_TO_EXTENDED a X X X ROWID_TO_RESTRICTEDa X X X X ROWID_TYPE a X X X X ROWID_VERIFYa X X X DBMS_SESSION UNIQUE_SESSION_ID b X X X DBMS_STANDARD DELETING b X X X INSERTING b X X X RAISE_APPLICATION_ERROR b X X X X UPDATING b X X X DBMS_UTILITY DATA_BLOCK_ADDRESS_BLOCK b X X X X DATA_BLOCK_ADDRESS_FILE b X X X X GET_HASH_VALUE b X X X X MAKE_DATA_BLOCK_ADDRESS b X X X X PORT_STRING b X X X X UTL_RAW BIT_AND b x x x x BIT_COMPLEMENT b X X X X BIT_OR b X X X X BIT_XOR b X X X X CAST_TO_RAW b X X X X COMPARE b X X X X CONCAT b X X X X CONVERT b X X X X COPIES b X X X X LENGTH b X X X X [Appendix A] What's on the Companion Disk? 1.3.7 Accessing Built−in Packaged Technology from Within SQL 35 . function that is to be used from within SQL. And since Oracle did not pragmatize built−in packages prior to Oracle 7.3.3, you will not be able to call built−in packaged programs from SQL (directly or. TOTAL_COMP −−−−−−−−−− −−−−−−−−−− SMITH 800 MILLER 1300 The same rules apply for built−in packaged programs callable from SQL. Oracle Corporation itself must provide a RESTRICT_REFERENCES pragma in its. you [Appendix A] What's on the Companion Disk? 1.3.7 Accessing Built−in Packaged Technology from Within SQL 31 install Oracle 7.3.4 or later. If you try to call a packaged function in SQL