Oracle PL/SQL: kurz & gut

Inhaltsverzeichnis

1. Oracle PL/SQL – kurz & gut
Einleitung
Danksagung
Konventionen
PL/SQL-Sprachgrundlagen
Der PL/SQL-Zeichensatz
Bezeichner
Boolesche, numerische und Zeichenliterale
Numerische Literale
Datums- und Uhrzeit-Intervall-Literale
Begrenzer
Kommentare
Pragmas
Anweisungen
Blockstruktur
Variablen und Programmdaten
Skalare Datentypen
LOB-Datentypen
Implizite Datentyp-Umwandlung
NULL in PL/SQL
Variablen deklarieren
Verankerte Deklarationen
Programmiererdefinierte Subtypen
Bedingte und sequenzielle Kontrollstrukturen
Bedingte Kontrollstrukturen
Sequenzielle Kontrollstrukturen
Schleifen
Einfache Schleife
Numerische FOR-Schleife
Cursor-FOR-Schleife
WHILE-Schleife
REPEAT UNTIL-Schleife emulieren
EXIT-Anweisung
CONTINUE-Anweisung (Oracle Database 11g)
Schleifen-Label
Interaktion mit der Datenbank
Sequenzen in PLSQL
Transaktionsverwaltung
Autonome Transaktionen
Cursor in PL/SQL
Explizite Cursor
Implizite Cursor
Dynamische Cursor
DBMS_SQL
SQL-Injektion und Bind-Variablen
Cursor-Variablen
Cursor-Ausdrücke
Exception-Handling
Exceptions deklarieren
Exceptions auslösen
Geltungsbereich
Propagierung
Datensätze in PL/SQL
Datensätze deklarieren
Datensatz-Felder referenzieren
Datensätze zuweisen
Datensätze und DML
Geschachtelte Datensätze
Collections in PL/SQL
Eine Collection deklarieren
Eine Collection initialisieren
Elemente hinzufügen und entfernen
Funktionen für geschachtelte Tabellen
Collection-Methoden
Collections und Zugriffsrechte
Geschachtelte Collections
Bulk Binds
Eingebaute Funktionen und Packages
Eingebaute Funktionen
Eingebaute Funktionen für reguläre Ausdrücke
Eingebaute Packages
Gespeicherte Prozeduren und Funktionen
Prozeduren
Funktionen
Parameter
Lokale Programme
Programme überladen
Vorwärts-Deklarationen
Tabellenfunktionen
Funktionsergebnis-Cache
Zugriffsrechte und gespeichertes PL/SQL
Trigger
Trigger erzeugen
Trigger-Prädikate
DML-Ereignisse
Zusammengesetzte DML-Trigger
DDL-Ereignisse
Datenbank-Ereignisse
Packages
Package-Struktur
Package-Elemente referenzieren
Package-Daten
Das Pragma SERIALLY_REUSABLE
Package-Initialisierung
PL/SQL-Funktionen in SQL aufrufen
Eine Funktion aufrufen
Package-Funktionen in SQL aufrufen
Vorrang der Spaltenangabe vor dem Funktionsnamen
Objektorientierte Features
Objekttypen
Typvererbung
Methoden
Methoden in Subtypen
Objekte mit PL/SQL und SQL manipulieren
Upcasting und Downcasting
Objekttypen ändern
Kompilierung
Gespeicherte PL/SQL-Programme kompilieren
Bedingte Kompilierung
Compiler-Warnungen
Der optimierende Compiler
Native Kompilierung von PL/SQL durchführen
Java-Integration
Beispiel
PL/SQL den Zugriff auf Java-Code ermöglichen
Data Dictionary
4.

Oracle PL/SQL: kurz & gut

Steven Feuerstein

Bill Pribyl

Chip Dawes

Die Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer übernehmen keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen.

Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind möglicherweise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikrovefilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.

Die Darstellung von Ameisen im Zusammenhang mit dem Thema Oracle PL/SQL ist ein Warenzeichen von O'Reilly Media, Inc.

Oracle® und alle Oracle-basierten Warenzeichen und Logos sind Warenzeichen oder eingetragene Warenzeichen der Oracle Corporation, Inc. in den USA und in anderen Ländern. Der O'Reilly Verlag ist unabhängig von der Oracle Corporation.

Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.

Satz: FKM, Neumünster

4.

O'Reilly Media Germany

Kapitel 1. Oracle PL/SQL – kurz & gut

Einleitung

Oracle PL/SQL – kurz & gut ist eine Schnellreferenz zur Programmiersprache PL/SQL, die prozedurale Erweiterungen der relationalen Datenbanksprache SQL und zahlreiche Oracle-Entwicklungstools zur Verfügung stellt. Überall dort, wo ein Package, eine Prozedur oder Funktion nur von einer bestimmten Version der Oracle-Datenbank (z.B. Oracle Database 11g) unterstützt wird, finden Sie einen entsprechenden Hinweis im Text.

Der Zweck dieser Taschenreferenz ist es, dem Benutzer von Oracle PL/SQL das Auffinden der Syntax von bestimmten Sprachelementen zu erleichtern. Sie ist jedoch kein vollständiges Benutzerhandbuch. Grundkenntnisse in der Programmiersprache PL/SQL werden vorausgesetzt. Weitere Informationen finden Sie in den folgenden O'Reilly-Büchern:

Oracle PL/SQL Programming, 4. Auflage, von Steven Feuerstein mit Bill Pribyl
Learning Oracle PL/SQL von Bill Pribyl mit Steven Feuerstein
Oracle PL/SQL Best Practices, 2. Auflage, von Steven Feuerstein
Oracle in a Nutshell von Rick Greenwald und David C. Kreines

Danksagung

Wir danken all denen, die an diesem Buch mitgearbeitet haben. Besonderer Dank gilt Bryn Llewelyn für seine Beiträge zur letzten Überarbeitung und zur dritten Auflage. Vielen Dank auch den Gutachtern der ersten Auflage, Eric J. Givler und Stephen Nelson, und dem Gutachter für die zweite und dritte Auflage, Jonathan Gennick. Außerdem wollen wir uns für die gute Arbeit der O'Reilly-Mannschaft bei der Bearbeitung und Produktion dieses Buchs bedanken.

Konventionen

GROSSBUCHSTABEN

Zeigen PL/SQL-Schlüsselwörter sowie bestimmte Bezeichner an, die von der Oracle Corporation als Namen eingebauter Funktionen und Pakete verwendet werden.

Kursiv

Zeigt Datei- und Verzeichnisnamen sowie Begriffseinführungen an.

Nichtproportionalschrift

Wird für Programmbeispiele, Zeichenliterale und Bezeichner verwendet.

Nichtproportionalschrift fett

Zeigt in Beispielen, die Interaktionen illustrieren, Benutzereingaben an.

[]

Schließen in Syntaxbeschreibungen optionale Elemente ein.

{}

Schließen in Syntaxbeschreibungen eine Liste ein, aus der Sie ein Element auswählen müssen.

|

Grenzt die Listenelemente in Syntaxbeschreibungen voneinander ab.

PL/SQL-Sprachgrundlagen

Dieser Abschnitt fasst die grundlegenden Bestandteile der PL/SQL-Sprache zusammen: Zeichen, Bezeichner, Literale, Begrenzer, die Verwendung von Kommentaren und Pragmas sowie den Aufbau von Anweisungen und Blöcken.

Der PL/SQL-Zeichensatz

Die Programmiersprache PL/SQL wird aus Buchstaben, Zahlen, Symbolen und Whitespace-Zeichen aufgebaut, die in der folgenden Tabelle genauer definiert werden:

Typ

Zeichen

Buchstaben

A–Z, a–z

Zahlen

0–9

Symbole

˜!@#$%^&*( )_-+=|[ ]{ }:;"'< >,.?/ ^

Whitespace-Zeichen

Leerzeichen, Tabulator, Zeilenvorschub, Wagenrücklauf

Zeichen werden zu vier lexikalischen Einheiten gruppiert: zu Bezeichnern, Literalen, Begrenzern und Kommentaren.

Bezeichner

Bezeichner sind Namen für PL/SQL-Objekte wie Konstanten, Variablen, Exceptions, Prozeduren, Cursor und reservierte Wörter. Bezeichner besitzen die folgenden Merkmale:

  • Sie können bis zu 30 Zeichen lang sein.

  • Sie dürfen keine Whitespace-Zeichen (Leerzeichen, Tabulator, Wagenrücklauf) enthalten.

  • Sie müssen mit einem Buchstaben beginnen.

  • Sie können Dollar-Zeichen ($), Unterstriche ( _ ) oder Pfund-Zeichen enthalten (#).

  • Sie berücksichtigen keine Groß-/Kleinschreibung.

Außerdem dürfen Sie keine PL/SQL-Schlüsselwörter als Bezeichner verwenden.

Sie sollten davon absehen, die reservierten Wörter von PL/SQL in Ihren Programmen als Bezeichner zu verwenden, da das zu Kompilier- oder Laufzeitfehlern führen kann, die schwer zu lösen sind.

Tipp

In früheren Ausgaben enthielt dieses Buch eine Liste der reservierten Wörter. In der V$RESERVED_WORDS-Data-Dictionary-View von Oracle Database 11g Release 1 werden mittlerweile jedoch mehr als 1.600 Wörter als reserviert aufgeführt. Bei unseren Tests haben wir festgestellt, dass mehr als 650 dieser Wörter nicht als Namen von Prozeduren oder Variablen verwendet werden können. Schlagen Sie in V$RESERVED_WORDS nach, wenn Sie eine Liste der nicht unterstützten Bezeichner suchen, und vermeiden Sie diese als Programm- oder Variablennamen.

Wenn Bezeichner in Anführungszeichen eingeschlossen sind, werden alle oben genannten Regeln außer der ersten ignoriert. So ist z.B. die folgende Deklaration gültig:

DECLARE
   "1 ^abc"  VARCHAR2(100);
BEGIN
   IF "1 ^abc" IS NULL THEN ...
END;

Boolesche, numerische und Zeichenliterale

Literale sind spezifische Werte, die nicht durch Bezeichner dargestellt werden. So sind z.B. TRUE, 3.14159, 6.63E-34, 'Moby Dick' und NULL allesamt Boolesche, numerische oder Zeichenliterale. Es gibt keine Literale von komplexen Datentypen, da ihre Werte interne Darstellungen sind; komplexe Typen erhalten ihre Werte durch eine direkte Zuweisung über einen Konstruktor. Anders als das übrige PL/SQL berücksichtigen Literale die Groß-/Kleinschreibung. Um einfache Anführungszeichen in ein Zeichenliteral einzubetten, müssen Sie zwei einfache Anführungszeichen nebeneinanderstellen.

Seit Oracle Database 10g können Sie Ihren eigenen Angabemechanismus für String-Literale in Ihren SQL- sowie PL/SQL-Anweisungen definieren. Verwenden Sie die Zeichen q' (q und ein einfaches gerades Anführungszeichen), um den selbst definierten Begrenzer für Ihre String-Literale anzuzeigen. Schließen Sie den literalen String mit dem selbst definierten Begrenzer und einem anhängenden einfachen Anführungszeichen – z.B. q'!mein String!'. NCHAR- und NVARCHAR-Begrenzern werden die Buchstaben nq vorangestellt, z.B. nq'^NCHAR-String^'. Diese Technik kann Ihren Code vereinfachen, wenn in einem String mehrere aufeinanderfolgende einfache Anführungszeichen auftauchen, wie es bei den Literalen in SQL-Anweisungen der Fall ist. Wenn Sie Ihren Begrenzer mit einem der vier Klammerzeichen ( [ {< definieren, müssen Sie als schließenden Begrenzer auch die schließende Klammerversion verwenden. Beispielsweise muss q'[ mit ]' geschlossen werden.

Die folgende Tabelle zeigt einige Beispiele:

Literal

Tatsächlicher Wert

'That''s Entertainment!'

That's Entertainment!

q'#That's Entertainment!#'

That's Entertainment!

'"Der Rabe"'

"Der Rabe"

'TZ=''CDT6CST'''

TZ='CDT6CST'

q'$TZ='CDT6CST'$'

TZ='CDT6CST'

q'[TZ='CDT6CST']'

TZ='CDT6CST'

''''

'

'''Hallo Welt'''

'Hallo Welt'

q'!'Hallo Welt'!'

'Hallo Welt'

''''''

''

q'['']'

"

nq'<Price='£10'>'

Price='£10'

nq'-WHERE name LIKE 'ñ'-'

WHERE name LIKE 'ñ'

Numerische Literale

Eventuell können Sie die Laufzeitperformance verbessern, wenn Sie den Datentyp numerischer Literale explizit angeben. Das erreichen Sie, indem Sie den Dezimaltrenner aus- oder einschließen oder indem Sie an den Zahlwert ein f oder d anhängen. Beispiele sehen Sie in der folgenden Tabelle:

Literal

Datentyp

3.14159

NUMBER

42

INTEGER

0.0

NUMBER

3.14159f

BINARY_FLOAT

3.14159d

BINARY_DOUBLE

Oracle Database 10g hat einige spezielle benannte Konstanten eingeführt:

BINARY_FLOAT_NAN (Not a Number, keine Zahl)
BINARY_FLOAT_INFINITY
BINARY_FLOAT_MAX_NORMAL
BINARY_FLOAT_MIN_NORMAL
BINARY_FLOAT_MAX_SUBNORMAL
BINARY_FLOAT_MIN_SUBNORMAL

Zu diesen Konstanten gibt es jeweils noch BINARY_DOUBLE_-Versionen.

Datums- und Uhrzeit-Intervall-Literale

Die in Oracle9i eingeführten Datums- und Uhrzeit-Intervall-Datentypen stellen ein zeitliches Intervall dar, das entweder in Jahren und Monaten oder in Tagen, Stunden, Minuten, Sekunden und Sekundenbruchteilen ausgedrückt wird. Literale dieser Datentypen werden über das Schlüsselwort INTERVAL angegeben, auf das das Literal und der/die Formatierungsstring(s) folgen. Bei der Intervallangabe müssen die größeren Felder den kleineren vorausgehen: Das heißt, YEAR TO MONTH ist zulässig, aber MONTH TO YEAR nicht. Beispiele finden Sie in der folgenden Tabelle:

Literal

Tatsächlicher Wert

INTERVAL '1–3' YEAR TO MONTH

1 Jahr und 3 Monate später

INTERVAL '125–11' YEAR(3) TO MONTH

125 Jahre und 11 Monate später

INTERVAL '−18' MONTH

18 Monate früher

INTERVAL '-48' HOUR

48 Stunden früher

INTERVAL '7 23:15' DAY TO MINUTE

7 Tage, 23 Stunden und 15 Minuten später

INTERVAL '1 12:30:10.2' DAY TO SECOND

1 Tag, 12 Stunden, 30 Minuten und 10,2 Sekunden später

INTERVAL '12:30:10.2' HOUR TO SECOND

12 Stunden, 30 Minuten und 10,2 Sekunden später

Begrenzer

Begrenzer sind Symbole mit einer besonderen Bedeutung, beispielsweise := (Zuweisungsoperator), || (Verkettungsoperator) und ; (Anweisungsbegrenzer). Die folgende Tabelle führt die PL/SQL-Begrenzer auf:

Begrenzer

Beschreibung

;

Terminator (für Anweisungen und Deklarationen)

+

Additionsoperator

-

Subtraktionsoperator

*

Multiplikationsoperator

/

Divisionsoperator

**

Exponentialoperator

||

Verkettungsoperator

:=

Zuweisungsoperator

=

Gleichheitsoperator

<> und !=

Ungleichheitsoperatoren

^= und ˜=

Ungleichheitsoperatoren

<

»Kleiner als«-Operator

<=

»Kleiner oder gleich«-Operator

>

»Größer als«-Operator

>=

»Größer oder gleich«-Operator

( und )

Ausdruck- oder Listenbegrenzer

<< und >>

Labelbegrenzer

,

Element-Trennzeichen (Komma)

'

Literalbegrenzer (einfaches Anführungszeichen)

q' und '

Selbst definierte Begrenzer für String-Literale

nq' und '

Selbst definierte Begrenzer für NCHAR-String-Literale

"

Gequoteter Literalbegrenzer (doppeltes Anführungszeichen)

:

Hostvariablenanzeiger

%

Attributanzeiger

.

Komponentenanzeiger, wie z.B. in Datensatz.Feld oder Package.Element (Punkt)

@

Anzeiger für eine Remote-Datenbank (Datenbanklink)

=>

Zuordnungsoperator (benannte Notation)

..

Bereichsoperator in der FOR-Schleife (zwei Punkte)

--

Anzeiger für einzeiligen Kommentar

/* und */

Begrenzer für mehrzeiligen Kommentar

Kommentare

Kommentare sind Abschnitte des Programmcodes, die die Lesbarkeit verbessern. Sie werden vom Compiler ignoriert.

Ein einzeiliger Kommentar beginnt mit einem doppelten Bindestrich (--) und endet mit einer neuen Zeile. Der Compiler ignoriert alle Zeichen zwischen -- und der neuen Zeile.

Ein mehrzeiliger Kommentar beginnt mit Schrägstrich-Stern (/*) und endet mit Stern-Schrägstrich (*/ ). Der Kommentarbegrenzer /* */ kann aber auch für einzeilige Kommentare verwendet werden. Der folgende Block demonstriert beide Arten von Kommentaren:

DECLARE
   -- Zwei Bindestriche kommentieren diese Zeile aus.
   /* Alles ist hier Kommentar, bis der Compiler auf das
      folgende Symbol trifft. * /

Sie können keine mehrzeiligen Kommentare in einen mehrzeiligen Kommentar einbetten. Darauf müssen Sie bei der Entwicklung achten, wenn Sie Code auskommentieren, der Kommentare enthält. Der folgende Programmcode demonstriert dies:

DECLARE
   /* Alles ist hier Kommentar, bis der Compiler
      /* Dieser innere Kommentar ist nicht erlaubt! */
      auf das folgende Symbol trifft. */

   /* Alles ist hier Kommentar, bis der Compiler
      -- Dieser innere Kommentar ist erlaubt!
      auf das folgende Symbol trifft. */

Pragmas

Das Schlüsselwort PRAGMA wird verwendet, um dem Compiler Anweisungen zu erteilen. Es gibt fünf Pragmas in PL/SQL:

AUTONOMOUS_TRANSACTION

Teilt dem Compiler mit, dass die Funktion, die Prozedur, der anonyme Top-Level-PL/SQL-Block, die Objektmethode oder der Datenbank-Trigger in ihrem bzw. seinem eigenen Transaktionsspeicher ausgeführt wird. Weitere Informationen zu diesem Pragma finden Sie im Abschnitt »Interaktion mit der Datenbank«.

EXCEPTION_INIT

Teilt dem Compiler mit, dass die angegebene Fehlernummer mit dem Bezeichner verknüpft werden soll, der im aktuellen Programm oder in einem Package, auf das zugegriffen werden kann, als EXCEPTION deklariert wurde. Im Abschnitt »Exception-Handling« finden Sie weitere Informationen zu diesem Pragma.

INLINE

Sagt dem Compiler, ob Aufrufe eines Unterprogramms durch eine Kopie des Unterprogramms ersetzt werden sollen oder nicht. Weitere Informationen zur Inline-Optimierung finden Sie im Abschnitt »Der optimierende Compiler«.

RESTRICT_REFERENCES

Teilt dem Compiler den Reinheitsgrad (purity level) eines Programms mit. Der Reinheitsgrad ist ein Maß dafür, inwieweit ein Programm keinen lesenden/schreibenden Zugriff auf Datenbanktabellen und/oder Package-Variablen durchführt. Siehe den Abschnitt »PL/SQL-Funktionen in SQL aufrufen« zu diesem Pragma.

SERIALLY_REUSABLE

Teilt dem Laufzeitmodul mit, dass Package-Daten nicht persistent zwischen verschiedenen Referenzen gehalten werden sollen. Dies wird zur Verringerung des Speicherbedarfs verwendet, falls das jeweilige Package nur für die Dauer eines Aufrufs (und nicht während der gesamten Session) benötigt wird. Im Abschnitt »Packages« finden Sie weitere Informationen zu diesem Pragma.

Anweisungen

Ein PL/SQL-Programm besteht aus einer oder mehreren logischen Anweisungen. Eine Anweisung wird mit einem Semikolon abgeschlossen. Die physische Markierung des Zeilenendes wird vom Compiler ignoriert. Die Ausnahme ist hier ein einzeiliger Kommentar (eingeleitet durch das Zeichen --).

Blockstruktur

Jedes PL/SQL-Programm ist ein Block, der aus einem Standardsatz von Elementen besteht, die durch Schlüsselwörter identifiziert werden (siehe Abbildung 1-1). Der Block bestimmt den Geltungsbereich der deklarierten Elemente sowie die Behandlung von Exceptions und deren Verarbeitung. Ein Block kann entweder anonym oder benannt sein. Benannte Blöcke enthalten Funktionen, Prozeduren, Packages und Trigger.

Die PL/SQL-Blockstruktur

Abbildung 1-1. Die PL/SQL-Blockstruktur


Hier ein Beispiel für einen anonymen Block:

DECLARE
   today DATE DEFAULT SYSDATE;
BEGIN
   -- Gib das Datum aus.
   DBMS_OUTPUT.PUT_LINE ('Heute ist ' || today);
END;

Nun folgt ein benannter Block, der die gleiche Aktion ausführt:

CREATE OR REPLACE PROCEDURE show_the_date
IS
   today DATE DEFAULT SYSDATE;
BEGIN
   -- Gib das Datum aus.
   DBMS_OUTPUT.PUT_LINE ('Heute ist ' || today);
END show_the_date;

Die folgende Tabelle fasst die Abschnitte eines PL/SQL-Blocks zusammen:

Abschnitt

Beschreibung

Kopf

Bei benannten Blöcken erforderlich. Gibt an, wie das Programm von äußeren PL/SQL-Blöcken aufgerufen wird. Anonyme Blöcke haben keinen Kopf. Sie beginnen mit dem Schlüsselwort DECLARE, falls es einen Deklarationsabschnitt gibt, oder dem Schlüsselwort BEGIN, falls es keine Deklarationen gibt.

Deklaration

Optional. Deklariert Variablen, Cursor, Typen (TYPE) sowie lokale Programme, die in den Abschnitten des Blocks oder der Exceptions verwendet werden.

Ausführung

Optional in Package- und TYPE-Spezifikationen. Enthält Anweisungen, die ausgeführt werden, wenn der Block aufgerufen wird.

Exception

Optional. Beschreibt das Verhalten bei der Fehlerbehandlung, falls Exceptions im Ausführungsabschnitt ausgelöst werden.