Conditional Compilation in Oracle
What is Conditional Compilation?
PL/SQL source code is compiled selectively based on the compiler directives. Therefore, in the compile time code can be different according to conditions.
Why do we need Conditional Compilation?
Using conditional compilation features, we can include version specific features to our PLSQL source code. Therefore, In any production environments which use different versions, Code is compiled and application is running properly without any issue. Assume, in development environments, we have developed multiple components such as component A for finance, component B for manufacturing, and component C for Sales. Now if we call methods written in component B for packages in component C, there is no issue when compiling and running particular code since all the components are properly deployed in the development environment. But, assume one of our customers install only component C in production environment, now when compiling the codes it gives errors since particular customer does not install component B , but methods in component B is still using in component C. To avoid this kind of scenarios, Conditional Compilation can be used and so, by compiling conditionally , it only allows to call methods of other component, if and only that particular component is installed in the customer environment.
Conditional Compilation Directives
Selection Directives - $IF, $THEN, $ELSE, $END
These directives are used to evaluate which code should be compiled according to conditions.
Error Directives - $ERROR
This can be used to report compilation errors, when evaluating the conditions
Conditional Compilation Supports for two packages in Oracle which are DBMS_PREPROCESSOR and DBMS_DB_VERSION.
DBMS_PREPROCESSOR - This Oracle package provides Get_Post_Processed_Method which can be used to view generated compiled code. In PLSQL, if you just deploy the file, you see all the codes including the directives you applied. But, DBMS_PREPROCESSOR.Get_Post_Processed_Method only displays the actually compiled codes which are satisfying the particular conditions.
set serveroutput on size 1000000
Begin
DBMS_PREPROCESSOR.print_post_processed_source(
object_type => 'PACKAGE BODY',
schema_name => 'NADZ',
object_name => 'Test_Cond_Compile_Api'
);
End;
/
Object_Type can be PACKAGE, PACKAGE_BODY, FUNCTION, PROCEDURE, TRIGGER.
DBMS_DB_VERSION - This package provides Oracle Version number and release number of the Oracle database that your application is connected.
The constants such as VER_LE_9, VER_LE_9_1, VER_LE_9_2,VER_LE_10, VER_LE_10_1, VER_LE_10_2 defined in this package can be used for conditional compilation to compile the code according to database version currently application connected.
set serveroutput on size 1000000
Begin
$IF (DBMS_DB_VERSION.VER_LE_10) $THEN
dbms_output.put_line('Version 10');
$ELSIF DBMS_DB_VERSION.ver_le_11_1 $THEN
dbms_output.put_line('Version 11 and Release 1');
$ELSIF DBMS_DB_VERSION.ver_le_11_2 $THEN
dbms_output.put_line('Version 11 and Release 2');
$ELSIF DBMS_DB_VERSION.VER_LE_11 $THEN
dbms_output.put_line('Version 11');
$ELSE
dbms_output.put_line('Other Version');
$END
End;
/
Assume you are going to implement a package in PLSQL and Your target is deploying all of PLSQL functions of this package in the customer environment, if and only customer installed the Finance_Api in that environment. If Finace_Api is not installed in the customer environment, none of methods in this package should be deployed. So, If you write code in below way,
create or replace package body TEST_COND_COMP_API is
$IF (Finance_Api.Is_Installed) $THEN
-- Public function and procedure declarations
function Calculate_Profit(profit_ NUMBER) return NUMBER
is
begin
return 1000;
end;
$ELSE
NULL;
$END
end TEST_COND_COMP_API;
If you deploy this in an environment where Finance_Api is installed, PLSQL package is deployed with defined functions without any error. But, If you deploy this in an environment where Finance_Api is not installed, You get an below error.
Compilation errors for PACKAGE BODY IFSAPP.TEST_COND_COMP_API
Error: PLS-00103: Encountered the symbol "NULL" when expecting one of the following:
begin end function pragma procedure subtype type
<an identifier> <a double-quoted delimited-identifier>
current cursor delete exists prior
The symbol "begin" was substituted for "NULL" to continue.
create or replace package body TEST_COND_COMP_API is
$IF (Finance_Api.Is_Installed) $THEN
-- Public function and procedure declarations
function Calculate_Profit(profit_ NUMBER) return NUMBER
is
begin
return 1000;
end;
$ELSE
PROCEDURE Dummy
IS
BEGIN
NULL;
END Dummy;
$END
end TEST_COND_COMP_API;
PL/SQL source code is compiled selectively based on the compiler directives. Therefore, in the compile time code can be different according to conditions.
Why do we need Conditional Compilation?
Using conditional compilation features, we can include version specific features to our PLSQL source code. Therefore, In any production environments which use different versions, Code is compiled and application is running properly without any issue. Assume, in development environments, we have developed multiple components such as component A for finance, component B for manufacturing, and component C for Sales. Now if we call methods written in component B for packages in component C, there is no issue when compiling and running particular code since all the components are properly deployed in the development environment. But, assume one of our customers install only component C in production environment, now when compiling the codes it gives errors since particular customer does not install component B , but methods in component B is still using in component C. To avoid this kind of scenarios, Conditional Compilation can be used and so, by compiling conditionally , it only allows to call methods of other component, if and only that particular component is installed in the customer environment.
Conditional Compilation Directives
Selection Directives - $IF, $THEN, $ELSE, $END
These directives are used to evaluate which code should be compiled according to conditions.
Error Directives - $ERROR
This can be used to report compilation errors, when evaluating the conditions
Conditional Compilation Supports for two packages in Oracle which are DBMS_PREPROCESSOR and DBMS_DB_VERSION.
DBMS_PREPROCESSOR - This Oracle package provides Get_Post_Processed_Method which can be used to view generated compiled code. In PLSQL, if you just deploy the file, you see all the codes including the directives you applied. But, DBMS_PREPROCESSOR.Get_Post_Processed_Method only displays the actually compiled codes which are satisfying the particular conditions.
set serveroutput on size 1000000
Begin
DBMS_PREPROCESSOR.print_post_processed_source(
object_type => 'PACKAGE BODY',
schema_name => 'NADZ',
object_name => 'Test_Cond_Compile_Api'
);
End;
/
Object_Type can be PACKAGE, PACKAGE_BODY, FUNCTION, PROCEDURE, TRIGGER.
DBMS_DB_VERSION - This package provides Oracle Version number and release number of the Oracle database that your application is connected.
The constants such as VER_LE_9, VER_LE_9_1, VER_LE_9_2,VER_LE_10, VER_LE_10_1, VER_LE_10_2 defined in this package can be used for conditional compilation to compile the code according to database version currently application connected.
set serveroutput on size 1000000
Begin
$IF (DBMS_DB_VERSION.VER_LE_10) $THEN
dbms_output.put_line('Version 10');
$ELSIF DBMS_DB_VERSION.ver_le_11_1 $THEN
dbms_output.put_line('Version 11 and Release 1');
$ELSIF DBMS_DB_VERSION.ver_le_11_2 $THEN
dbms_output.put_line('Version 11 and Release 2');
$ELSIF DBMS_DB_VERSION.VER_LE_11 $THEN
dbms_output.put_line('Version 11');
$ELSE
dbms_output.put_line('Other Version');
$END
End;
/
Assume you are going to implement a package in PLSQL and Your target is deploying all of PLSQL functions of this package in the customer environment, if and only customer installed the Finance_Api in that environment. If Finace_Api is not installed in the customer environment, none of methods in this package should be deployed. So, If you write code in below way,
create or replace package body TEST_COND_COMP_API is
$IF (Finance_Api.Is_Installed) $THEN
-- Public function and procedure declarations
function Calculate_Profit(profit_ NUMBER) return NUMBER
is
begin
return 1000;
end;
$ELSE
NULL;
$END
end TEST_COND_COMP_API;
If you deploy this in an environment where Finance_Api is installed, PLSQL package is deployed with defined functions without any error. But, If you deploy this in an environment where Finance_Api is not installed, You get an below error.
Compilation errors for PACKAGE BODY IFSAPP.TEST_COND_COMP_API
Error: PLS-00103: Encountered the symbol "NULL" when expecting one of the following:
begin end function pragma procedure subtype type
<an identifier> <a double-quoted delimited-identifier>
current cursor delete exists prior
The symbol "begin" was substituted for "NULL" to continue.
This error is given since it is going to create package with NULL body. So you can change this by including dummy method for else part in below way.
create or replace package body TEST_COND_COMP_API is
$IF (Finance_Api.Is_Installed) $THEN
-- Public function and procedure declarations
function Calculate_Profit(profit_ NUMBER) return NUMBER
is
begin
return 1000;
end;
$ELSE
PROCEDURE Dummy
IS
BEGIN
NULL;
END Dummy;
$END
end TEST_COND_COMP_API;
Smart work......
ReplyDeleteKeep up the good work....