Using PL/SQL Conditional Compilation
PL/SQL conditional compilation is very easy to use. You need to learn just two new types of semantic construct:
- Compiler directives
- Conditional compilation flags (ccflags), which for the conditional compiler are like "constants" that can be set at a system, session, or individual compilation level (Some default flags are available, and you can supply your own.)
The most basic principle of conditional compilation is that you must be able to compile your code conditionally (i.e., compile certain code IF certain conditions are met, ELSE compile other code). So, the most basic building block for conditional compilation is a compiler directive that works like an if... then... else construct.
In PL/SQL CC, this building block is known as the selection directive. It works very similarly to the if... then... else construct in PL/SQL. The syntax is:
$IF condition $THEN .....
[$ELSIF condition $THEN.... ]
As you may have guessed, all PL/SQL CC tokens are preceded by a dollar sign (
The two key differences between the CC selection directive and the standard PL/SQL if... then... else construct are the following:
- The CC selection directive terminates with
- The condition in the CC IF-test has significant restrictions. Since the compiler needs to evaluate condition at compile-time, condition cannot be variableit must be a constant value at compile-time. Specifically, it must be a static Boolean expression. A good approximation to this concept is an expression that is static at compile-time (see Sidebar 1. Static Boolean Expressions for a more in-depth explanation).
So, for example, this is acceptable:
$IF -4 = 8 $THEN
But this is not, since
–4=TRUNC(sysdate,'MM') is not a static Boolean expression:
$IF -4=TRUNC(sysdate,'MM') $THEN
The IF-test expressions can include package constants (set elsewhere, not in the same package, of course) so long as these are static Boolean expressions themselves, for example:
create or replace package PayrollApp_CC_Constants is
c_SpecialNumber constant PLS_INTEGER := 8;
c_DebugOn constant BOOLEAN := false;
$IF PayrollApp_CC_Constants.c_DebugOn $THEN
$ELSIF PayrollApp_CC_Constants.c_SpecialNumber = -4 $THEN
(Author's Note: In this and all subsequent examples,
debug('X') does not refer to any PL/SQL language element. If not otherwise specified, it refers to a hypothetical procedure, found elsewhere in the hypothetical package being used in the example, which takes a debug message as argument and presumably prints it out or logs it somewhere.)
When using static-expression constants in your IF-test expressions for conditional compilation, it's best to separate these constants out and keep them all together in a package that contains nothing but such constants. This way, it's easier to see at a glance what the values of the constants determining your compilation results are. They are also less likely to be confused with regular application constants in the PL/SQL code, which could, for example, lead to such a constant accidentally being set to a non-static value or expression. Finally, separating out the constants means you are guaranteed not to tangle yourself in circular compilation dependencies.
The following example makes it very clear that the conditional compilation selection directives are processed before Oracle tries to compile, or even parse, the rest of the code. Consider this simple procedure:
create or replace procedure testproc is
$if TRUE $then
dbms_output.put_line('We got here');
RANDOM BAD STUFF, NOT EVEN SYNTACTICALLY CORRECT
The text of this procedure contains big syntax mistakes ("
RANDOM BAD STUFF, NOT EVEN SYNTACTICALLY CORRECT"), but these mistakes are in a branch of the
$IF - $THEN - $ELSE that will never be evaluated. And this procedure compiles just fine:
SQL> create or replace procedure testproc is
3 $if TRUE $then
4 dbms_output.put_line('We got here');
6 RANDOM BAD STUFF, NOT EVEN SYNTACTICALLY CORRECT
9 end testproc;
SQL> show errors procedure testproc