Als PDF Downloaden!

Werbung
Tipps & Tricks: September 2006
Bereich:
PL/SQL
Erstellung:
09/2006 HA
Versionsinfo:
9.2, 10.2, 11.1
Letzte Überarbeitung:
06/2009 HA
Verarbeitung eines dynamischen Selects
Dynamische Selects zu schreiben ist dank Ref Cursoren mittlerweile ziemlich einfach geworden. Man muss
jedoch wissen, wie viele Spalten man ausliest, und welchen Datentyp sie haben. In der Regel ist das kein
Problem, wenn man über die Dynamik nur erreichen will, dass je nach übergebenen Parametern auf
unterschiedliche Tabellen zugegriffen wird oder nach unterschiedlichen Spalten sortiert werden soll.
Was aber tut man, wenn man die Spaltenliste des Select-Befehls nicht kennt?
In diesem Fall kann man auf das altbewährte und teilweise bereits als veraltet belächelte DBMS_SQL-Package
zurückgreifen. Es ermöglicht, über die Prozedur DESCRIBE_COLUMNS die Spaltenliste zu ermitteln. Diese
Prozedur liefert die Anzahl der Spalten zurück und eine Beschreibung jeder Spalte in Form einer INDEX
BY-Tabelle, die auf einem Record-Datentyp (DBMS_SQL.DESC_REC) beruht. Ausgelesen werden u. a. Name
und Datentyp der Spalten.
Um auch die Anzahl der Spalten komplett dynamisch halten zu können, wurde im unten gezeigten Beispiel mit
INDEX BY-Tabellen der wichtigsten Datentypen als Variablen gearbeitet.
Beispiel:
CREATE or replace PROCEDURE GETROWS (p_select IN VARCHAR2) AS
v_desc
DBMS_SQL.DESC_TAB;
v_id
INTEGER;
v_count
INTEGER;
v_ret
INTEGER;
Type t_ntype IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_col_n
t_ntype;
Type t_vtype IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
v_col_v
t_vtype;
Type t_dtype IS TABLE OF DATE INDEX BY BINARY_INTEGER;
v_col_d
t_dtype;
v_output VARCHAR2(2000);
BEGIN
v_id := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(v_id, p_select, DBMS_SQL.v7);
DBMS_SQL.DESCRIBE_COLUMNS(v_id, v_count, v_desc);
FOR i in 1..v_count LOOP
v_col_n(i) := NULL;
v_col_v(i) := NULL;
v_col_d(i) := NULL;
END LOOP;
FOR i in 1..v_count LOOP
CASE v_desc(i).col_type
WHEN DBMS_TYPES.TYPECODE_VARCHAR THEN
Muniqsoft GmbH
Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40
IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0
Seite 1 von 2
DBMS_SQL.DEFINE_COLUMN(v_id, i, v_col_v(i), 2000);
WHEN DBMS_TYPES.TYPECODE_NUMBER THEN
DBMS_SQL.DEFINE_COLUMN(v_id, i, v_col_n(i));
WHEN DBMS_TYPES.TYPECODE_DATE THEN
DBMS_SQL.DEFINE_COLUMN(v_id, i, v_col_d(i));
END CASE;
END LOOP;
v_ret := DBMS_SQL.EXECUTE(v_id);
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(v_id);
EXIT WHEN v_ret IS NULL OR v_ret <=0;
FOR i IN 1..v_count LOOP
v_output := 'Spalteninhalt Spalte '||v_desc(i).col_name ||': ';
CASE v_desc(i).col_type
WHEN DBMS_TYPES.TYPECODE_VARCHAR THEN
DBMS_SQL.COLUMN_VALUE(v_id, i, v_col_v(i));
v_output := v_output||v_col_v(i);
WHEN DBMS_TYPES.TYPECODE_NUMBER THEN
DBMS_SQL.COLUMN_VALUE(v_id, i, v_col_n(i));
v_output := v_output||v_col_n(i);
WHEN DBMS_TYPES.TYPECODE_DATE THEN
DBMS_SQL.COLUMN_VALUE(v_id, i, v_col_d(i));
v_output := v_output||v_col_d(i);
END CASE;
DBMS_OUTPUT.PUT_LINE(v_output);
END LOOP; END LOOP;
DBMS_SQL.CLOSE_CURSOR(v_id);
EXCEPTION
WHEN CASE_NOT_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Unbekannter Datentyp einer Spalte');
DBMS_SQL.CLOSE_CURSOR(v_id);
END;
/
SET SERVEROUTPUT ON SIZE 1000000
EXEC GETROWS('SELECT * FROM EMP')
Muniqsoft GmbH
Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40
IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0
Seite 2 von 2
Herunterladen