Neue PL/SQL Features IV - Conditional Compilation

Heute setzen wir unsere Serie neuer PL/SQL Features mit einem doch schon etwas älteren, aber nicht weniger interessanten Feature fort. Es geht um die bedingte Kompilierung. Nehmen wir mal als Beispiel, das PRAGMA UDF aus einem vorangegangenen Blog-Beitrag. Dieses Feature wurde mit der Oracle Datenbank Version 12 eingeführt. Wir wollen dieses Feature zukünftig nutzen, es gibt aber leider immer noch Datenbanken in der Version 11.2.0.4. Die Einführung des PRAGMA UDF auf einer 11er Datenbank führt dann zu Kompilierungsfehlern.

 

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE    11.2.0.4.0      Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

SQL> create or replace function fnc_betwen_str(p_text in varchar2, p_start in number, p_ende in number) return varchar2
  2  is
  3    PRAGMA UDF;
  4  begin
  5    return substr(p_text, p_start , p_ende - p_start +1);
  6  end;
  7  /

Warning: Function created with compilation errors.

SQL> show err
Errors for FUNCTION FNC_BETWEN_STR:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/10     PLS-00127: Pragma UDF is not a supported pragma

 

Wir müssten also verschiedene Code-Pfade für die verschiedenen Versionen pflegen. Das bedeutet natürlich einen deutlichen Mehraufwand und birgt die Gefahr, das die Pfade auseinander laufen. Hier kommt nun die bedingte Kompilierung ins Spiel, die es seit Version 10.1 gibt. Denn wie der Name schon sagt, können wir bestimmte Code-Abschnitte quasi ausblenden, abhängig von einer Bedingung. Das geschieht mit einem If-Then-Else Ausdruck in Form von Preprocessor Tokens. Dazu liefert uns das Package DBMS_DB_VERSION die nötige Information zur Datenbankversion.

 

SQL> create or replace function fnc_betwen_str(p_text in varchar2, p_start in number, p_ende in number) return varchar2
  2  is
  3    $IF DBMS_DB_VERSION.VER_LE_11
  4    $THEN
  5    $ELSE
  6    PRAGMA UDF;
  7    $END
  8  begin
  9    return substr(p_text, p_start , p_ende - p_start +1);
 10  end;
 11  /

Function created.

 

Nun wird bei einer Datenbank Version 11 oder kleiner kein Pragma verwendet, denn dieser Zweig ist leer. Nur wenn die Version größer als 11 ist, wird das Pragma im Else-Zweig mit in den Code aufgenommen. Auf einer Datenbank 19c kann das natürlich ebenso fehlerfrei kompiliert werden, nur wird hier eben das PRAGMA UDF mit in den Code-Pfad aufgenommen.

 

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL> create or replace function fnc_betwen_str(p_text in varchar2, p_start in number, p_ende in number) return varchar2
  2  is
  3    $IF DBMS_DB_VERSION.VER_LE_11
  4    $THEN
  5    $ELSE
  6    PRAGMA UDF;
  7    $END
  8  begin
  9    return substr(p_text, p_start , p_ende - p_start +1);
 10  end;
 11  /

Function created.

 

Es gibt aber noch ein weitere interessante Funktionalität, nämlich $ERROR. Damit können wir Kompilierungsfehler erzeugen. Aber wozu soll das gut sein? Nehmen wir nochmal an, unsere PL/SQL Prozedur hat durch die bedingte Kompilierung mehrere Code-Pfade für verschiedene Datenbank Versionen. Der Pfad für eine neuere Version ist aber noch nicht fertig ausprogrammiert. Dann können wir $ERROR verwenden um darauf aufmerksam zu machen. Die folgende Prozedur können wir auf einer 11er Datenbank fehlerfrei kompilieren und ausführen: 

 

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE    11.2.0.4.0      Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

SQL> create or replace procedure dummy_procedure
  2  is
  3  begin
  4    $IF DBMS_DB_VERSION.VER_LE_11
  5    $THEN
  6      dbms_output.put_line('Codepath Versions < 12');
  7    $ELSE
  8      $ERROR
  9      'Code for Versions 12+ not implemented yet: ' || $$PLSQL_UNIT || ' at line ' || $$PLSQL_LINE
 10      $END
 11    $END
 12  end;
 13  /

Procedure created.

SQL> set serveroutput on
SQL> exec dummy_procedure
Codepath Versions < 12

PL/SQL procedure successfully completed.

 

In einer höheren Version jedoch nicht mehr, hier bekommen wir Meldung inklusive Programmteil und Zeilennummer in der Fehlermeldung geliefert:

 

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL> create or replace procedure dummy_procedure
  2  is
  3  begin
  4    $IF DBMS_DB_VERSION.VER_LE_11
  5    $THEN
  6      dbms_out.put_line('Codepath Versions < 12');
  7    $ELSE
  8      $ERROR 
  9      'Code for Versions 12+ not implemented yet: ' || $$PLSQL_UNIT || ' at line ' || $$PLSQL_LINE
 10      $END
 11    $END
 12  end;
 13  /

Warning: Procedure created with compilation errors.

SQL> show err
Errors for PROCEDURE DUMMY_PROCEDURE:

LINE/COL ERROR
-------- -----------------------------------------------------------------
8/5      PLS-00179: $ERROR: Code for Versions 12+ not implemented yet:
         DUMMY_PROCEDURE at line 9

 

Die bedingte Kompilierung hat also durchaus Potential, die Entwicklung und Pflege von PL/SQL zu vereinfachen und zu unterstützen. Probieren Sie es aus. Eine Einführung zur bedingten Kompilierung, zu den verfügbaren Preprocessor Tokens und zu den verfügbaren Inquiry Directives finden Sie in der Oracle PL/SQL Dokumentation.

Verwandte Blogbeiträge:

Kommentare

Keine Kommentare

Kommentar schreiben

* Diese Felder sind erforderlich