Pragma in Detail
Pragma in Detail
A PRAGMA IS GENERALLY A LINE OF SOURCE CODE PRESCRIBING AN ACTION YOU WANT THE
COMPILER TO TAKE. ITS LIKE AN OPTION THAT YOU GIVE THE COMPILER.
IT CAN RESULT IN DIFFERENT RUNTIME BEHAVIOUR FOR THE PROGRAM BUT IT DOESN'T GET
TRANSLATED DIRECTLY INTO BYTECODE.
PRAGMA instruction_to_compiler;
1) AUTONOMOUS_TRANSACTION:
THE PRAGMA INSTRUCTS THE PLSQL COMPILER TO ESTABLISH A PLSQL BLOCK AS AUTONOMOUS OR
INDEPENDENT. FOR THE PURPOSES OF THE AUTONOMOUS TRANSACTION, A PLSQL BLOCK CAN BE
ANY OF THE FOLLOWING:
PRAGMA AUTONOMOUS_TRANSACTION;
YOU CAN PUT THE AUTONOMOUS TRANSACTION PRAGMA ANYWHERE IN THE DECLARATION SECTION
OF YOUR PL/SQL BLOCK.
AN AUTONOMOUS TRANSACTION STARTS WITH THE FIRST SQL STATEMENT OF THE PL/SQL BLOCK
AND ENDS WITH A COMMIT. IT STARTS WITHIN THE CONTEXT OF AN ANOTHER TRANSACTION
CALLED PARENT TRANSACTION AND INDEPENDENT OF IT (PARENT TRANSACTION).TO MAKE A
TRANSACTION AUTONOMOUS U HAVE TO DECLARE PRAGMA AUTONOMOUS_TRANSACTION AT THE
BEGINNING.
1) LOGGING MECHANISM
ON THE ONE HAND, YOU NEED TO LOG AN ERROR TO YOUR DATABASE LOG TABLE. ON THE OTHER
HAND, YOU NEED TO ROLL BACK YOUR CORE TRANSACTION BECAUSE OF THE ERROR. AND YOU
DON�T WANT TO ROLL BACK OVER OTHER LOG ENTRIES. WHAT�S A PERSON TO DO? GO
AUTONOMOUS!THIS IS PROBABLY THE MOST COMMON MOTIVATION FOR PL/SQL DEVELOPERS TO USE
AUTONOMOUS TRANSACTIONS AND IS EXPLORED AT THE END OF THIS SECTION.
IF YOU DEFINE A TRIGGER AS AN AUTONOMOUS TRANSACTION, THEN YOU CAN COMMIT AND/OR
ROLL BACK IN THAT TRIGGER, WITHOUT AFFECTING THE TRANSACTION THAT FIRED THE
TRIGGER. WHY IS THIS VALUABLE? YOU MAY WANT TO TAKE AN ACTION IN THE DATABASE
TRIGGER THAT IS NOT AFFECTED BY THE ULTIMATE DISPOSITION OF THE TRANSACTION THAT
CAUSED THE TRIGGER TO FIRE. FOR EXAMPLE, SUPPOSE THAT YOU WANT TO KEEP TRACK OF
EACH ACTION AGAINST A TABLE, WHETHER OR NOT THE ACTION COMPLETED. YOU MIGHT EVEN
WANT TO BE ABLE TO DETECT WHICH ACTIONS FAILED.
MUTATING TABLE TRIGGER ERRORS OCCUR WHEN A ROW-LEVEL TRIGGER ATTEMPTS TO READ FROM
OR WRITE TO THE TABLE FROM WHICH IT WAS FIRED. IF, HOWEVER, YOU MAKE YOUR TRIGGER
AN AUTONOMOUS TRANSACTION BY ADDING THE PRAGMA AUTONOMOUS_TRANSACTION STATEMENT AND
COMMITTING INSIDE THE BODY OF THE TRIGGER, THEN YOU WILL BE ABLE TO QUERY THE
CONTENTS OF THE FIRING TABLE�BUT YOU CAN ONLY SEE ALREADY COMMITTED CHANGES TO THE
TABLE. IN OTHER WORDS, YOU WILL NOT SEE ANY CHANGES MADE TO THE TABLE THAT CAUSED
THE FIRING OF THE TRIGGER. IN ADDITION, YOU WILL STILL NOT BE ALLOWED TO MODIFY THE
CONTENTS OF THE TABLE.
2) EXCEPTION_INIT
ITS A PRAGMA WHICH IS USED TO ASSOCIATE USER DEFINED EXCEPTION WITH ORACLE DEFINED
ERROR NUMBER.
-01422 - SYSTEM DEFINED ERROR CODE,IN GENERAL WE GET THIS TYPE OF ERROR CODE IN A
SITUATION LIKE OUR SELECT STATEMENT RETRIEVES ROWS MORE THAN THE CAPACITY OF
MEMORY VARIABLE DECLARED IN DECLARATIVE SECTION.
EXAMPLE
DECLARE
v_employeeid EMPLOYEES.EMPLOYEE_ID%TYPE;
unexpected_data EXCEPTION;
PRAGMA EXCEPTION_INIT (unexpected_data,-01422);
BEGIN
SELECT employee_id INTO v_employeeid FROM employees WHERE employee_id BETWEEN
101 AND 123;
EXCEPTION
WHEN unexpected_data
THEN
DBMS_OUTPUT.PUT_LINE ('SELECT STATEMENT IS RETRIVING ROWS MORE THAN THE
CAPABILITY OF MEMORY VARIABLE,KINDLY DECLARE CURSOR IN DECLARATIVE SECTION');
END;
3) RESTRICT_REFERENCES
WNDS
RNDS
WNPS
RNPS
PRAGMA RESTRICT_REFERENCES USES TO CONTROL THE SIDE EFFECTS OF PL/SQL SUBPROGRAMS.
EVERY PL/SQL SUBPROGRAMS MUST FOLLOW SOME RULES IN TERMS OF TRANSACTION CONTROL AND
SECURITY.
SYNTAX :-
RNDS � READ NO DATABASE STATE. ASSERTS THAT THE FUNCTION NOT TO READ OR QUERY
TABLES
RNPS � READ NO PACKAGE STATE. ASSERTS THAT THE FUNCTION NOT TO READ OR REFERENCE
PACKAGE VARIABLES
WNDS � WRITE NO DATABASE STATE. ASSERTS THAT THE FUNCTION NOT MODIFY DATABASE
TABLES
WNPS � WRITE NO PACKAGE STATE. ASSERTS THAT THE FUNCTION NOT MODIFY PACKAGE
VARIABLES
TRUST � ASSERTS THAT THE FUNCTION CAN BE TRUSTED NOT TO VIOLATE ONE OR MORE RULES.
USED ONLY WHEN C OR JAVA ROUTINES ARE CALLED FROM PL/SQL.
EXPLANATION :-
COMPILING��..
SQL> ../PKG_SALARY.SQL;
PACKAGE CREATED.
PACKAGE BODY CREATED.
EXECUTING���
COMPILING��..
SQL> ../PKG_SALARY.SQL;
PACKAGE CREATED.
NOTE:-
DEFAULT KEY WORD APPLIES PRAGMA RESTRICT_REFERENCES TO ALL OF THE SUB PROGRAMS IN
SIDE THE PACKAGE SEE BELOW EXAMPLE
NOTE:- NORMALLY FUNCTIONS ARE NOT CREATED FOR DML RELATED PROCESSES AND PRAGMA
RESTRICT_REFERENCES ARE NOT NECESSARY.
4) SERIALLY_REUSABLE
THE SERIALLY_REUSABLE PRAGMA SPECIFIES THAT THE PACKAGE STATE IS NEEDED FOR ONLY
ONE CALL TO THE SERVER (FOR EXAMPLE, AN OCI CALL TO THE DATABASE OR A STORED
PROCEDURE INVOCATION THROUGH A DATABASE LINK). AFTER THIS CALL, THE STORAGE FOR THE
PACKAGE VARIABLES CAN BE REUSED, REDUCING THE MEMORY OVERHEAD FOR LONG-RUNNING
SESSIONS.
THIS PRAGMA IS APPROPRIATE FOR PACKAGES THAT DECLARE LARGE TEMPORARY WORK AREAS
THAT ARE USED ONCE IN THE SAME SESSION.
THE STATE OF A SERIALLY REUSABLE PACKAGE PERSISTS ONLY FOR THE LIFETIME OF A CALL
TO THE SERVER. ON A SUBSEQUENT CALL TO THE SERVER, IF A REFERENCE IS MADE TO THE
SERIALLY REUSABLE PACKAGE, ORACLE CREATES A NEW INSTANTIATION (DESCRIBED BELOW) OF
THE SERIALLY REUSABLE PACKAGE AND INITIALIZES ALL THE GLOBAL VARIABLES TO NULL OR
TO THE DEFAULT VALUES PROVIDED. ANY CHANGES MADE TO THE SERIALLY REUSABLE PACKAGE
STATE IN THE PREVIOUS CALLS TO THE SERVER ARE NOT VISIBLE.
SINCE THE STATE OF A NON-REUSABLE PACKAGE PERSISTS FOR THE LIFETIME OF THE SESSION,
THIS LOCKS UP UGA MEMORY FOR THE WHOLE SESSION. IN APPLICATIONS SUCH AS ORACLE
OFFICE A LOG-ON SESSION CAN TYPICALLY EXIST FOR DAYS TOGETHER. APPLICATIONS OFTEN
NEED TO USE CERTAIN PACKAGES ONLY FOR CERTAIN LOCALIZED PERIODS IN THE SESSION AND
WOULD IDEALLY LIKE TO DE-INSTANTIATE THE PACKAGE STATE IN THE MIDDLE OF THE SESSION
ONCE THEY ARE DONE USING THE PACKAGE.
EXAMINE THE PACKAGE WITH & WITHOUT SERIALLY_REUSABLE: CREATE TWO PACKAGES WITH &
WITHOUT SERIALLY_REUSABLE
SQL_11G> BEGIN
2 WITHOUT_SERIALLY_REUSABLE_PKG.V_WITHOUT_SR := 100;
3 WITH_SERIALLY_REUSABLE_PKG.V_WITH_SR := 100;
4 END;
5 /
PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.
SQL_11G> BEGIN
2 DBMS_OUTPUT.PUT_LINE('WITHOUT_SERIALLY_REUSABLE_PKG.V_WITHOUT_SR VALUE IS -> '
|| WITHOUT_SERIALLY_REUSABLE_PKG.V_WITHOUT_SR );
SQL_11G> BEGIN
2 WITHOUT_SERIALLY_REUSABLE_PKG.V_WITHOUT_SR := 100;
3 WITH_SERIALLY_REUSABLE_PKG.V_WITH_SR := 100;
4 DBMS_OUTPUT.PUT_LINE('WITHOUT_SERIALLY_REUSABLE_PKG.V_WITHOUT_SR VALUE IS ->
' || WITHOUT_SERIALLY_REUSABLE_PKG.V_WITHOUT_SR );
5 DBMS_OUTPUT.PUT_LINE ('WITH_SERIALLY_REUSABLE_PKG.V_WITH_SR VALUES IS ->' ||
WITH_SERIALLY_REUSABLE_PKG.V_WITH_SR );
6 END;
7 /
� THE MAXIMUM NUMBER OF WORK AREAS NEEDED FOR A SERIALIZED PACKAGE IS THE NUMBER OF
CONCURRENT USERS OF THAT PACKAGE. THE INCREASED USE OF SGA MEMORY IS OFFSET BY THE
DECREASED USE OF UGA OR PROGRAM MEMORY. FINALLY, THE DATABASE AGES OUT WORK AREAS
NOT IN USE IF IT NEEDS TO RECLAIM MEMORY FROM THE SGA FOR OTHER REQUESTS.
5) PRAGMA INLINE
PRAGMA INLINE DIRECTIVE IS NEW FEATURE PROVIDED SINCE ORACLE DATABASE 11G.
THE PRAGMA INLINE DIRECTIVE IS USED TO DETERMINE IF SUBPROGRAM CALL IS INLINE OR
NOT.
PLSQL_OPTIMIZE_LEVEL:
Level 0: no compiler optimizations (PL/SQL compiled as is);
Level 1: high-level optimizations (such as moving constants out of loops);
Level 2: default level. Aggressive optimizations (such as rewriting cursor-for-
loops as array fetches) and in 11g, also inlining any subprograms that we
request with PRAGMA INLINE;
Level 3: most aggressive level: New in 11g, these will inline all subprograms where
possible (excluding those contained in built-in packages).
2-IF PLSQL_OPTIMIZE_LEVEL IS EQUAL TO 3, THEN THE INLINE IS DONE WITH HIGH PRIORITY
REGARDING PRAGMA INLINE VALUE, IF PRAGMA INLINE VALUE IS YES, IT WILL BE INLINED
WITH HIGH PRIORITY OTHERWISE NOT INLINED
YOU CAN USE IT ANYWHERE IN YOUR CODE AND IT HAS BELOW SYNTAX
PRAGMA INLINE(SUBPROGRAM_NAME,'YES');
PRAGMA INLINE(SUBPROGRAM_NAME,'NO');
DEMO
1- I WILL CREATE ANONYMOUS BLOCK FOR CALLING SUBPROGRAM WITHOUT USING PRAGMA INLINE
AND PRINT THE TIME USED TO EXECUTE THE CODE
DECLARE
LN$START_TIME NUMBER;
LN$END_TIME NUMBER;
LN$RESULT NUMBER;
FOR I IN 1 .. 10000000
LOOP
LN$RESULT := ADD_FIVE (I);
END LOOP;
LN$END_TIME := DBMS_UTILITY.GET_TIME;
DBMS_OUTPUT.
PUT_LINE ('TIME ELAPSED IS ' || TO_CHAR (LN$END_TIME - LN$START_TIME));
END;
DECLARE
LN$START_TIME NUMBER;
LN$END_TIME NUMBER;
LN$RESULT NUMBER;
FOR I IN 1 .. 10000000
LOOP
PRAGMA INLINE (ADD_FIVE, 'YES');
LN$RESULT := ADD_FIVE (I);
END LOOP;
LN$END_TIME := DBMS_UTILITY.GET_TIME;
DBMS_OUTPUT.
PUT_LINE ('TIME ELAPSED IS ' || TO_CHAR (LN$END_TIME - LN$START_TIME));
END;
I POSTED TIMER IN PLSQL AND SQL, YOU CAN USE IT FOR TRACKING TIMERS.
CONCLUSION
EXECUTING CALLING SUBPROGRAM WITH PRAGMA INLINE TAKES 160 AND WITHOUT IT TAKES 318,
SO USING PRAGMA INLINE PROVIDE US WITH HIGH PERFORMANCE.