Zu Oracle

Bereich:
Versionsinfo:
PL/SQL
8.1.7, 9.2, 10.2, 11.1
Erstellung:
Letzte Überarbeitung:
12/2003 HA
05/2009 HA
 Als PDF Downloaden!

Aufruf von Funktionen über dynamisches SQL

Gelegentlich kommt man in die Verlegenheit, dass eine Prozedur oder Funktion in unterschiedlichen Datenbank-Versionen unterschiedlich heisst, ein Skript mit ihrem Aufruf aber auf möglichst vielen Datenbank-Versionen laufen soll. Hier hilft (vor Version 10.2) nur dynamisches SQL weiter.

In DBMS_UTITLIY gibt es bis Version 9.0.x eine Funktion namens IS_PARALLEL_SERVER. Ab Version 9.2 existiert diese nicht mehr; stattdessen wurde IS_CLUSTER_DATABASE eingeführt. An diesem Beispiel soll hier exemplarisch gezeigt werden, wie so etwas mit EXECUTE IMMEDIATE bzw. DBMS_SQL realisierbar ist. Beide Funktionen sind vom Datentyp BOOLEAN.
Als Returnwerte für dynamisches SQL können nur Server-Datentypen verwendet werden, daher muss der Return-Wert zusätzlich gewandelt werden, am besten zu einer Zahl.

Im folgenden Beispiel wurde der dynamische Aufruf der Funktion der Überschaubarkeit wegen in eine eigenständige Funktion gepackt; in der Praxis, wenn man mit Skripten arbeitet, ist er sinnvollerweise Teil des Skripts.

Beispiel mit EXECUTE IMMEDIATE:

CREATE OR REPLACE FUNCTION IS_PARALLEL(p_version NUMBER) RETURN BOOLEAN IS
   v_string         VARCHAR2(2000);
   v_call           VARCHAR2(2000);
   v_result         INTEGER;
   v_ret            BOOLEAN;
BEGIN
   IF p_version >= 92000 THEN
      v_call := 'v_isParallel := DBMS_UTILITY.IS_CLUSTER_DATABASE;';
   ELSE
      v_call := 'v_isParallel := DBMS_UTILITY.IS_PARALLEL_SERVER;';
   END IF;
   v_string := 'DECLARE
                  v_isParallel boolean;
               BEGIN
                  '||v_call||'
                  :v_ret := SYS.DIUTIL.bool_to_int(v_isParallel);
               END;';
   EXECUTE IMMEDIATE v_string
      USING OUT v_result;
   v_ret := SYS.DIUTIL.int_to_bool(v_result);
   RETURN v_ret;
END IS_PARALLEL;
/

EXECUTE IMMEDIATE ist seit Version 8i verfügbar; soll die Funktion in noch niedrigeren Versionen eingesetzt werden, so muss stattdessen DBMS_SQL verwendet werden:

Beispiel mit DBMS_SQL:

CREATE OR REPLACE FUNCTION IS_PARALLEL(p_version NUMBER) RETURN BOOLEAN IS
   v_string         VARCHAR2(2000);
   v_call           VARCHAR2(2000);
   v_cur            INTEGER;
   v_ret_cur        INTEGER;
   v_result         INTEGER;
   v_ret            BOOLEAN;
BEGIN
   IF p_version >= 92000 THEN
      v_call := 'v_isParallel := DBMS_UTILITY.IS_CLUSTER_DATABASE;';
   ELSE
      v_call := 'v_isParallel := DBMS_UTILITY.IS_PARALLEL_SERVER;';
   END IF;
   v_string := 'DECLARE
                  v_isParallel boolean;
               BEGIN
                  '||v_call||'
                  :v_ret := SYS.DIUTIL.bool_to_int(v_isParallel);
               END;';
   v_cur := DBMS_SQL.open_cursor;
   DBMS_SQL.parse(v_cur, v_string, DBMS_SQL.V7);
   DBMS_SQL.bind_variable(v_cur, ':v_ret', v_result);
   v_ret_cur := DBMS_SQL.execute(v_cur);
   DBMS_SQL.VARIABLE_VALUE(v_cur, ':v_ret', v_result);
   DBMS_SQL.CLOSE_CURSOR(v_cur);
   v_ret := SYS.DIUTIL.int_to_bool(v_result);
   RETURN v_ret;
END IS_PARALLEL;
/

Der Aufruf dieser Funktion würde in etwa so aussehen:

DECLARE
   v_version        VARCHAR2(2001);
   v_comp           VARCHAR2(2001);
   v_version_number NUMBER;
BEGIN
   DBMS_UTILITY.DB_VERSION(v_version, v_comp);
   v_version_number := TO_NUMBER(REPLACE(v_version, '.'));
   IF IS_PARALLEL(v_version_number) THEN
      DBMS_OUTPUT.PUT_LINE('Parallel Server / RAC');
   ELSE
      DBMS_OUTPUT.PUT_LINE('kein Parallel Server / RAC');
   END IF;
END;
/

Anmerkungen:

  • Einzelheiten zu DBMS_UTILITY und der zugehörigen Prozedur DB-VERSION finden Sie hier.
  • Bei ähnlich gelagerten Fällen ist bedingte Kompilierung eine Alternative, sofern das Programm oder Skript nicht unter Versionen vor Version 10.2 lauffähig sein muss.
Suche

Kontakt

Niederlassungen

  Witneystraße

    089 6228 6789-0

  Grünwalder Weg

    089 679090-40

E-Mail Verteiler Monatstipps

Bitte nehmen Sie mich in den Verteiler der monatlichen Tipps & Tricks auf.