PL/SQL
PL/SQL | |
---|---|
Basisdaten | |
Paradigmen: | prozedural |
Erscheinungsjahr: | 1991 |
Entwickler: | Oracle |
Aktuelle Version: | 10.2 (2005) |
Typisierung: | stark, statisch, explizit |
Beeinflusst von: | Ada[1] |
Betriebssystem: | plattformunabhängig |
Lizenz: | proprietär |
Oracle Technology Network |
PL/SQL (Procedural Language/Structured Query Language) ist eine proprietäre Programmiersprache der Firma Oracle. PL/SQL-Programme werden von den relationalen Datenbanksystemen von Oracle serverseitig ausgeführt.
PL/SQL verbindet die Geschwindigkeit der Abfragesprache SQL mit dem Komfort prozeduraler Programmiersprachen. Die Syntax wurde sehr stark an die Programmiersprache Ada angelehnt.
Unterstützt werden Variablen, Bedingungen, Schleifen und Ausnahmen. Ab der Version 8 der Oracle-RDBMS halten auch objektorientierte Merkmale Einzug.
PL/SQL ist besonders für das Arbeiten mit Datenbanken ausgelegt. Insbesondere kann man im Quelltext SQL-Befehle nach dem Oracle-Standard einfügen. Dabei werden die SQL-Anweisungen nicht als Zeichenketten erzeugt und an eine Datenbankschnittstelle übergeben (wie z.B. bei ODBC, JDBC u.ä.), sondern fügen sich nahtlos in den Programmcode ein. Die Korrektheit der SQL-Statements kann somit schon durch Kompilieren verifiziert werden, zumindest wenn diese statisch, also nicht erst zur Laufzeit erzeugt sind.
Dies gilt jedoch ausschließlich für DML-Befehle. DDL und DCL müssen mit dbms_sql (einem PL/SQL-Package) oder mit der Syntax "execute immediate <befehl>" ausgeführt werden.
Verwendung
- Man kann PL/SQL-Code wie SQL-Befehle über ein Datenbank-Frontend absetzen, der dann direkt abgearbeitet wird
- Man kann einzelne Unterprogramme (Stored Procedures) oder Bibliotheken mehrerer Unterprogramme (Packages) als dauerhafte Datenbankobjekte auf dem Datenbankserver speichern und damit die Funktionalität der Datenbank erweitern; jeder Benutzer der Datenbank kann diese Unterprogramme aufrufen und nutzen. Die Berechtigungen können für jedes einzelne PL/SQL-Paket an einzelne Benutzer bzw. Benutzergruppen (sogenannte 'Rollen') vergeben werden.
- Programmierung von Datenbanktriggern
- Programmierung in diversen Tools (Oracle-Forms, Oracle-Reports)
Der Vorteil von PL/SQL ist, dass Programme direkt auf der Datenbank ausgeführt werden, was zu einem erheblichen Geschwindigkeitsvorteil führt. Konkret kann Kommunikation zwischen Prozessen und eventuell Netzwerkverkehr - falls Datenbank und Applikationsserver auf unterschiedlicher Hardware ausgeführt werden - vermieden werden.
Grundlegender Aufbau
PL/SQL Programme bestehen aus Blöcken:
declare -- Deklarationsblock begin -- Eigentliches Programm exception -- Ausnahmeverarbeitung end;
- /* So kommentiert man
- mehrzeilig */
- --So kommentiert man einzeilig
Variablendefinitionen
Variablen werden im (optionalen) Deklarationsabschnitt definiert und optional initialisiert.
declare Zahl1 number(2); Zahl2 number(2) := 17; Text varchar(20) := 'Das ist ein Text'; begin select hausnummer into Zahl1 from Adressverzeichnis where name='Meier'; end;
:= ist der Zuweisungsoperator, mit dem man einer Variable einen Wert zuweist.
Zahlenvariablen
variablenname number(P[,S]) := Wert;
Um eine Zahlenvariable zu definieren, schreibt man den Variablennamen gefolgt vom Variablentyp "number".
Hinter diesem schreibt man in runden Klammern die Genauigkeit P sowie optional ein Komma und die Anzahl an Nachkommastellen S.
Genauigkeit entspricht in diesem Fall der Anzahl an Stellen, welche die Variable enthalten kann, und nicht dem Wertebereich.
Auswahl weiterer Datentypen für Zahlenvariablen:
- dec, decimal, double precision, integer, int, numeric, real, smallint, binary_integer, pls_integer
Textvariablen
variablenname varchar(L) := 'Text';
Um eine Textvariable zu definieren, schreibt man den Variablennamen gefolgt vom Variablentyp "varchar".
Hinter diesem schreibt man die Anzahl der Zeichen, die in der Variable gespeichert werden können, in Klammern.
Auswahl weiterer Datentypen für Textvariablen:
- varchar, varchar2, char, long, raw, long raw, nchar, nchar2, clob
Boolean
variablenname boolean:= true;
Kann TRUE, FALSE oder NULL sein.
Datum
variablenname date :=to_date( '01.01.2005' , 'DD.MM.YYYY');
Um eine Datumsvariable zu definieren schreibt man den Variablennamen gefolgt vom Variablentyp "date".
Damit man einen Text in ein Datum konvertieren kann, stellt Oracle die Funktion to_date zur Verfügung.
Diese Funktion wandelt den Text zwischen den ersten Hochkommas in ein Datum mit dem angegebenen Format zwischen den zweiten Hochkommas um.
Beispiel: "to_date('31.12.2004','dd.mm.yyyy')"
Um ein Datum in einen Text zu konvertieren, gibt es die Funktion to_char(Datum).
Datentyp über Spalte festlegen
Variablenname Tabellenname.Spaltenname%type;
Definiert eine Variable des Typs der angegebenen Spalte.
Datentyp über Tabelle festlegen
Variablenname Tabellenname%rowtype;
Definiert eine Variable des Typs der angegebenen Tabelle.
Beispiel :
CURSOR cursor_name IS SELECT * FROM tabelle; variable tabelle%rowtype; ... FOR i IN cursor_name LOOP variable := i; andere_variable := variable.SPALTENNAME; END LOOP;
Benutzerdefinierte Datentypen
Benutzerdefinierte Datentypen werden mit Hilfe von "type datentyp is record(feld1 typ1 :=xyz, feld2 typ2 :=xyz, ..., feldn typn :=xyz);" definiert.
declare type t_adresse is record( hausname adresse.hausname%type, strasse adresse.strasse%type, hausnummer adresse.hausnummer%type, postleitzahl adresse.postleitzahl%type); v_adresse t_adresse; begin select hausname,strasse, hausnummer, postleitzahl into v_adresse from adresse where rownum = 1; end;
Das Beispielprogramm definiert einen eigenen Datentyp mit Namen t_adresse welcher die Felder hausname, strasse, hausnummer und postleitzahl enthält.
Mit diesem Datentyp wird eine Variable v_adresse definiert, welche mit einem Datensatz aus der Tabelle adresse gefüllt wird.
Mittels Punktnotation kann auf die Attribute zurückgegriffen werden "v_adresse.hausname := 'Nollenburgerweg 115';"
Schleifen
Schleifen wiederholen die in ihrem Körper enthaltenen Anweisungen.
Loop-Schleife (Basisschleife)
loop ... exit when BEDINGUNG; end loop;
Die loop-Schleife wiederholt die in ihrem Körper enthaltenen Anweisungen. Sie kann durch ein "exit when" gefolgt von einer Abbruchbedingung beendet werden.
- Beachte: Auch wenn die Bedingung für das "exit" erfüllt sein sollte werden die Anweisungen im Schleifenkörper mindestens einmal ausgeführt.
While-Schleife
while Bedingung loop ... end loop;
Die while-Schleife wiederholt die in ihrem Körper enthaltenen Anweisungen, so lange die Bedingung in ihrem Kopf erfüllt ist.
- Beachte: Sollte die Bedingung im Kopf nicht erfüllt sein, werden die Anweisungen im Schleifenkörper nie ausgeführt.
For-Schleife
for v_counter in 1..10 loop ... end loop;
Die for-Schleife zählt eine Indexvariable von einem festgelegten Startwert bis zu einem festgelegten Endwert. Der kleinere Wert steht immer links, der größere immer rechts. Gibt man das Schlüsselwort REVERSE nach dem IN an, so wird vom größeren zum kleineren Wert heruntergezählt.
- Beachte: Auch hierbei muss der kleinere Wert links und der größere Wert rechts stehen.
begin for i in reverse 1 .. 5 loop dbms_output.put_line(to_char(i)); end loop; end; 5 4 3 2 1
- Hinweis: Wenn Sie beim Arbeiten mit SQL*Plus die erwarteten Zahlen 5 bis 1 nicht sehen, müssen Sie vorher die Ausgabe einschalten
set serveroutput on
Cursor-For-Schleife
for Record-Index in (Select Mitarbeiter_Nummer from Personaltabelle) loop
... end loop;
Die Cursor for-Schleife öffnet automatisch den Cursor, liest die Datensätze ein und schließt den Cursor wieder.
Alternativ dazu kann das SELECT-Statement des Cursors auch vorher definiert werden, um es mehrfach zu verwenden bzw. um die Darstellung übersichtlicher zu gestalten (besonders bei längeren/komplexeren Abfragen von Vorteil).
cursor cursor_mitarbeiter is Select Mitarbeiter_Nummer from Personaltabelle;
for Record-Index in cursor_mitarbeiter loop
... end loop;
Der Zugriff auf die Mitarbeiter-Nummer innerhalb der FOR-Schleife erfolgt mit dem Verbindungsoperator ".":
- Record-Index.Mitarbeiter_Nummer
Bedingungen
Mit Hilfe von Bedingungen kann man auf verschiedene Situationen unterschiedlich reagieren.
If-Then-Else
declare v_land welt.land%type; begin dbms_output.enable(20000); select land into v_land from welt where rownum = 1; if v_land = 39 then dbms_output.put_line('Land ist 39'); elsif v_land = 49 then dbms_output.put_line('Land ist 49'); else dbms_output.put_line('Land unbekannt'); end if; end;
'if' prüft, ob eine Bedingung erfüllt ist. Ist die Bedingung erfüllt, wird der Code zwischen 'if' und 'end if' ausgeführt, ansonsten wird er übersprungen. Optional kann mit 'elsif' eine weitere Bedingung mit zugehörigem Code angegeben werden, der ausgeführt wird, falls diese Bedingung erfüllt ist. Zu guter Letzt kann man ein allgemeines 'else' angeben, dessen Code ausgeführt wird, wenn keine der vorangegangen Bedingungen erfüllt waren.
Simple CASE
CASE <variable> WHEN <Ausdruck1> THEN <ausführen>; WHEN <Ausdruck2> THEN <ausführen>; . WHEN <Ausdruckn> THEN <ausführen>; ELSE <ausführen>; END CASE; /
CASE vergleicht eine Variable mit einem Ausdruck und gibt bei einer Übereinstimmung einen Wert zurück.
Searched CASE
CASE WHEN <variable> < <Wert> THEN <ausführen>; WHEN <variable> between <Wert> and <Wert> THEN <ausführen>; . WHEN <Vergleich> THEN <ausführen>; ELSE <ausführen>; END CASE; /
In der WHEN-Klausel wird ein Ausdruck mit einem 2. verglichen. Dabei muss das Ergebnis einen Booleschen Wert zurück geben.
Select
Mit Hilfe von Selects ruft man Daten aus einer Datenbank ab:
- select vorname,name,adresse from benutzer where id = 1028
Dieser Select liefert den Namen, Vornamen und die Adresse aus der Tabelle "benutzer" mit der id 1028.
Ein Select besteht immer aus:
- select Spalte1, Spalte2, Spalte3,...,Spalten from Tabellenname where SpalteX = 'abc' and SpalteY = 123 or SpalteZ = 'xzy'
Mit Hilfe von Where gibt man Bedingungen an, um die Auswahl einzuschränken. Mit Hilfe von Or, Not oder And kann man diese noch verknüpfen.
Mittels
- select land into v_land from welt where rownum= 1
kann man Daten aus einem Select in einer Variable speichern.
Insert
Mit Hilfe von Inserts speichert man Daten in einer Datenbank.
- insert into adresse values('Müller','Feldweg','82','74414','Baumhausen')
Ein Insert besteht immer aus:
- insert into Tabellenname values('Wert1','Wert2','Wert3',[..],'Wertn')
oder
- insert into Tabellenname select Spalten from Tabellenname2 where Bedingungen
Noch ein Beispiel:
- insert into deutschland select * from england
Alle Daten aus England werden in Deutschland kopiert.
Update
Mit Hilfe von Update ändert man Daten in einer Datenbank:
- update adresse set hausname = 'Kunz', strasse = 'Holzweg' where hausname = 'Müller'
Ein Update besteht immer aus:
- update Tabellenname set Spalte1 = 'abc', Spalte2 = 123, [..], Spalten = 'xyz' where Spaltex = 'abc' and Spaltey = 321 or Spaltez = 123
Mit Hilfe von Where gibt man Bedingungen an, um das Update einzuschränken. Diese kann mit Hilfe von Or, Not oder And noch verknüpfen.
Vergleichbare Möglichkeiten der Programmierung bei anderen Datenbanken
- PL/pgSQL in der Open-Source-Datenbank PostgreSQL
- SQL-PL für Adabas
- Transact SQL (TSQL) ist die entsprechende Programmiersprache für RDBMS von Sybase und Microsoft
Siehe auch: Applikationsserver, Embedded SQL