Upload
bertram-bohlander
View
130
Download
1
Tags:
Embed Size (px)
Citation preview
Dr. Heidrun Bethge PL/SQL 1
PL/SQL
procedural language / structured query language
Dr. Heidrun Bethge PL/SQL 2
Agenda
• Was ist PL/SQL?• PL/SQL Blöcke• Datentypen• Kontrollstrukturen• Datenbankstrukturen / Cursor• Prozeduren und Funktionen• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 3
Literatur
• Oracle Database PL/SQL Language Reference
Oracle pdf Dokument
• auch Quelle für einige Beispiele
Dr. Heidrun Bethge PL/SQL 4
Was ist PL/SQL?• Oracles Programmiersprache für Stored
Procedures• Erweiterung des SQL-Potentials• Integration in Oracle-Datenbankserver• Beinhaltet die Funktionalität einer modernen
Programmiersprache: – Variablendeklaration– Schleifen und andere logische Strukturen– Fehlerbehandlung – Modularität– Kapselung– etc.
Dr. Heidrun Bethge PL/SQL 5
Vorteile von PL/SQL• PL/SQL ist sehr einfach zu lernen: große
Ähnlichkeit zu bekannten Programmiersprachen
• PL/SQL-Programm wird in der Oracle Datenbank gespeichert: Ein PL/SQL-Programm kann von jedem Datenbankbenutzer mit entsprechenden Rechten genutzt werden. Keine Verbreitung des Programms an Clients notwendig.
• PL/SQL insbesondere für Bearbeitung großer Datenmengen geeignet
Dr. Heidrun Bethge PL/SQL 6
Bessere Performanz• Ein PL/SQL-Programm kann mehrere SQL-
Befehle zu einer Einheit zusammenfassen. Dies ist insbesondere für Transaktionen von Vorteil.
• Die Befehle müssen nicht zum Datenbanksystem transferiert werden, da sie bereits dort gespeichert sind.
• So entsteht weniger Netzwerkverkehr und die Performanz von Anwendungen wird erhöht.
Dr. Heidrun Bethge PL/SQL 7
Enge Integration mit SQL• In PL/SQL direkt nutzbar: select, insert,
update, delete und Transaktionsverwaltung• Syntax von SQL-Befehlen ist in PL/SQL
identisch (Ausnahme: select)• Schreiben von SQL-Ergebnis in Variable:select <attribut> into <variable>
from <tabelle> where <bedingung>;• PL/SQL hat die gleichen Datentypen wie
Oracle-Tabellen -> keine Typkonvertierung notwendig. (Es gibt auch eigene PL/SQL-Typen.)
Dr. Heidrun Bethge PL/SQL 8
• Was ist PL/SQL?
• PL/SQL Blöcke• Datentypen• Kontrollstrukturen• Datenbankstrukturen / Cursor• Prozeduren und Funktionen• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 9
Blockstruktur von PL/SQL• Die Grundeinheit jedes PL/SQL-Programms ist der
Block. • Jedes PL/SQL-Programm besteht
– entweder aus einem einzelnen Block – oder aus mehreren aufeinander folgenden Blöcken– oder aus ineinander geschachtelten Blöcken
• [DECLARE-- Deklarationsteil]BEGIN-- Ausführungsteil[EXCEPTION-- Fehlerbehandlungsteil]END; (nicht das Semikolon am Ende vergessen!)/ (Ausführung des PL/SQL-Programms)
Dr. Heidrun Bethge PL/SQL 10
2 Typen von BlöckenEs gibt zwei Arten von Blöcken:• Anonyme Blöcke werden nicht gespeichert
und nur einmal ausgeführt. Sie sind eine Art komplexer SQL-Befehl.
• Benannte Blöcke sind mit Namen versehen und werden in der Datenbank dauerhaft gespeichert. Sie können immer wieder ausgeführt werden.
Typen benannter Blöcke sind:– Prozeduren– Funktionen– Trigger
Dr. Heidrun Bethge PL/SQL 11
anonymer Block: BeispieleBEGIN
DBMS_OUTPUT.PUT_LINE('Hallo Welt');END;_______________________________________DECLARE
heute DATE;BEGIN
heute:=SYSDATE;DBMS_OUTPUT.PUT_LINE('Heute: ' || heute);
END;
Dr. Heidrun Bethge PL/SQL 12
Ausführung von SQL-Befehlen in PL/SQLIn PL/SQL direkt nutzbar: select, insert, update, delete und Transaktionsverwaltung
SQL-Befehle werden in PL/SQL exakt so eingegeben, wie sie z.B. von SQL Plus aus verwendet werden.
Es ist kein Unterschied in der Verwendung von SQL innerhalb von PL/SQL oder außerhalb vorhanden.(außer SELECT .. INTO)
BEGIN INSERT INTO departments VALUES (400,'abc',NULL ,NULL); COMMIT;END;
Dr. Heidrun Bethge PL/SQL 13
Syntax – ein paar Besonderheiten
• unabhängig von Groß- und Kleinschreibung• jede Anweisung wird durch Semikolon
abgeschlossen:;• Anweisung kann über mehrere Zeilen gehen.• Verkettung von Zeichenketten: ||'Hans' || 'Mustermann'
• Kommentare:o /* */: Mehrzeilenkommentareo -- bis zum Ende der Zeile
• / (= run) am Ende von PL/SQL bewirkt die direkte Ausführung
Dr. Heidrun Bethge PL/SQL 14
• Was ist PL/SQL?• PL/SQL Blöcke
• Datentypen• Kontrollstrukturen• Datenbankstrukturen / Cursor• Prozeduren und Funktionen• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 15
Datentypen
• alle in Oracle-SQL verfügbaren Datentypen. Z.B. CHAR, DATE oder NUMBERVorteil: Datentypenkonvertierung zwischen SQL und Programmierung nicht erforderlich
• Spezielle PL/SQL-Datentypen. Z.B. BOOLEAN oder BINARY_INTEGER
• selbstdefinierte Unterdatentypen
Dr. Heidrun Bethge PL/SQL 16
PL/SQL-Datentypen
• Skalar: enthält einzelnen Wert. Z.B. BINARY_INTEGER, BOOLEAN
• Zusammengesetzt: Z.B. RECORD, TABLE, VARRAY
• LOB (Location of large Objects): z.B. Textblöcke oder Bilder: z.B. BFILE, BLOB
• Referenz: enthält Pointer. Z.B. REF CURSORS, OBJECT TYPES
Dr. Heidrun Bethge PL/SQL 17
Skalare Datentypen• Skalare SQL-Datentypen:
• VARCHAR2• CHAR• DATE• LONG• NUMBER
• Skalare nicht-SQL-Datentypen:• Integers: BINARY_INTEGER, INTEGER, INT,
SMALLINT• Decimal numbers: DEC, DECIMAL, DOUBLE,
PRECISION, NUMERIC, REAL• BOOLEAN. Werte: True, False, NULL
Dr. Heidrun Bethge PL/SQL 18
BINARY_INTEGER• Kein SQL-Datentyp, reines PL/SQL• Ist identisch mit PLS_INTEGER seit der
Version 10g release 1• Ganze Zahlen von -2147483647 bis
2147483647, d. h. 32 Bit• Verbraucht weniger Speicherplatz als
NUMBER• Schneller als NUMBER, da Hardware
Arithmetik angewendet wird• Für Integer innerhalb dieses Wertebereichs
sollte dieser Datentyp gewählt werden
Dr. Heidrun Bethge PL/SQL 19
Deklaration von Variablen und Konstanten
• Variablen und Konstanten werden im Deklarationsbereich des PL/SQL Blocks deklariert.
• Variablendeklaration ist zwingend erforderlich.• Jede Variable und Konstante hat einen spezifischen
Datentyp.• Variablen:
– birthday DATE; -- mit NULL initialisiert– birthday DATE := NULL; -- äquivalent zu obigem– emp_count SMALLINT;– i, j, k SMALLINT; -- nicht zulässig
• Konstanten:– credit_limit CONSTANT REAL := 5000.00;
Dr. Heidrun Bethge PL/SQL 20
Deklaration Besonderheiten• DEFAULT:
– blood_type CHAR DEFAULT ‘0‘;– blood_type CHAR := ‘0‘;– credit BINARY_INTEGER RANGE 1000..25000;
• NOT NULL:– acct_id INTEGER(4) NOT NULL := 9999;Initialisierungswert muss bei NOT NULL mit angegeben werden
Dr. Heidrun Bethge PL/SQL 21
%TYPE und %ROWTYPE• %TYPE für Felder oder Variablen
credit REAL(7, 2);debit credit%TYPE;v_email employees.email%TYPE;Datentyp einer Variable oder eines Felds einer Tabelle wird geerbt.
• %ROWTYPE für DatensätzeDECLARE
emprec employees%ROWTYPE;BEGIN
emprec.empid := 10; emprec.deptid := 20;
END;
Dr. Heidrun Bethge PL/SQL 22
Wertzuweisung1. Wertzuweisungszeichen: :=
– zahl := 1;– zeichenkette := 'Zeichen';– logisch := FALSE;– datum := '01-JAN-91';– tax := price * taxe_rate;– bonus := current_salary * 0.10;– amount := TO_NUMBER(SUBSTR(‘750
dollars‘, 1, 3);
2. Datenbankwerte in Variable über SELECT– SELECT sal * 0.10 INTO Bonus FROM
emp WHERE empno = emp_id;
Dr. Heidrun Bethge PL/SQL 23
• Was ist PL/SQL?• PL/SQL Blöcke• Datentypen
• Kontrollstrukturen• Datenbankstrukturen / Cursor• Prozeduren und Funktionen• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 24
Kontrollstrukturen
• Verzweigungen– IF – CASE
• Schleifen & Sprünge– LOOP – WHILE LOOP– FOR LOOP– GOTO
Dr. Heidrun Bethge PL/SQL 25
IF-Struktur
IF Bedingung1 THEN
Anweisungen1;
[ELSIF Bedingung2 THEN
Anweisungen2;]
[ELSE
Anweisungen3;]
END IF;
Dr. Heidrun Bethge PL/SQL 26
Beispiel IFDECLARE
current_day VARCHAR2(9):='Samstag';BEGINIF current_day='Samstag' THEN
DBMS_OUTPUT.PUT_LINE('Heute ist Samstag!');ELSIF current_day='Sonntag' THEN
DBMS_OUTPUT.PUT_LINE('Heute ist Sonntag!');ELSE
DBMS_OUTPUT.PUT_LINE('Leider kein Wochenende');
END IF;END;
Dr. Heidrun Bethge PL/SQL 27
CASECASE variableWHEN Wert1 THEN <Aktion1>;WHEN Wert2 THEN <Aktion2>;WHEN Wert3 THEN <Aktion3>;ELSE <Aktion4>;
END CASE;--CASE WHEN <Bedingung1> THEN <Aktion1>;WHEN <Bedingung2> THEN <Aktion2>;WHEN <Bedingung3> THEN <Aktion3>;ELSE <Aktion4>;
END CASE;
Dr. Heidrun Bethge PL/SQL 28
LOOPLOOP...IF <Bedingung> THEN
EXIT; END IF;
END LOOP;
oder:
LOOP...EXIT WHEN <Bedingung>
END LOOP;
Dr. Heidrun Bethge PL/SQL 29
Beispiel LOOPDECLAREzaehler BINARY_INTEGER:=1;
BEGINLOOP
DBMS_OUTPUT.PUT_LINE(zaehler);zaehler:=zaehler+1;
EXIT WHEN zaehler=11;END LOOP;
END;
Dr. Heidrun Bethge PL/SQL 30
WHILE LOOP
WHILE <Bedingung> LOOP...
END LOOP;
Die Schleife wird solange durchgeführt, wie die <Bedingung> wahr bleibt oder ein EXIT ausgeführt wird.
Dr. Heidrun Bethge PL/SQL 31
FOR-LOOPFOR zaehler IN [REVERSE] untere_grenze .. obere_grenze LOOP
...END LOOP;
• Zählervariable wird nicht deklariert• Zählervariable ist außerhalb des LOOP nicht
mehr gültig• Der Zählervariablen können keine Werte
zugewiesen werden• Keine Schrittweitenangabe
Dr. Heidrun Bethge PL/SQL 32
NULL• Das NULL-Statement führt keine Aktion durch und
gibt die Kontrolle an den nächsten Befehl weiter.• Es kann als Platzhalter eingesetzt werden.• Für Kontrollstrukturen ist es erforderlich, dass
ausführbare Befehle in die Strukturen eingetragen werden. Sind diese noch nicht programmiert, kann man stattdessen NULL schreiben.
IF <Bedingung> THENDBMS_OUTPUT.PUT_LINE('Wahr');
ELSENULL;
END IF;
Dr. Heidrun Bethge PL/SQL 33
• Was ist PL/SQL?• PL/SQL Blöcke• Datentypen• Kontrollstrukturen
• Datenbankstrukturen / Cursor
• Prozeduren und Funktionen• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 34
Cursor
Ein Cursor wird verwendet, um Daten zu
lesen und zu ändern
Es gibt zwei Arten Cursors:• Impliziter Cursor
Lesen von nur einem Datensatz• Expliziter Cursor
SELECT, INSERT, UPDATE, DELETE von keinem, einem oder mehreren Datensätzen
Dr. Heidrun Bethge PL/SQL 35
Beispiel für einen impliziten Cursor
DECLAREdepname VARCHAR2(100);
BEGINselect department_nameinto depnamefrom departmentswhere department_id=10;DBMS_OUTPUT.PUT_LINE('Die Abteilung 10 hat den Namen ' || depname);
END;
Die Ausgabe eines SELECT-Befehls wird an eine PL/SQL Variable mit implizitem Cursor übergeben
Dr. Heidrun Bethge PL/SQL 36
Fehler bei implizitem CursorDECLARE
depname varchar2(100);BEGIN
select department_nameinto depnamefrom departments;DBMS_OUTPUT.PUT_LINE('Die Abteilung hat
denNamen ' || depname);
END;
Die Abfrage darf nur einen Datensatz als Ergebnis liefern.
Dr. Heidrun Bethge PL/SQL 37
Expliziter Cursor
SELECT, INSERT, UPDATE, DELETE auf keinem, einem oder mehreren Datensätzen innerhalb von PL/SQL
Vorgehensweise:
1. Deklarieren des Cursors
2. Öffnen des Cursors
3. Datensätze einzeln lesen/bearbeiten
4. Schließen des Cursors
Dr. Heidrun Bethge PL/SQL 38
Beispiel für einen expliziten CursorDECLARE
CURSOR dep_cursor ISselect department_id, department_namefrom departments;
dep_row dep_cursor%ROWTYPE;BEGIN
OPEN dep_cursor;LOOP
FETCH dep_cursor INTO dep_row;EXIT WHEN dep_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE('Abteilung ' || dep_row.department_id || ' ' ||
dep_row.department_name);END LOOP;CLOSE dep_cursor;
END;
Dr. Heidrun Bethge PL/SQL 39
Syntax Cursor• CURSOR cursor_name IS select query;• DECLARE cursor_variable%ROWTYPE• OPEN cursor_name • Referenzierung von einzelnen Datensätzen
z.B. innerhalb einer Schleife• CLOSE cursor_name• EXIT WHEN cursor_name%NOTFOUND
ermittelt, ob der letzte Datensatz bereits erreicht wurde
Dr. Heidrun Bethge PL/SQL 40
Cursor-Attribute• Das DBMS richtet einen Kontextbereich für
jedes der folgenden SQL-Befehle ein: INSERT, UPDATE, DELETE, SELECT
• Der Kontextbereich enthält Informationen über die Anzahl der Ergebnisdatensätze etc.
• Cursor können diesen Kontextbereich über Cursor-Attribute ansprechen.
Dr. Heidrun Bethge PL/SQL 41
Cursor-Attribute Beispiele• SQL%FOUND liefert TRUE, falls beim letzten SQL-
Befehl mindestens ein Datensatz beteiligt war.Gegenteil: SQL%NOTFOUND
• Falls mit SELECT INTO kein Datensatz gefunden wird, ist ein %NOTFOUND nicht sinnvoll, da vorher bereits der Fehler NO_DATA_FOUND entsteht.
• SQL%ROWCOUNT liefert die Anzahl der beteiligten Datensätze des letzten SQL-Befehls
• SQL%ROWCOUNT bezieht sich immer auf den letzten SQL-Befehl. Dies wird nicht durch ROLLBACK beeinflusst.
• SQL%ISOPEN gibt an, ob ein Cursor geöffnet ist.
Dr. Heidrun Bethge PL/SQL 42
CURRVAL / NEXTVAL• CURRVAL: aktueller Wert einer SEQUENCE• NEXTVAL erhöht die SEQUENCE und gibt neuen
Wert zurück• Aufruf: sequence_name.CURRVAL• Inkrement mittels NEXTVAL lässt sich mittels
ROLLBACK nicht rückgängig machen
• CURRVAL und NEXTVAL können nur in der SELECT-Liste, in der VALUES-Klausel und in der SET-Klausel verwendet werden.
• ungültig: seq_value := employees_seq.NEXTVAL;SELECT ... WHERE employee_id = employees_seq.CURRVAL;
Dr. Heidrun Bethge PL/SQL 43
• Was ist PL/SQL?• PL/SQL Blöcke• Datentypen• Kontrollstrukturen• Datenbankstrukturen / Cursor
• Prozeduren und Funktionen
• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 44
Benannte Blöcke
• werden in der Datenbank gespeichert• können Parameter aufnehmen• können immer wieder aufgerufen werden,
auch von anderen PL/SQL-Programmen• Typen benannter Blöcke:
– Stored Procedures– Funktionen: geben EINEN Wert zurück, Aufruf
auch innerhalb eines SQL-Befehls möglich– Trigger: werden ereignisgesteuert aufgerufen bei
Ausführung von INSERT, UPDATE oder DELETE
Dr. Heidrun Bethge PL/SQL 45
Syntax Prozeduren/Funktionen
{FUNCTION|PROCEDURE} name [(parameter[, parameter, ...])] RETURN datatype IS[Deklarationen] --nicht DECLARE!!
BEGIN...
[EXCEPTION...]
END [name];
Dr. Heidrun Bethge PL/SQL 46
einfache FunktionCREATE OR REPLACE FUNCTION quadriere(zahl NUMBER)
RETURN NUMBER ISBEGIN
RETURN (zahl * zahl);END quadriere;
-- Aufruf der FunktionDECLARE
r NUMBER;BEGIN
r := quadriere(7);DBMS_OUTPUT.PUT_LINE ('Ergebnis: ' || TO_CHAR(r));
END;
Dr. Heidrun Bethge PL/SQL 47
Funktion eingebettet in Block
DECLARE FUNCTION quadriere1(zahl NUMBER)
RETURN NUMBER AS zahlquadrat NUMBER;BEGIN
zahlquadrat := zahl * zahl;RETURN zahlquadrat;
END;BEGINDBMS_OUTPUT.PUT_LINE(quadriere1(100));
END;
Dr. Heidrun Bethge PL/SQL 48
Ein- und Ausgabeparameter• IN (Standard) Eingabeparameter OUT AusgabeparameterIN OUT beides gleichzeitig
• IN Werte können nicht verändert werden• OUT und IN OUT nicht bei Funktionen• NOCOPY: OUT und IN OUT werden als reference
und nicht als value (Standard) übergeben• Beispiel:
DECLARETYPE Staff IS VARRAY(200) OF Employee;PROCEDURE reorganize (my_staff IN OUT NOCOPY Staff) IS ...
Dr. Heidrun Bethge PL/SQL 49
Default-Werte• Beispiel:
PROCEDURE create_dept (new_dname CHAR DEFAULT 'TEMP', new_loc CHAR DEFAULT 'TEMP') IS …
• Aufruf:– create_dept;– create_dept('MARKETING');– create_dept('MARKETING', 'NEW YORK');– create_dept('NEW YORK');– create_dept(, 'NEW YORK'); -- FEHLER!– create_dept(new_loc=>'NEW YORK');– außerhalb des Blocks bei stored procedure: call create_dept;
Dr. Heidrun Bethge PL/SQL 50
RETURN• RETURN beendet Prozedur/Funktion• auch für Schnellausstieg z.B. in Schleife
geeignet• mehrere RETURN möglich• Prozeduren:
– kein RETURN notwendig, aber möglich– keine Wertübergabe an RETURN
• Funktionen: – ein RETURN zwingend– es muss ausführbar sein– Wertübergabe zwingend
Dr. Heidrun Bethge PL/SQL 51
PL/SQL Funktionen in SQL• Die Funktion darf nicht INSERT, UPDATE oder DELETE
enthalten• Parameter und Rückgabewert müssen Datenbank-
Datentypen haben.• Keine OUT und IN OUT Parameter
CREATE OR REPLACE FUNCTION mwst ( p_salary IN employees.salary%TYPE) RETURN NUMBERASBEGIN RETURN (p_salary * 0.19);END mwst;--SELECT first_name||' '||last_name AS "Angestellter",
mwst(salary) AS "Steuern"FROM employees;
Dr. Heidrun Bethge PL/SQL 52
• Was ist PL/SQL?• PL/SQL Blöcke• Datentypen• Kontrollstrukturen• Datenbankstrukturen / Cursor• Prozeduren und Funktionen
• Fehlerbehandlung
Dr. Heidrun Bethge PL/SQL 53
Exceptions
• Fehlerbehandlung in PL/SQL• 2 Arten von Exceptions:
– vordefinierte Exceptions– benutzerdefinierte Exceptions
• beide werden syntaktisch gleich verwendet
• Kompilationsfehler sind keine Exceptions
Dr. Heidrun Bethge PL/SQL 54
Vordefinierte Exceptions• werden automatisch von PL/SQL ausgelöst:
– Fehler bei Befehlen auf Datenbankobjekten (SQL-Befehle)
– Programmierfehler (z.B. Division durch Null). • Exceptions haben vordefinierte Namen. Diese
können in PL/SQL verwendet werden. • Jede Exception hat einen Fehlercode, der aus den
Buchstaben ORA- und 5 Ziffern besteht. – no_data_found (ORA-00100): Eine SELECT-
Anfrage liefert eine leere Datenmenge– not_logged_on (ORA-01012):
Keine Verbindung zur Datenbank
Dr. Heidrun Bethge PL/SQL 55
Laufzeitfehler abfangenDECLARE
wert1 NUMBER := 10;wert2 NUMBER := 0;ergebnis NUMBER;
BEGIN-- Division durch Nullergebnis := wert1 / wert2;DBMS_OUTPUT.PUT_LINE('Ergebnis = ' || ergebnis);
EXCEPTION-- Nur einer der WHEN-Blöcke wird ausgeführtWHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('Es wurde durch Null geteilt.');
ergebnis := NULL;WHEN OTHERS THEN -- alle anderen Fehler
DBMS_OUTPUT.PUT_LINE('Ein anderer Fehler ist aufgetreten.');
ergebnis := NULL;END;
Dr. Heidrun Bethge PL/SQL 56
benutzerdefinierte ExceptionDECLARE
fehlerdef EXCEPTION;BEGIN
IF true THENRAISE fehlerdef;
END IF;EXCEPTION
WHEN fehlerdef THEN -- diese Exception DBMS_OUTPUT.PUT_LINE('fehlerdef
exception.');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('irgendein anderer Fehler');
END;