RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Streamline Your Oracle Production Code with Conditional Compilation : Page 2

Every Oracle PL/SQL developer concerned about the performance impact of repeated if... then... else calls can use conditional compilation to scrub these calls from production code. And that's just the beginning.


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:
  1. Compiler directives
  2. 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.... ]
[$ELSE .....]

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:

  1. The CC selection directive terminates with $END, not $END $IF.
  2. The condition in the CC IF-test has significant restrictions. Since the compiler needs to evaluate condition at compile-time, condition cannot be variable—it 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;
end PayrollApp_CC_Constants;

$IF PayrollApp_CC_Constants.c_DebugOn $THEN
	debug('Debug On');
$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');
end testproc;

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
  2  begin
  3  $if TRUE $then
  4     dbms_output.put_line('We got here');
  5  $else
  7  $end
  8  null;
  9  end testproc;
10 /

Procedure created.

SQL> show errors procedure testproc
No errors.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date