Pragma Details

Embed Size (px)

Citation preview

  • 7/27/2019 Pragma Details

    1/16

    PRAGMA

    AUTONOMOUS TRANSACTIONS......................................................... . . . . . . . . . . . . . . . . . . . . . . . 1 DESCRIPTION................................................................................................................... 2 EXAMPLE Autonomous Transaction.................................................. . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 PRAGMA EXCEPTION..................................................................................... . . . . . . . . . . . 14 PRAGMA SERIALLY_REUSABLE............................................................................ 15 PRAGMA RESRTICTED_REFERENCE..................................................... . . . . . .. . . . . . . . . 17AUTONOMOUS TRANSACTIONSINTRO -

    Before the release of PL/SQL 8.1, each Oracle session could have at most oneactive transaction at a given time. In other words,any and all changes made in yoursession had to be either saved or erased in their entirety. This restriction haslong beenconsidered a drawback in the PL/SQL world. Developers have requested the abilitytoexecute and save or cancel certain DML statements (INSERT, UPDATE, DELETE)without affecting the overall sessions transaction.

    You can now accomplish this goal with the autonomous transaction feature ofPL/SQL 8.1 and above. When you define a PL/SQL block (anonymous block, procedure,function, packaged procedure, packaged function, database trigger) as an autonomoustransaction, you isolate the DML in that block from the callers transaction context.That block becomes an independent transaction that is started by another transaction,referred to as the main transaction.

    Within the autonomous transaction block, the main transaction is suspended. You

    performyour SQL operations, commit or roll back those operations, and resume the maintransaction.To define a PL/SQL block as an autonomous transaction you simply include thefollowing statement in your declaration section:Syntax --PRAGMA AUTONOMOUS_TRANSACTION;

    The pragma instructs the PL/SQL compiler to establish a PL/SQL block as autonomous or independent. For the purposes of the autonomous transaction, a PL/SQL block can be any of the following:Top-level (but not nested) anonymous PL/SQL blocks

    Functions and procedures, defined either in a package or as standalone programsMethods (functions and procedures) of a SQL object typeDatabase triggers1

    You can put the autonomous transaction pragma anywhere in the declaration sectio

  • 7/27/2019 Pragma Details

    2/16

    n ofyour PL/SQL block. The best option, however, would be to place it before any datastructure declarations. That way, anyone reading your code will immediately identify theprogram as an autonomous transaction.

    This pragma is the only syntax change made to PL/SQL to support autonomoustransactions. COMMIT, ROLLBACK, the DML statementsall the rest is as it wasbefore. However, these statements have a different scope of impact and visibility whenexecuted within an autonomous transaction, and you will have to include a COMMITorROLLBACK in your program.DESCRIPTIONThe AUTONOMOUS_TRANSACTION pragma instructs the PL/SQL compilerto mark a routine as autonomous (independent). An autonomous transaction is an

    independent transaction started by another transaction, the main transaction .Autonomous transactions let you suspend the main transaction, do SQL operations,commit or roll back those operations, then resume the main transaction.Usage NotesIn this context, the term routine includes

    Top-level (not nested) anonymous PL/SQL blocksLocal, standalone, and packaged functions and proceduresMethods of a SQL object typeDatabase triggers

    You cannot use the pragma to mark all subprograms in a package (or all methods in anobject type) as autonomous. Only individual routines can be marked autonomous. Youcan code the pragma anywhere in the declarative section of a routine. But, for r

    eadability,code the pragma at the top of the section.

    Once started, an autonomous transaction is fully independent. It shares no locks,resources, or commit-dependencies with the main transaction. So, you can log events,increment retry counters, and so on, even if the main transaction rolls back.

    Unlike regular triggers, autonomous triggers can contain transaction controlstatements such as COMMIT and ROLLBACK. Also, unlike regular triggers,autonomous triggers can execute DDL statements (such as CREATE and DROP)using native dynamic SQL.

    Changes made by an autonomous transaction become visible to other transactions whenthe autonomous transaction commits. The changes also become visible to the maintransaction when it resumes, but only if its isolation level is set to READ COMMITTED(the default).2

  • 7/27/2019 Pragma Details

    3/16

    If you set the isolation level of the main transaction to SERIALIZABLE, as follows,changes made by its autonomous transactions are not visible to the main transaction whenit resumes:

    When in the main transaction, rolling back to a savepoint marked before you started anautonomous transaction does not roll back the autonomous transaction. Remember,autonomous transactions are fully independent of the main transaction.

    If an autonomous transaction attempts to access a resource held by the main transaction(which cannot resume until the autonomous routine exits), a deadlock can occur.In thatcase, Oracle raises an exception in the autonomous transaction, which is rolledback if theexception goes unhandled.

    If you try to exit an active autonomous transaction without committing or rolling back,Oracle raises an exception. If the exception goes unhandled, the transaction isrolledback.

    Related TopicsEXCEPTION_INIT Pragma, RESTRICT_REFERENCES Pragma,SERIALLY_RESUABLE PragmaEXAMPLE Autonomous TransactionIn the following example, you mark a packaged function as autonomous:

    CREATE PACKAGE banking AS...FUNCTION balance (acct_id INTEGER) RETURN REAL;END banking;CREATE PACKAGE BODY banking AS

    ...

    FUNCTION balance (acct_id INTEGER) RETURN REALISPRAGMA AUTONOMOUS_TRANSACTION;my_bal REAL;BEGIN...END;END banking;In the example below, you mark a database trigger as autonomous. Unlike regulartriggers, autonomous triggers can contain transaction control statements.3

    CREATE TRIGGER parts_trigger

    BEFORE INSERT ON parts FOR EACH ROWDECLAREPRAGMA AUTONOMOUS_TRANSACTION;

    BEGININSERT INTO parts_log VALUES(:new.pnum, :new.pname);COMMIT; -- allowed only in autonomous triggersEND;******When to Use Autonomous Transactions

  • 7/27/2019 Pragma Details

    4/16

    You will want to define your program module as an autonomous transaction whenever

    you want to isolate the changes made in that module from the callers transactioncontext.Here are some specific ideas where autonomous transactions are useful:Logging mechanismThis is the classic example of the need for an autonomous transaction. You needto logerror information in a database table, but don't want that log entry to be a part of the

    logical transaction.Commits and rollbacks in your database triggersIf you define a trigger as an autonomous transaction, then you can commit and/orroll

    back in that code.Retry counterAutonomous transactions can help you keep track of how many times a user tries toconnect to a database or get access to a resource (you'll reject access after acertain

    number of attempts).Software usage meterYou want to keep track of how often a program is called during an application session.This information is not dependent on, and cannot affect, the transaction being processed

    in the application.Reusable application componentsIt is becoming ever more important to be able to offer standalone units of work(alsoknown as cartridges) that get their job done without any side effects on the calling

    environment. Autonomous transactions will play a crucial role in this area.4

    ******RULES AND EXCEPTIONS -

    While it is certainly very easy to add the autonomous transaction pragma to yourcode,there are some rules and restrictions on the use of this feature. You can only make a top-level anonymous block an autonomous transaction. The following construction willwork:

    DECLAREPRAGMA AUTONOMOUS_TRANSACTION;myempno NUMBER;BEGININSERT INTO emp VALUES (myempno, ...);COMMIT;END;/whereas this construction:DECLARE

  • 7/27/2019 Pragma Details

    5/16

    myempno NUMBER;BEGINDECLAREPRAGMA AUTONOMOUS_TRANSACTION;BEGININSERT INTO emp VALUES (myempno, ...);COMMIT;

    END;END;/results in this error:PLS-00710: PRAGMA AUTONOMOUS_TRANSACTION cannot be declared hereYou can now use COMMIT and ROLLBACK inside your database triggers. Theseactions will not affect the transaction that caused the database trigger to fire.

    If an autonomous transaction attempts to access a resource held by the main transaction(which has been suspended until the autonomous routine exits), you can cause a deadlockto occur in your program. Here is a simple example to demonstrate the problem. Aprocedure to perform an update is created, and then called after already havingall rowsupdated:

    5

    CREATE OR REPLACE PROCEDUREupdate_salary (dept_in IN NUMBER)ISPRAGMA AUTONOMOUS_TRANSACTION;

    CURSOR myemps ISSELECT empno FROM empWHERE deptno = dept_inFOR UPDATE NOWAIT;

    BEGIN

    FOR rec IN myempsLOOPUPDATE emp SET sal = sal * 2WHERE empno = rec.empno;END LOOP;COMMIT;END;/BEGINUPDATE emp SET sal = sal * 2;

    update_salary (10);END;/This results in the following error:

    ERROR at line 1:ORA-00054: resource busy and acquire with NOWAIT specified

    You cannot mark all subprograms in a package (or all methods in an object type)asautonomous with a single PRAGMA declaration. You must indicate autonomoustransactions explicitly in each program. For example, the following package specificationis invalid:CREATE PACKAGE warcrimes_pkg

  • 7/27/2019 Pragma Details

    6/16

    ASPRAGMA AUTONOMOUS_TRANSACTION;PROCEDURE register (

    culprit IN VARCHAR2, event IN VARCHAR2);END warcrimes_pkg;/6

    One consequence of this rule is that you cannot tell by looking at the packagespecification which, if any, programs will run as autonomous transactions.

    To exit without errors from an autonomous transaction program, you must performanexplicit commit or rollback. If the program (or any program called by it) has transactionspending, the runtime engine will raise an exceptionand then it will roll back thoseuncommitted transactions.Suppose, for example, that your job is to take over failing companies and make themprofitable by firing employees. You would then want to use this procedure:CREATE OR REPLACE PROCEDURE fire_em_allISPRAGMA AUTONOMOUS_TRANSACTION;BEGIN

    DELETE FROM emp;END;/

    You want to make the program an autonomous transaction because you dont want anyone to back out the changes when you are not looking. If you do not explicitly commit, when you run this procedure, the following error occurs:SQL> exec fire_em_allERROR at line 1ORA-06519: active autonomous transaction detected and rolled back

    The COMMIT and ROLLBACK statements end the active autonomoustransaction; they do not, however, force the termination of the autonomous routi

    ne. Youcan have multiple COMMIT and/or ROLLBACK statements inside your autonomousblock.An autonomous block is one in which autonomous transactions are expected. Zero,one,or more autonomous transactions can be executed within an autonomous block.

    You can roll back only to savepoints marked in the current transaction. When youare in an autonomous transaction you cannot roll back to a savepoint set in themain transaction. If you try to do so, the runtime engine will raise this exception:ORA-01086: savepoint 'your savepoint' never established

    The TRANSACTIONS parameter in the Oracle initialization file (INIT.ORA)specifies the maximum number of transactions allowed concurrently in a session.If youuse autonomous transactions (which run concurrently with the main transaction),you7

    might exceed this numberand raise an exceptionunless you raise theTRANSACTIONS value. This is the error you will get if you encounter this problem:

  • 7/27/2019 Pragma Details

    7/16

    ORA-01574: maximum number of concurrent transactions exceededThe default value for TRANSACTIONS in Oracle8i is 75.Using Autonomous Transactions from Within SQL

    Ever since Oracle 7.3, you have been able to call your own functions from withinSQL provided that you follow a variety of rules. The main one is this: you are not allowed to update the database. And you cant save or cancel changes from within the function.

    With the autonomous transaction feature, however, the picture changes. An autonomoustransaction program never violates the two database-related purity levels, RNDS(readsno database state) and WNDS (writes no database state), even if that program actuallydoes read from or write to the database. This is because those purity levels orconstraintsapply to the SQL statement (which, in this case, is the main transaction), yet anautonomous transactions DML actions never affect the main transaction.

    As long as you define a program to be an autonomous transaction, you can also call it directly or indirectly in a SQL statement. If your program cannot assert another purity level, such as WNPS (writes no package state), you may be restrict

    ed from calling that program in certain parts of the SQL statement, such as theWHERE clause.As an example, suppose that you want to keep a trace of all the rows that have beentouched by a query. This table is created:

    CREATE TABLE query_trace ( table_name VARCHAR2(30), rowid_info ROWID,queried_by VARCHAR2(30),queried_at DATE);This function is then created to perform the audit:

    CREATE OR REPLACE FUNCTION traceit (

    tab IN VARCHAR2,rowid_in IN ROWID)RETURN INTEGERIS

    BEGININSERT INTO query_trace VALUES (tab, rowid_in, USER, SYSDATE);RETURN 0;END;8

    /When you try to use this function inside a query, you get the following error:

    SQL> select ename, traceit ('emp', rowid) from emp;

    *ERROR at line 1:ORA-14551: cannot perform a DML operation inside a query

    However, if traceit is now transformed into an autonomous transaction by addingthepragma (and committing the results before the RETURN statement), the results arevery

  • 7/27/2019 Pragma Details

    8/16

    different. The query works, and the query_trace table is filled:SQL> SELECT ename, traceit ('emp', ROWID)2 FROM emp;ENAMETRACEIT ('EMP',ROWID)--------------------------KING

    0...MILLER

    014 rows selected.SQL>SQL> SELECT table_name, rowid_info, queried_by,2TO_CHAR (queried_at, 'HH:MI:SS') queried_at3 FROM query_trace;TABLE_NAME ROWID_INFOQUERIED_BY QUERIED_AT---------- ------------------ ---------- ----------emp

    AAADEPAACAAAAg0AAA SCOTT 05:32:54...empAAADEPAACAAAAg0AAN SCOTT 05:36:50

    You have other options when it comes to tracing queries: you can write to the screen with the DBMS_OUTPUT built-in package or send information to a pipe with DBMS_PIPE. Now that autonomous transactions are available, if you do want to sendinformation to a database table (or delete rows or update data, etc.), you can take that route instead, but be sure to analyze carefully the overhead of this approach.Transaction Visibility9

    The default behavior of autonomous transactions is that once a COMMIT orROLLBACK occurs in the autonomous transaction, those changes are visibleimmediately in the main transaction. Oracle offers a SET TRANSACTION statementoption to hide those changes from the main transaction:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;The default isolation level is READ COMMITTED, which means that as soon as changesare committed, they are visible to the main transaction.

    As is usually the case with the SET TRANSACTION statement, you must call it before

    you initiate your transactions (i.e., issue any SQL statements); in addition, the settingaffects your entire session, not just the current program. The following scriptdemonstrates the SERIALIZABLE isolation level at work.First, an autonomous transaction procedure is created:CREATE OR REPLACE PROCEDURE fire_em_allISPRAGMA AUTONOMOUS_TRANSACTION;BEGINDELETE FROM emp2;COMMIT;

  • 7/27/2019 Pragma Details

    9/16

    END;/A script is run that sets the isolation level to SERIALIZABLE, then the numberof rowsthat appear in the emp2 table at the following times are displayed:Before I call fire_em_allAfter I call fire_em_all but before the main transaction is committed or rolledbackAfter I commit in the main transaction, here is the script that is run:DECLAREPROCEDURE showcount (str VARCHAR2) ISnum INTEGER;

    BEGINSELECT COUNT(*) INTO num FROM emp2;DBMS_OUTPUT.PUT_LINE (str || ' ' || num);END;BEGINSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;showcount ('Before isolated AT delete');fire_em_all;showcount ('After isolated AT delete');

    10

    COMMIT;

    showcount ('After MT commit');END;/Here is the output from running the script:

    Before isolated AT delete 14After isolated AT delete 14After MT commit 0******************

    EXAMPLE FOR DATA BASE TRIGGER DEFINED AS AN AUTONOMOUSTRANSACTIONS

    The benefit of autonomous transactions for database triggers is that insidethose triggers you can now issue COMMITs and ROLLBACKs, statements that areotherwise not allowed in database triggers. The changes you commit and roll backwill

    not affect the main transaction that caused the database trigger to fire. They will only apply to DML activity taking place inside the trigger itself (or through stored program units called within the trigger).

    You may want to take an action in the database trigger that is not affected by t

    he ultimatedisposition of the transaction that caused the trigger to fire. For example, suppose thatyou want to keep track of each action against a table, whether or not the actioniscompleted. You might even want to be able to detect which actions failed. You can useautonomous transactions to do this.

    First, construct a simple autonomous transaction trigger on the ceo_compensation

  • 7/27/2019 Pragma Details

    10/16

    table that writes a simple message to the following ceo_comp_history table. Here are the two table definitions:CREATE TABLE ceo_compensation (company VARCHAR2(100),name VARCHAR2(100),compensation NUMBER,layoffs NUMBER);

    CREATE TABLE ceo_comp_history (name VARCHAR2(100),description VARCHAR2(255),

    occurred_on DATE);Here is the before-insert trigger to run all the elements in the script:CREATE OR REPLACE TRIGGER bef_ins_ceo_comp11

    BEFORE INSERT ONceo_ com pensation FOR EACH ROWDECLAREPRAGMA AUTONOMOUS_TRANSACTION;BEGININSERT INTOceo_ com p_history VALUES (:new.name, 'BEFORE INSERT', SYSDATE);COMMIT;

    END;/With this trigger in place, every insert attempt can be tracked, as shown in the stepsbelow:BEGININSERT INTOceo_ com pensation VALUES ('Mattel', 'Jill Barad', 9100000, 2700);INSERT INTOceo_ com pensation VALUES ('American Express Company','Harvey Golub', 33200000, 3300);INSERT INTOceo_ com pensation VALUES ('Eastman Kodak', 'George Fisher', 10700000, 20100);

    ROLLBACK; --I wish!END;/SELECT name,description,TO_CHAR (occurred_on,'MM/DD/YYYY HH:MI:SS') occurred_onFROMceo_ com p_history;NAMEDESCRIPTIONOCCURRED_ON-------------------- -----------------------------------Jill Barad

    BEFORE INSERT03/17/1999 04:00:56Harvey GolubBEFORE INSERT03/17/1999 04:00:56George FisherBEFORE INSERT03/17/1999 04:00:56Fine-tuning the database trigger

  • 7/27/2019 Pragma Details

    11/16

    But there is something of a problem with the trigger just defined. The trigger was defined as an autonomous transaction because the alert was performed in the body of the trigger. Suppose you want to perform some additional DML for the maintransaction here in the trigger. It wont be rolled back with the rest of the transaction (if a rollback occurs).12

    Generally, it is recommended that you not make a database trigger itself the autonomoustransaction. Instead, push all of the independent DML activity (such as writingto theaudit or history table) into its own procedure. Make that procedure the autonomoustransaction. Have the trigger call the procedure.First, create the audit procedure:

    CREATE OR REPLACE PROCEDURE audit_ceo_comp (name IN VARCHAR2,description IN VARCHAR2,occurred_on IN DATE)ISPRAGMA AUTONOMOUS_TRANSACTION;BEGIN

    INSERT INTO ceo_comp_history VALUES (audit_ceo_comp.name,audit_ceo_comp.description,audit_ceo_comp.occurred_on);COMMIT;END;/Then change the trigger to the following.

    CREATE OR REPLACE TRIGGER aft_ins_ceo_compAFTER INSERT ON ceo_compensation FOR EACH ROWDECLAREok BOOLEAN := is_valid_comp_info (:NEW.name);

    BEGINIF okTHENaudit_ceo_comp (:new.name, 'AFTER INSERT', SYSDATE);ELSERAISE VALUE_ERROR;

    END IF;END;/Note the following differences:

    The trigger is now an after-insert trigger, rather than a before-insert trigger.Waituntil after the INSERT to the compensation table takes place, then perform theaudit.13

    When the is_valid_comp_info function returns FALSE, do not even perform an

  • 7/27/2019 Pragma Details

    12/16

    audit. Instead, stop the transaction by raising an error. This demonstrates theotherreason you dont want the trigger itself to be autonomous. In some situations, youwill always want to perform an audit. Under other circumstances, however, youmay want to stop the main transaction by raising an exception. Both of thoseevents can't happen if the exception is raised in the same block and transactionasthe audit DML.

    As you take advantage of the new autonomous transaction pragma, plan out how youwill be using these new code elements. You will almost always be better off hiding the details of your new, independent transactions behind a procedural interface.PRAGMA EXCEPTION

    The EXCEPTION_INIT pragma is used to tell the compiler to associate a particularerror number with an exception declared in your program. You should only associate a single error code to a specific exception.

    This allows specification of a handler to take care of any exceptions that resultfrom an Oracle error. If you don't specify the EXCEPTION_INIT clause, you must allowfor processing of non-specified exceptions in the OTHERS exception area.

    The EXCEPTION_INIT clause must appear in the same declarative section as itsassociated exception handler.DECLAREexception_name EXCEPTION;PRAGMA EXCEPTION_INIT (exception_name, error_code_literal);BEGIN

    wheree xception_name is the name of an exception anderro r_code_l iteral is thenumber of the Oracle error (including the minus sign, if the error code is negative, as isalmost always the case).In the following program code, we declare and associate an exception for this error:

    ORA-2292 violated integrity constraining (OWNER.CONSTRAINT) -child record found.This error occurs if we try to delete a parent record while there are child records still inthat table. A child record is a record with a foreign key reference to the parent table:14

    PROCEDURE delete_company (company_id_in IN NUMBER)

    IS/* Declare the exception. */still_have_employees EXCEPTION;

    /* Associate the exception name with an error number. */PRAGMA EXCEPTION_INIT (still_have_employees, -2292);

    BEGIN/* Try to delete the company. */DELETE FROM companyWHERE company_id = company_id_in;

    EXCEPTION/* If child records were found, this exception is raised! */

  • 7/27/2019 Pragma Details

    13/16

    WHEN still_have_employees

    THENDBMS_OUTPUT.PUT_LINE(' Please delete employees for company first.');END;

    When you use EXCEPTION_INIT, you must supply a literal number for the secondargument of the pragma call. By explicitly naming this system exception, the purpose ofthe exception handler is self-evident.The EXCEPTION_INIT pragma improves the readability of your programs by assigningnames to otherwise obscure error numbers. You can employ the EXCEPTION_INITpragma more than once in your program. You can even assign more than one exceptionname to the same error number.***********PRAGMA SERIALLY_REUSABLE

    Prior to PL/SQL 8, any data declared in a package simply stayed around until theend of the session, whether or not it was needed any more by the application. While this is an important feature of PL/SQL packages (persistent, global data),it limits scalability since such memory grows linearly with the number of users.

    To help applications better manage memory usage, PL/SQL8 provides the pragmaSERIALLY_REUSABLE, which lets you mark some packages as "serially reusable."You can so mark a package if its state is needed only for the duration of a callto theserver (for example, an OCI call to the server, a PL/SQL client-to-server, or server-to-server RPC).

    The global memory for such packages is not kept in the memory area per user, butinsteadin a small SGA pool for reuse. Before reuse, the package global variables are initializedto NULL or to the default values provided.

    15

    The pool is kept in SGA memory so that the work area of a package can be reusedacrossusers who have requests for the same package. In this scheme, the maximum numberofwork areas needed for a package is only as many as there are concurrent users ofthepackage, which is typically much fewer than the total number of logged on users.Theuser of "serially reusable" packages does increase the shared-pool requirementsslightly,but this is more than offset by the decrease in the per-user memory requirements

    . Further,Oracle ages out work areas not in use when it needs to reclaim shared pool memory.Note: Use this feature with care. Many of your existing packages may absolutelyrely onthe persistent data feature.

    The keyword pragma signifies that the statement is a pragma (compiler directive).Pragmas are processed at compile time, not at run time. They do not affect the m

  • 7/27/2019 Pragma Details

    14/16

    eaningof a program; they simply convey information to the compiler.ExampleThe following example shows how global variables in a "serially reusable" packagebehave across call boundaries:CREATE OR REPLACE PACKAGE sr_pkgISPRAGMA SERIALLY_REUSABLE;

    num NUMBER := 0; -- Global variablePROCEDURE print_pkg;PROCEDURE init_pkg (n NUMBER);END sr_pkg;/CREATE OR REPLACE PACKAGE BODY sr_pkgIS-- the body is required to have the pragma since the

    -- specification of this package has the pragmaPRAGMA SERIALLY_REUSABLE;-- Print package statePROCEDURE print_pkg ISBEGIN

    DBMS_OUTPUT.PUT_LINE ('num: ' || sr_pkg.num);END;

    -- Initialize package statePROCEDURE init_pkg (n NUMBER) ISBEGINsr_pkg.num := n; --initialise global variableEND;END sr_pkg;16

    First, we enable output from SQL*Plus:SQLPLUS> set serveroutput on;Next, we initialize the package with a value of 4 and then display the package contents --all within a single PL/SQL block:

    SQLPLUS> begin-- initialize and print the packageSR_PKG.init_pkg(4);

    -- Print it in the same call to the server.-- We should see the new values.SR_PKG.print_pkg;end;/Statement processed.num: 4

    And we see that initial value of 4. If we had placed the call to SR_PKG.print_pkg insidethe same PL/SQL block, however, that package variable would lose its setting, asisshown in the following steps:

    SQLPLUS> begin-- We should see that the package state is reset to the-- initial (default) values.SR_PKG.print_pkg;

  • 7/27/2019 Pragma Details

    15/16

    end;/Statement processed.num: 0PRAGMA RESRTICTED_REFERENCE

    When a stand alone user defined function is used in a SQL statement, there is noguarantee that the function does not update the database. This guarantee can bemade by:Inspecting the code, or by Executing a SQL statement with the function. If the SQL parseidentifies an INSERT, UPDATE, or DELETE, the execution will fail. You do not have toexecute the specific path for the statement to fail. If the code contains ANY tablemodification SQL, you will know it.

    If user defined functions are used to any extent it is advisable to encapsulatethem withina package and designate this package as pure, that is, the functions in the package donot modify the database. The purity of the package is denoted with the PL/SQL17

    pragma: RESTRICT_REFERENCES. This pragma has one mandatory argument andthree optional arguments. The optional arguments define the level of the purity ofthefunction.RESTRICT_REFERENCES Pragma SyntaxRESTRICT_REFERENCES function_name

    RNDS - This asserts that the function reads no database state (does not query databasetables).WNDS - This asserts that the function writes no database state (does not modifydatabasetables).

    RNPS - This asserts that the function reads no package state (does not referencethevalues of packaged variables)WNPS - This asserts that the function writes no package state (does not change the valuesof packaged variables).TRUST - This asserts that the function can be trusted not to violate one or morerules.Usage Notes

    You can declare the pragma RESTRICT_REFERENCES only in a package spec or objecttype spec. You can specify up to four constraints (RNDS, RNPS, WNDS, WNPS) To call the function from parallel queries, you must specify all four constraints. No

    constraint implies another. For example, WNPS does not imply RNPS.When you specify TRUST, the function body is not checked for violations of theconstraints listed in the pragma. The function is trusted not to violate them.

    If you specify DEFAULT instead of a function name, the pragma applies to all functions in the package spec or object type spec (including, in the latter case, the system-defined constructor). You can still declare the pragma for individualfunctions. Such pragmas override the default pragma.

    A RESTRICT_REFERENCES pragma can apply to only one function declaration. So, a

  • 7/27/2019 Pragma Details

    16/16

    pragma that references the name of overloaded functions always applies to the nearestforegoing function declaration.The following code segment illustrates a package that provides procedures and functionsin employee data and uses the pragma RESTRICT_REFERENCES.create or replace package emp_pkg isfunction highest_paid_employee return emp.emp%name;-- returns the highest paid employee namefunction round_salary(n varchar2) return number;-- returns the ROUNDED salary of the employeepragma restrict_references(round_salary, WNDS);end emp_pkg;==================================THE END====================