CONDITIONAL COMPILATION
Oracle 10g release 2 introduces a new feature called Conditional compilation. It allows PLSQL compiler to compile a selected parts of a program based on conditions you specify with the $IF directive in PLSQL.
It enables you to customize the functionality in a PLSQL application without removing source code.
It utilizes the latest functionality with the latest database release or disable the new features to run the application against an older release of the database.
It activates the debugging or tracing functionality in the development environment and hide the functionality in the application in the production environment.
Compiler flags are identified by the "$$" prefix while the conditional control is provided by the $IF-$THEN-$ELSE-$END syntax.
Benefits of Conditional Compilation:
- Support multiple version of the same program in one source code
- Easy maintenance and debugging of code
- Easy migration of code to a different release of the database.
How does conditional compilation works?
- Selection directives: Use the $IF token
- Inquiry directives: Use the $$ token
- Error directives: Use the $ERROR token
We can use DBMS_DB_VERSION package to get the latest DB version. This is a package without package body. This package has two variables.
- version –> Its indicates the database version
- release –> Its indicates the latest release no.
Also, there are many variables which are initialized as False. But one variable is initialized as True. That indicates the current database version:
ver_le_19 constant boolean := TRUE;
So the current database version is 19.
SELECT TEXT FROM ALL_SOURCE WHERE LOWER(NAME) = 'dbms_db_version';
package dbms_db_version is
version constant pls_integer :=
19; -- RDBMS version number
release constant pls_integer := 0; -- RDBMS release number
/* The following boolean constants follow a naming convention. Each
constant gives a name for a boolean expression. For example,
ver_le_9_1 represents version <= 9 and release <= 1
ver_le_10_2 represents version <= 10 and release <= 2
ver_le_10 represents version <= 10
Code that references these boolean constants (rather than directly
referencing version and release) will benefit from fine grain
invalidation as the version and release values change.
A typical usage of these boolean constants is
$if dbms_db_version.ver_le_10 $then
version 10 and ealier code
$elsif dbms_db_version.ver_le_11 $then
version 11 code
$else
version 12 and later code
$end
This code structure will protect any reference to the code
for version 12. It also prevents the controlling package
constant dbms_db_version.ver_le_11 from being referenced
when the program is compiled under version 10. A similar
observation applies to version 11. This scheme works even
though the static constant ver_le_11 is not defined in
version 10 database because conditional compilation protects
the $elsif from evaluation if the dbms_db_version.ver_le_10 is
TRUE.
*/
/* Deprecate boolean constants for unsupported releases */
ver_le_9_1 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_9_1);
ver_le_9_2 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_9_2);
ver_le_9 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_9);
ver_le_10_1 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_10_1);
ver_le_10_2 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_10_2);
ver_le_10 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_10);
ver_le_11_1 constant boolean := FALSE;
PRAGMA DEPRECATE(ver_le_11_1);
ver_le_11_2 constant boolean := FALSE;
ver_le_11 constant boolean := FALSE;
ver_le_12_1 constant boolean := FALSE;
ver_le_12_2 constant boolean := FALSE;
ver_le_12 constant boolean := FALSE;
ver_le_18 constant boolean := FALSE;
ver_le_19 constant boolean := TRUE;
end dbms_db_version; SET SERVEROUTPUT ON;
BEGIN
DBMS_OUTPUT.PUT_LINE('DB_VERSION -> '||DBMS_DB_VERSION.VERSION);
DBMS_OUTPUT.PUT_LINE('RELEASE NO -> '||DBMS_DB_VERSION.RELEASE);
IF DBMS_DB_VERSION.ver_le_19 THEN
DBMS_OUTPUT.PUT_LINE('ITS 19C');
END IF;
END;
/ SELECT FUN_GET_EMP_DTLS(100) EMP_DTLS FROM DUAL;
CREATE OR REPLACE FUNCTION FUN_GET_EMP_DTLS(P_EMPID EMPLOYEES.EMPLOYEE_ID%TYPE)
RETURN VARCHAR2
IS
V_DTLS VARCHAR2(1000);
BEGIN
SELECT FIRST_NAME||' '||LAST_NAME
INTO V_DTLS
FROM EMPLOYEES
WHERE EMPLOYEE_ID = P_EMPID;
--
$IF DBMS_DB_VERSION.VERSION < 19 $THEN
RETURN V_DTLS;
$ELSE
V_DTLS := 'NO DATA FOUND';
RETURN V_DTLS;
$END
END;
/ Now in the following example, we will check the plsql_optimize_level. If its not set at 3 then oracle will raise an error.
Now checking the current plsql_optimize_level:
SELECT NAME||' -> '||VALUE plsql_optimize_level FROM V$PARAMETER WHERE NAME = 'plsql_optimize_level';
So it will definitely raise an error as per below code.
CREATE OR REPLACE PROCEDURE OPT_LEVEL_TEST
AS
V_STRING VARCHAR2(100);
BEGIN
SELECT NAME||' -> '||VALUE
INTO V_STRING
FROM V$PARAMETER
WHERE NAME = 'plsql_optimize_level';
DBMS_OUTPUT.PUT_LINE(V_STRING);
$IF $$plsql_optimize_level <> 3 $THEN
$ERROR 'PLSQL OPTIMIZE LEVEL SHOULD BE 3' $END
$END
END;
/ Now setting the PLSQL_OPTIMIZE_LEVEL as 3.
Now the below procedure will be compiled successfully.
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 3;
CREATE OR REPLACE PROCEDURE OPT_LEVEL_TEST
AS
V_STRING VARCHAR2(100);
BEGIN
SELECT NAME||' -> '||VALUE
INTO V_STRING
FROM V$PARAMETER
WHERE NAME = 'plsql_optimize_level';
DBMS_OUTPUT.PUT_LINE(V_STRING);
$IF $$plsql_optimize_level <> 3 $THEN
$ERROR 'PLSQL OPTIMIZE LEVEL SHOULD BE 3' $END
$END
END;
/ EXEC OPT_LEVEL_TEST;
RELATED TOPICS: