| Arbeiten mit PL/SQL-Tabellen |
|
|
| Donnerstag, 16. Oktober 2008 um 15:00 | ||||
|
Die Arbeit mit PL/SQL scheint auf den ersten Blick kompliziert. Tatsächlich steht aber ein mächtiges Konzept dahinter, um mehrere Werte auf einmal zu bearbeiten. Wie Records werden auch PL/SQL Tabellen in zwei Schritten erzeugt. Erst muss die Tabellenstruktur deklariert werden mit Hilfe des TYPE Statements. Im zweiten Schritt muß eine Variable des eben angelegten Tabellentypen deklariert, bzw. instanziiert werden. Die Deklaration erfolgt mit
Dies erzeugt einen Tabellentypen, der 20stellige VARCHAR2-Werte aufnimmt. Das NOT NULL ist optional. Die Datentypen in einem Tabellentypen können alle skalaren Typen sein, aber auch Records (womöglich ein Record, dessen Feldkomponente wieder eine Tabelle ist? Damit läßt sich ganz schön was anstellen…). Um eine Variable des Typen zu instanziieren, nutzen wir
ACHTUNG! Seit der ORACLE-Version 9i ist es auch möglich, als Index-Kriterium Zeichenketten zu verwenden, so daß Sie mit Hilfe eines Strings auf eine Zeile der Tabelle zugreifen können (deshalb spricht man jetzt auch von associative arrays).
Weiterhin wichtig ist, dass Sie die Indizierungsform durchaus weglassen können, also z.B.
Dann handelt es sich aber nicht mehr um eine PL/SQL-Tabelle, sondern um eine nested table, die sich an bestimmten Stellen anders als eine PL/SQL-Tabelle verhält. Zeilen in PL/SQL TabellenWir erinnern uns, dass wir auf Zeilen in einer PL/SQL Tabelle mit Hilfe eines Index zugreifen. Die Syntax hierzu sieht wie folgt aus:
Der Die folgenden Beispiele sind allesamt zulÄssig. Wir nutzen automatische Typkonvertierung, Zahlen mit Nachkommaanteil werden gerundet.
Auf die gleiche Art und Weise können wir auch wieder aus einer Tabelle lesen. Was passiert aber, wenn eine referenzierte Zeile nicht existiert? Eine Zeile existiert erst, wenn ihr ein Wert zugewiesen wurde (Dieser Wert kann natürlich auch NULL sein). Wenn Sie versuchen, eine Zeile anzusprechen, die nicht existiert, erhalten Sie eine NO_DATA_FOUND Ausnahme. PL/SQL Tabellen füllen und leerenEs gibt drei verschiedene Arten, PL/SQL Tabellen zu füllen.
Direkte Zuweisung meint die Form, die wir zuvor genutzt haben, also:
Die iterative Zuweisung erfolgt z.B. in Form einer Schleife. Meist wird hier wohl die FOR-CURSOR-LOOP genutzt, um die Daten aus einer SQL Tabelle in eine PL/SQL Tabelle zu übernehmen.
Eine wesentlich schnellere Form ist das sogenannte BULK COLLECT:
Aggregierte Zuweisung meint die Zuweisung einer gesamten Tabelle an eine andere Tabelle. Diese muß typkompatibel sein. So wie bei Records ist das Vergleichen zweier Tabellen auf diese Art nicht möglich, hier muß Element für Element verglichen werden.
Es ist nicht möglich, alle Zeilen einer Tabelle zu entfernen oder gar zu “droppen”. Zwar können wir den einzelnen Zeilen einer Tabelle den Wert NULL zuweisen, aber die Zeile existiert weiter, eben gefüllt mit dem NULL Wert. Um eine Tabelle zu leeren und den verwendeten Speicher freizugeben, können wir einen Trick anwenden:
Seit PL/SQL Version 2.3 kann aber auch das DELETE Statement genutzt werden. PL/SQL TabellenfunktionenEs gibt für die Arbeit mit PL/SQL Tabellen eine Reihe vordefinierter Prozeduren und Funktionen:
Damit erhalten wir eine Reihe von Informationen über die referenzierte Tabelle, mit der Ausnahme der DELETE Anweisung, die eine Zeile aus einer Tabelle löscht. Die DELETE AnweisungDie DELETE Anweisung tut genau das, was wir erwarten: Sie löscht Zeilen in PL/SQL Tabellen. Die Syntax ist allerdings eine andere als in SQL:
Die COUNT FunktionAuch diese Funktion ist recht einfach zu merken. Sie liefert die Anzahl Werte in der PL/SQL Tabelle zurück. Zeilen, denen kein Wert zugeordnet ist, werden nicht mitgezählt. Sind keine Zeilen in der Tabelle, liefert COUNT die Zahl 0 zurück.
Die FIRST FunktionDie FIRST Funktion liefert den kleinsten Index zurück, an dem ein Wert eingetragen wurde. Sind keine Elemente (Zeilen) in der PL/SQL Tabelle, liefert FIRST den Wert NULL zurück.
Die NEXT FunktionDie NEXT Funktion liefert für einen gegebenen Indexwert den nächstgrößeren zurück, an dem ein Wert eingetragen ist. Sie ist sehr nützlich, weil wir ja erwähnt haben, dass eine PL/SQL Tabelle lückenhaft sein kann, die Zeilen also nicht hintereinanderliegen müssen. Das nächste Element nach Zeile 10 kann also 1000 sein. Wenn es keine Werte mehr hinter dem übergebenen Indexwert gibt, liefert NEXT den Wert NULL.
Im obigen Beispiel erhält die Variable next_value den Wert 5. Die LAST FunktionSie ist das genaue Gegenteil der FIRST Funktion, liefert also den letzten Indexwert der Tabelle zurück, an dem noch ein Element steht. Gibt es keine Elemente in der Tabelle, wird NULL zurückgeliefert. Die Syntax ist:
Die EXISTS FunktionDie wohl wichtigste Funktion im Umgang mit PL/SQL Tabellen, um den Zugriff auf uninitialisierte Zeilen und damit die NO_DATA_FOUND Ausnahme zu vermeiden: Die EXISTS Funktion liefert TRUE zurück, wenn am gegebenen Index ein Element (auch NULL) eingetragen ist, andernfalls FALSE. Sie kann beispielsweise so verwendet werden:
The PRIOR FunctionDie PRIOR Funktion ist das Gegenteil der NEXT Funktion. PRIOR liefert den nächstkleineren Indexwert, an dem ein Element steht, für einen gegebenen Indexwert zurück. Sie liefert NULL, wenn es kein Element mit einem kleineren Indexwert gibt. Beispiel:
Ein Beispiel für die Arbeit mit PL/SQL TabellenLassen Sie uns nun anschauen, wie PL/SQL Tabellen am einfachsten mit Daten gefüllt werden können. Es ist nicht ganz so einfach wie ein SELECT INTO, um einzelne Spaltenwerte in Variablen zu lesen. Wir müssen den Lesevorgang selbst programmieren. Wir müssen einen PL/SQL Block schreiben, der die Daten in eine PL/SQL Tabelle übernimmt. Die notwendigen Schritte sind folgende:
Schauen wir uns ein wenig Code an:
Nun, alternativ können wir eine PL/SQL Tabelle aber auch einfacher füllen:
In diesem Beispiel nutzen wir einen impliziten Cursor und übernehmen alle Datensätze in unsere PL/SQL Tabelle mit einem sogenannten BULK COLLECT, das mit der Version PL/SQL-Version 2.3 eingeführt wurde.
|
||||


Kommentare
BULK COLLECT funktioniert aber nur, wenn INDEX BY BINARY_INEGER ist. Zitieren
Alle Kommentare dieses Beitrages als RSS-Feed.