
| LOB Oracle Large Object. Oracle Datentyp zur Aufnahme großer Datenmengen (bis zu 128 Terabytes). |
| BLOB Binary Large Object. Oracle Datentyp zur Aufnahme binärer Daten innerhalb der Datenbank (z. B. Programme, Grafiken etc.). |
| CLOB Character Large Object. Oracle Datentyp für ein Datenbankfeld zur Speicherung von großen Textdaten (bis zu 4 GB). |
| NCLOB National Character Large Object. Oracle Datentyp zum Speichern langer alphanumerischer Felder mit dem National Characterset der Oracle-Datenbank. Bis 4000 Byte werden inline gespeichert, bei größeren Datenmengen wird außerhalb der Tabellenstruktur in einem eigenen Segment gespeichert. |
| LONG Oracle Datentyp zum Abspeichern langer Felder mit alphanumerischem Inhalt. Die Speicherung der Daten findet inline, also innerhalb der Tabellenstruktur statt; maximal 2 GB Größe. |
| LONG RAW Oracle Datentyp zum Abspeichern von binären Informationen; bei Oracle maximal 2 GB Größe. Seit Oracle 8 durch BLOB abgelöst. |
| OVERLOADING Speicherung von gleich benannten Funktionen oder Prozeduren innerhalb der Datenbank, die sich nur in Anzahl, Reihenfolge und/oder Datentyp unterscheiden. |
| BUILT-IN Eingebaute Verarbeitungsfunktionalitäten innerhalb von PL/SQL. |
Für eine Migration sprechen die folgenden Vorteile des LOB-Datentyps gegenüber dem LONG-Datentyp:
Mit der ALTER TABLE Anweisung kann eine LONG-Spalte in eine CLOB/NCLOB-Spalte geändert werden. Ebenso kann eine BLOB-Spalte aus einer LONG_RAW-Spalte generiert werden (siehe Abbildung 1).
Allgemeine Syntax:ALTER TABLE [<schema>.]<table_name>
MODIFY ( <long_column_name> { CLOB | BLOB | NCLOB }
[DEFAULT <default_value>]) [LOB_storage_clause];
Beispiel: CREATE TABLE mitarbeiter_lob (mitarbeiternr NUMBER, lob_foto LONG RAW); ALTER TABLE mitarbeiter_lob MODIFY (lob_foto BLOB); |
| Abb. 1: Allgemeine Syntax und ein Anwendungsbeispiel für die Wandlung des Datentyps. |
Dabei ist es möglich, ein DEFAULT-Constraint explizit anzugeben. Auch das Setzen der STORAGE-Klausel für die neue LOB-Spalte ist erlaubt. Bereits vorhandene Constraints auf einer LONG-Spalte werden bei der Migration übernommen.
Bei der Migration ist zu beachten, dass LOB-Spalten im Gegensatz zu LONG-Datentypen nicht in "geclusterten" Tabellen enthalten sein dürfen. Ebenso gilt, dass in der Auswahlliste eines UPDATE OF Trigger keine LOB-Spalten vorhanden sein dürfen. Es muss also vorher geprüft werden, ob die zu migrierende Tabelle diesen Triggertyp besitzt und in der UPDATE OF-Klausel Bezug auf LONG- bzw. LONG RAW-Spalten genommen wird.
Darüber hinaus ist zu beachten, dass bei der Migration von LONG- zu LOB-Datentypen die Indizes manuell neu aufgebaut werden müssen.
Besonders problematisch kann dies bei funktionsbasierten Indizes sein. Wenn eine Applikation damit arbeitet, muss sie nach der Migration nicht angepasst werden.
Für einen DOMAIN-Index gilt, dass dieser vor der Migration erst gelöscht werden muss! Für die entsprechende Erweiterung ist dann der Neueintrag vorzunehmen.
Es ist zu beachten, dass eine Konvertierung über Alter Table wieder zurück von LOB zu LONG nicht möglich ist. Ein Workaround bietet dabei allerdings die Möglichkeit, die Daten aus der LOB-Spalte über eine OCI-Applikation in eine neu generierte LONG-Spalte einzulesen. Danach kann die LOB-Spalte wieder gelöscht werden.
Für die Prüfung einer Anwendung (z. B. Packages), die sich auf LONG-Spalten bezieht, ist der Einsatz des Skriptes utldtree.sql sehr hilfreich. Damit wird geprüft, ob Teile der Anwendung möglicherweise neu geschrieben werden müssen. Zu finden ist das Skript im Verzeichnis $ORACLE_HOME/- rdbms/admin.
Das Skript erlaubt, alle Datenbankobjekte zu sehen, die rekursiv abhängig sind von einem anderen Datenbankobjekt. Es werden dabei nur diejenigen Datenbankobjekte angezeigt, für die auch eine Zugriffsberechtigung besteht.
Die Dokumentation ist im Skript selbst hinterlegt. Die Prüfung sollte immer vor der Migration der Tabellenspalten stattfinden. Das utldtree.sql Skript ist nur für PL/SQL erforderlich. Für SQL und OCI müssen die Bestandteile der entsprechenden Anwendung nicht geändert werden.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Abb. 2: Auszug aus den Konvertierungsfunktionen in SQL und PL/SQL. |
Mit PL/SQL ist es möglich, die folgenden SQL-Statements abzusetzen:
Ebenso ist es möglich, die folgenden Zuweisungen vorzunehmen:
Dadurch können Zuweisungen als aktuelle Parameterwerte mit einem LOB (CLOB, BLOB) Datentyp zu einem formalen Parameter eines anderen Datentyps (VARCHAR2, RAW) einer Datenbankfunktion durchgeführt werden.
Ebenso ist der Aufruf von PL/SQL Built-In-Funktionen mit LOB möglich. Die PL/SQL Built-In-Funktionen, die den Datentyp CLOB als Eingabeparameter und Rückgabewert benutzen, sind in Abbildung 2 dargestellt. In dieser Übersicht der Funktionen bedeutet die Angabe "CNV", dass erst implizit eine Konvertierung in einen alphanumerischen Datentyp vorgenommen wird. Die Angabe "N/A" bedeutet, dass bisher keinerlei Angaben vorhanden sind. Zu beachten ist dabei, dass im SQL-Umfeld nur bis 4 KB und im PL/SQL bis zu 32 KB dargestellt werden können.
Besonders zu beachten ist, dass die implizite Datentypkonvertierung auch in PL/SQL erlaubt ist:
Die Konvertierung von NUMBER, ROW_ID, BINARY_INTEGER, DATE und PLS_INTEGER nach LONG ist ebenfalls erlaubt. Allerdings gibt es nicht die Möglichkeit der impliziten Konvertierung zu einem LOB-Datentyp. Hierzu ist es erforderlich, mit der Konvertierungsfunktion TO_CHAR zu arbeiten. Erst dadurch wird erreicht, dass eine Konvertierung innerhalb eines Programms fehlerfrei erfolgt. Somit ist insbesondere der Quellcode von gespeicherten Datenbankobjekten, wie Packages, Prozeduren, Funktionen und Triggern, auf implizite Konvertierungen zu überprüfen.
Eine Übersicht über die explizit zu verwendenden Konvertierungsfunktionen in PL/SQL finden Sie in Abbildung 3.
|
||||||||||||
| Abb. 3: Konvertierungsfunktionen für die explizite Datentypkonvertierung in PL/SQL. |
Die Fehlerbehandlung bei der Konvertierung gestaltet sich wie folgt: Wenn mit einer dieser Funktionen versucht wird, in den entsprechenden Zeichensatz der Datenbank zu konvertieren und der konvertierte Wert größer ist als der maximal zu speichernde Wert, so wird eine Fehlermeldung ausgegeben. Das gleiche gilt auch für die implizite Datentypkonvertierung.
Generell darf ein Overloading existieren, solange ein Unterschied zweier Prozeduren bezüglich Anzahl, Namen, Reihenfolge und/oder Datentyp der formalen Parameter existiert.
Wir nehmen einmal an, es existierten vor der Migration zwei Prozeduren mit gleichem Namen und nur mit der Differenzierung durch LOB- und LONG-Datentyp. Nach einer Konvertierung von LONG zu LOB würden dann innerhalb des Programms zwei Prozeduren mit gleicher Anzahl, Namen, Reihenfolge und Datentyp der formalen Parameter existieren. Dies würde einen Oracle-Fehler auslösen und somit dem Konzept des Overloading widersprechen.
Eine Besonderheit stellt die Parameterübergabe durch %TYPE und %ROWTYPE dar. Hierdurch ist es möglich, nach einer Konvertierung einer Tabellenspalte zu einem LOB-Datentyp mit den neuen Werten zu arbeiten (siehe Abbildung 4). Die schon oben erwähnten Konvertierungsrichtungen sind dabei möglich.
CREATE TABLE test_long (long_sp LONG); -- Wechsel von LONG nach LOB
DECLARE
var_1 VARCHAR2(100);
var_2 test_long.long_sp%type; -- Diese Variable wechselt von LONG nach CLOB
BEGIN
SELECT *
INTO var_2
FROM test_long;
var_1 := var_2; -- Wechsel von VARCHAR2 := LONG nach VARCHAR2 := CLOB
var_2 := var_1; -- Wechsel von LONG := VARCHAR2 nach CLOB := VARCHAR2
END;
/ |
| Abb. 4: Verwendung von %TYPE und %ROWTYPE. |
Das Entscheidende an der Migration von LONG- zu LOB-Datentypen sind die entsprechenden Vorüberlegungen, die angestellt werden müssen. Die Migration selbst ist relativ simpel, aber die Auswirkung ("Einmal LOB, immer LOB") ist relativ schwerwiegend.
Klaus Günther (info@ordix.de).