
Weiterführende Links
Funktionen sind grundlegende Bausteine in Programmiersprachen. Bei Oracle müssen zwei Arten von Funktionen unterschieden werden:
Eine Funktion hat entweder keinen, einen oder mehrere Parameter, aber zwingend nur genau einen Rückgabewert. Die Funktion in Abbildung 1 gibt den festen Text „Hallo" gefolgt vom Inhalt des Parameters p_wer zurück.
SQL> CREATE OR REPLACE FUNCTION fct_hallo( p_wer VARCHAR2 ) 2 RETURN VARCHAR2 3 IS 4 BEGIN 5 RETURN ,Hallo , || p_wer; 6 END; 7 / Funktion wurde erstellt. SQL> SELECT fct_hallo( ,Welt‘ ) FROM dual; FCT_HALLO(,WELT‘) -------------------------------------- Hallo Welt |
| Abb. 1: Beispielcode für eine Funktion mit einem Übergabeparameter. |
Funktionen können in PL/SQL und - wie das Beispiel in Abbildung 1 zeigt - in SQL verwendet werden. Oracle bietet auch die Möglichkeit, eigene Aggregatfunktionen wie min, avg usw. zu implementieren. Dies ist jedoch erheblich aufwendiger.
Neben den Funktionen stellen die Prozeduren den zweiten wichtigen Baustein in der PL/SQL-Programmierung dar. Prozeduren unterscheiden sich von Funktionen im Wesentlichen dadurch, dass diese keinen Rückgabewert liefern. Somit können Prozeduren auch nicht in SQL-Befehlen verwendet werden.
Wie in Funktionen können die Übergabeparameter auch in Prozeduren sowohl zur Übergabe (IN), als auch zur Rückgabe (OUT) oder sowohl-als-auch (IN/OUT) verwendet werden (siehe Abbildung 2).
SQL> CREATE OR REPLACE PROCEDURE prc_hallo( p_wer IN VARCHAR2, p_ausgabe OUT VARCHAR2 ) 2 IS 3 BEGIN 4 p_ausgabe := ,Hallo , || p_wer; 5 END; 6 / Prozedur wurde erstellt. SQL> DECLARE 2 v_ausgabe VARCHAR2(100); 3 BEGIN 4 prc_hallo( ,Welt‘, v_ausgabe ); 5 dbms_output.put_line( v_ausgabe ); 6 END; 7 / Hallo Welt |
| Abb. 2: Beispielcode für eine Prozedur mit zwei Parametern. |
Werden mit Hilfe von PL/SQL umfangreichere Funktionalitäten programmiert, so bietet es sich an, zusammengehörige Prozeduren und Funktionen in Pakete zusammenzufassen. Ein Paket kann entweder ausschließlich aus einer Paketspezifikation bestehen oder aus einer Spezifikation und einem Paketrumpf (Objekttyp PACKAGE BODY).
Eine Paketspezifikation (Objekttyp PACKAGE) deklariert die öffentlichen Prozeduren, Funktionen und globalen Variablen. Der Paketrumpf enthält die Implementierung der öffentlichen Schnittstelle und die privaten Prozeduren, Funktionen sowie lokale und globale Variablen. Zur Fehlerbehandlung lassen sich in Paketen Exceptions definieren und verwenden.
Der Programmcode zu Prozeduren kann aus der View user_source ausgelesen werden. In dieser View findet sich auch der Programmcode zu Prozeduren, Funktionen, Triggern usw. Soll der Code geschützt werden, so kann er mit Hilfe des Betriebssystemprogramms wrap verschlüsselt werden. Anschließend wird das verschlüsselte Paket in die Datenbank eingespielt.
CREATE OR REPLACE TYPE department_t AS OBJECT ( deptno number(10), dname CHAR(30)); |
| Abb. 3: Deklaration eines Records als Objekttyp TYPE. |
Mit dem Objekttyp TYPE bietet Oracle die Möglichkeit, eigene Objekttypen zu deklarieren. Im einfachsten Fall ist dies ein Record, welcher wie in Abbildung 3 deklariert wird. Die Möglichkeiten eigener Typen gehen jedoch weit darüber hinaus. So lassen sich neben der einfachen Deklaration von Record, Arrays und Nested Tables auch Funktionen und Prozeduren mit dem Objekttyp TYPE erstellen. Darüber hinaus kann man Typen auch entsprechend der objektorientierten Programmierung implementieren.
Indizes gehören zu den Basisbausteinen einer Datenbank. Sie ermöglichen den schnellen Zugriff auf Daten und dienen als Werkzeug zur Umsetzung von Unique-, Primary-Key- und Foreign-Key-Constraints. Indizes lassen sich mit der Eigenschaft UNIQUE oder NON-UNIQUE anlegen. Die UNIQUE-Eigenschaft gewährleistet, dass jede von diesem Index referenzierte Wertekombination in der zugrunde liegenden Tabelle eindeutig ist.
Von der Implementierung unterscheiden sich B*-Indizes und die für sehr spezielle Anfragen entworfenen Bitmap-Indizes. Die beiden Varianten unterscheiden sich im physikalischen Aufbau und haben bezüglich Größe, Zugriffsgeschwindigkeit, Indizierung von NULL-Werten und Aufwand für Einfügeoperationen sehr unterschiedliche Eigenschaften. Sowohl die Implementierung (B* versus Bitmap) als auch die Komprimierung haben keinen Einfluss auf den Objekttyp. Zur optimalen Speichernutzung lassen sich B*-Indizes komprimieren. Lesen Sie hierzu auch den passenden Artikel [1].
Werden Indizes auf partitionierten Tabellen angelegt, so können die Indizes global (1 Indexsegment pro Tabelle), global partitioniert (n Index-Segmente je Tabelle) oder lokal partitioniert (je Tabellenpartition bzw. je nach Subpartition 1 Indexsegment) sein. Je nach Art der Indizierung ist der zugehörige Objekttyp INDEX, INDEX PARTITION oder INDEX SUBPARTITION.
Ein interessanter Sonderfall ist die Index Organized Table (IOT). Die IOT ist, wie der Name schon sagt, eine Tabelle, die in Form eines Indexes aufgebaut ist. Aus Sicht der Objekttypen ist es sowohl eine Tabelle als auch ein Index. Das Segment, also der zugehörige Speicherplatz, ist der Index.
CREATE UNIQUE INDEX adresse_idx1 ON adresse( stadt, strasse, hausnummer ) COMPRESS 2; |
| Abb. 4: Index auf drei Spalten, wovon 2 komprimiert sind. |
Ein eindeutiger B*-Index auf drei Spalten, von denen die ersten beiden komprimiert sind, lässt sich beispielsweise wie in Abbildung 4 anlegen.
Weiterhin bietet Oracle die Möglichkeit, funktionsbasierte Indizes anzulegen. In diesem Fall wird nicht ein Wert aus der Tabelle indiziert, sondern die Rückgabe einer Funktion auf diesen Wert. So kann beispielsweise ein Index auf UPPER(name) angelegt werden. Über einen solchen Index lässt sich dann unabhängig von der Groß-/Kleinschreibung recherchieren. Auch funktionsbasierte Indizes sind vom Typ INDEX.
CREATE INDEX schriftverkehr_idx1 ON schriftverkehr( text ) INDEXTYPE IS ctxsys.context ... |
| Abb. 5: Anlegen eines Volltextindexes. |
Neben den zuvor vorgestellten Indizierungsvarianten bietet Oracle noch eine weitere Variante an. Mit Hilfe des Objekttyps INDEXTYPE können Indizierungen implementiert werden, die weit über die Möglichkeiten von funktionsbasierten Indizes hinausgehen. Die Programmierung dieser Typen ist aber äußerst komplex. ctxsys.context ist ein weit verbreiteter INDEX-Typ. Dies ist ein speziell entwickelter Indextyp zur Volltextindizierung von großen Textmengen. Der Befehl in Abbildung 5 legt einen Volltextindex an.
In einer der nächsten ORDIX News setzen wir diese Artikelreihe dann wieder in alphabetischer Form fort. Dann werden wir uns mit „J" wie Java-Objekttypen in der Datenbank beschäftigen.
Martin Hoermann (info@ordix.de).