Einführung in PLSQL Prozedurale Erweiterung der Sprache SQL um Elemente wie Variablen, Schleifen, Bedingungen, Ausnahmebehandlung Code läuft innerhalb der Datenbank ab und ist deshalb sehr performant Zusätzlich große Anzahl an vordefinierten Bibliotheken (packages) verfügbar. Einsatzfelder: anonyme Blöcke Funktionen und Prozeduren, Methoden Trigger Andreas Schmidt Einführung in PLSQL 122
Struktur eines PLSQL Programms DECLARE BEGIN EXCEPTION END; -- Deklarationen -- eigentlicher -- Programmteil -- Fehlerbehandlung Deklarations und Ausnahmebehandlung sind optional beliebige Schachtelung der Blöcke ineinander möglich Deklarationsteil erlaubt Definition von Variablen, Konstanten, Cursorn, Funktionen und Prozeduren Variablen in dem Block gültig in dem sie deklariert wurden Kommentare: -- ich bin ein Kommentar * ich bin ein mehrzeiliger Kommentar * Andreas Schmidt Einführung in PLSQL 222
Datentypen in PLSQL BINARY_INTEGER Wertebereich -2147483647-2147483646 NUMBER [(Länge, Nachkommastelle)] 38 Stellen Genauigkeit CHAR [(Länge)] maximale Länge von 32767 Bytes VARCHAR2 [(Länge)] BOOLEAN DATE ROWID CURSOR Beispiel DECLARE owner char(10) := ich ; tablename char(30); bytes number(10) := 128000; today date not Null; ok boolean; pi constant number := 3.14159; zaehler number(5) := 1; CURSOR spieler_cursor is select * from spieler order by name; Andreas Schmidt Einführung in PLSQL 322
Datentypen in PLSQL Namen von Tabellen und Spalten sind als vordefinierte Variable vorhanden Attribut %TYPE liefert Datentyp einer anderen Variablen oder einer Tabellenspalte Attribut %ROWTYPE liefert Datentyp einer Tabellenzeile (Zugriff auf einzelne Felder über. - Notation) Beispiele: DECLARE stadt_name Stadt.name%type; nevada Wueste%rowtype; groesse Wueste.flaeche%type; hauptstadt stadt_name%type; BEGIN... groesse := nevada.flaeche; Tabelle Wueste Spalte name in Tabelle Stadt Andreas Schmidt Einführung in PLSQL 422
Bildschirmausgabe PLSQL Programme erzeugen normalerweise keine Bildschirmausgabe spezielles Paket zur Bildschirmausgabe verfügbar (DBMS_OUTPUT) Bildschirmausgabe mit Prozedur: DBMS_OUTPUT.PUT_LINE(<zeichenkette>); Bildschirmausgabe kann an und ausgeschaltet werden (Default OFF) Anweisung (SQLPLUS Sitzung) 1 : SET SERVEROUTPUT ON OFF [SIZE <numbytes>] Beispiel: SQL> set serveroutput on size 10000000 BEGIN DBMS_OUTPUT.PUT_LINE( Hallo designierter PLSQL Crack!! ); END; 1. SQLDeveloper: Menue >> Ansicht >> DBMS-Ausgabe (auf Pluszeichen drücken und passende Datenbankverbindung angeben) Andreas Schmidt Einführung in PLSQL 522
Kontrollstrukturen Zuweisungen Zuweisungsoperator := a := b * 120 + c; INTO Operator mit SELECT (nur, wenn genau ein Datensatz zurückgeliefert wird) declare anzahl_millionen_staedte number; select count(*) into anzahl_millionen_staedte from mondial.city where population > 1000000; dbms_output.put_line('es gibt ' anzahl_millionen_staedte ' Millionenstädte in der Mondial Datenbank'); FETCH... INTO (Mit Cursor) FETCH cur_station INTO s_id, x, y; Andreas Schmidt Einführung in PLSQL 622
Kontrollstrukturen (bedingte Anweisungen) bedingte Verzweigung IF <bedingung> THEN <anweisungen> END IF; Alternative IF <bedingung> THEN <anweisungen> ELSE <anweisungen> END IF; mehrere Alternativen IF <bedingung 1> THEN <anweisungen> ELSIF <bedingung 2> THEN <anweisungen> ELSIF <bedingung 3> THEN <anweisungen> ELSE <anweisungen> END IF; Andreas Schmidt Einführung in PLSQL 722
Kontrollstrukturen (Schleifen) LOOP... END LOOP a := 0; LOOP a := a + 1; if a = 50 then exit; end if; END LOOP; FOR <zaehlbereich> LOOP... END LOOP FOR i IN 1..50 LOOP insert into buch (kapitel, text) values (i, text(i)); END LOOP; Rückwärts FOR i in REVERSE 1..20 loop dbms_output.put_line(i); END LOOP; WHILE <bed> LOOP... END LOOP a := 0; WHILE a <= 50 LOOP b := b + a; a := a + 1; END LOOP; Andreas Schmidt Einführung in PLSQL 822
Ausnahmebehandlung Behandlung von Fehlern und Ausnahmesituationen durch Exceptionhandler Tritt Aufnahme auf, so wird normaler Ablauf abgebrochen und eine Fehlerbehandlung durchgeführt. Fehlerbehandlung erfolgt in EXCEPTION- Block. Ausnahmen können vordefiniert oder benutzerdefiniert sein. Beispiel (vordefinierte Ausnahme) DECLARE eine_stadt mondial.city%rowtype; stadt_name varchar2(20) := 'Karlsruhe'; -- alternativ: 'Metropolis' 'Springfield' BEGIN SELECT * INTO eine_stadt FROM mondial.city WHERE name = stadt_name; dbms_output.put_line(eine_stadt.name ' hat ' eine_stadt.population ' Einwohner'); EXCEPTION when no_data_found then dbms_output.put_line('stadt ' stadt_name ' gibt es nicht'); when too_many_rows then dbms_output.put_line('stadt ' stadt_name ' gibt es es mehrfach'); END; Andreas Schmidt Einführung in PLSQL 922
vordefinierte Ausnahmen Fakultät IWI Exception Oracle Error SQLCODE ACCESS_INTO_NULL ORA-06530-6530 COLLECTION_IS_NULL ORA-06531-6531 CURSOR_ALREADY_OPEN ORA-06511-6511 DUP_VAL_ON_INDEX ORA-00001-1 INVALID_CURSOR ORA-01001-1001 INVALID_NUMBER ORA-01722-1722 LOGIN_DENIED ORA-01017-1017 NO_DATA_FOUND ORA-01403 +100 NOT_LOGGED_ON ORA-01012-1012 PROGRAM_ERROR ORA-06501-6501 ROWTYPE_MISMATCH ORA-06504-6504 STORAGE_ERROR ORA-06500-6500 SUBSCRIPT_BEYOND_COUNT ORA-06533-6533 SUBSCRIPT_OUTSIDE_LIMIT ORA-06532-6532 TIMEOUT_ON_RESOURCE ORA-00051-51 TOO_MANY_ROWS ORA-01422-1422 VALUE_ERROR ORA-06502-6502 ZERO_DIVIDE ORA-01476-1476 Erläuterungen: http:fara.cs.uni-potsdam.de~uhlmann19ch09.html Andreas Schmidt Einführung in PLSQL 1022
Ausnahmebehandlung - eigene Ausnahmen DECLARE exep_moloch exception; eine_stadt mondial.city%rowtype; stadt_name varchar2(20) := 'San Francisco'; -- alternativ: 'Mexico City' BEGIN SELECT * INTO eine_stadt FROM mondial.city WHERE name = stadt_name; if eine_stadt.population > 5000000 then raise exep_moloch; end if; dbms_output.put_line(eine_stadt.name ' hat ' eine_stadt.population ' Einwohner'); EXCEPTION when exep_moloch then dbms_output.put_line('stadt ' eine_stadt.name ' ist zu groß für mich'); when others then dbms_output.put_line('fehler: ' sqlerrm); END; Andreas Schmidt Einführung in PLSQL 1122
CURSOR SQL Anweisung liefert i.a. eine Menge von Tupeln zurück Cursor zur sequentiellen Abarbeitung der Ergebnismenge Deklaration: DECLARE... cursor c1 is select * from land; Zugriff auf den Inhalt mittels OPEN FETCH CLOSE Status des Cursors %ISOPEN %FOUND %NOTFOUND %ROWCOUNT Andreas Schmidt Einführung in PLSQL 1222
CURSOR Programmcode: declare cursor cur_french_city is select * from mondial.city c where c.country = 'F' and c.population is not null order by c.population desc; a_city mondial.city%rowtype; OPEN cur_french_city; FETCH cur_french_city INTO a_city; WHILE cur_french_city%found LOOP dbms_output.put_line('datensatz: ' cur_french_city%rowcount ' Stadt: ' a_city.name ' (' a_city.population ')'); FETCH cur_french_city INTO a_city; END LOOP; CLOSE cur_french_city; Ausgabe: Datensatz: 1 Stadt: Paris (2152423) Datensatz: 2 Stadt: Marseille (800550) Datensatz: 3 Stadt: Lyon (415487) Datensatz: 4 Stadt: Toulouse (358688) Datensatz: 5 Stadt: Nice (342439) Datensatz: 6 Stadt: Strasbourg (252338) Datensatz: 7 Stadt: Nantes (244995) Datensatz: 8 Stadt: Bordeaux (210336) Datensatz: 9 Stadt: Montpellier (207996) Datensatz: 10 Stadt: Saint Etienne (199396) Datensatz: 11 Stadt: Rennes (197536) Datensatz: 12 Stadt: Le Havre (195854) Datensatz: 13 Stadt: Reims (180620)... Andreas Schmidt Einführung in PLSQL 1322
CURSOR Kurzform (ohne OPEN, FETCH, CLOSE) declare cursor cur_french_city is select * from mondial.city c where c.country = 'F' and c.population is not null order by c.population desc; FOR a_city in cur_french_city LOOP dbms_output.put_line('datensatz: ' cur_french_city%rowcount ' Stadt: ' a_city.name ' (' a_city.population ')'); END LOOP; Andreas Schmidt Einführung in PLSQL 1422
CURSOR ohne explizite Cursorvariable: FOR a_city in (select * from mondial.city c where c.country = 'F' and c.population is not null order by c.population desc) LOOP dbms_output.put_line('datensatz: ' cur_french_city%rowcount ' Stadt: ' a_city.name ' (' a_city.population ')'); END LOOP; Andreas Schmidt Einführung in PLSQL 1522
CURSOR mit Parametern in where Klausel können Auswahlkriterien angegeben werden Werte können beim öffnen des Cursors mit übergeben werden z.b.: OPEN cur_city('d'); Ideal bei geschachtelten Tabellen Beispiel declare cursor cur_city(country_id char) is select * from mondial.city c where c.country = country_id and c.population is not null order by c.population desc; FOR a_city in cur_city('d') LOOP dbms_output.put_line('datensatz: ' cur_city%rowcount ' Stadt: ' a_city.name ' (' a_city.population ')'); END LOOP; END; Andreas Schmidt Einführung in PLSQL 1622
Funktionen, Prozeduren Definition von Prozeduren und Funktionen innerhalb eines PLSQL Blocks Integration von Prozeduren und Funktionen als Datenbankobjekte Übergabeparameter können als IN, OUT und IN OUT deklariert werden. Übergabeparameter können einen Standardwert besitzen Parametertypen ohne Größenangabe Beispiel Prozedurkopf. procedure spielzug(spieler_id in integer, ziel_station in integer, ticket in varchar default 'Taxi') is -- Implementierung; Prozedur-Funktionsrumpf entspricht einem PLSQL-Block ohne Schlüsselwort DECLARE Andreas Schmidt Einführung in PLSQL 1722
Funktionen, Prozeduren Funktionsdeklaration entspricht Prozedurdeklaration mit Unterschied, dass Ergebnistyp der Funktion angegeben wird. Rückgabe der berechneten Ergebnisse mittels Schlüsselwort RETURN. Beispiel: function minimum(a in number, b in number) return number is if a < b then return a; else return b; end if; Aufruf: dbms_output.put_line('min. von 12 und -7:' minimum(12,-7)); Andreas Schmidt Einführung in PLSQL 1822
Beispiel declare m number; function minimum(a in number, b in number) return number is if a < b then return a; else return b; end if; procedure maximum(a in number, b in number, res out number) is if a > b then res := a; else res := b; end if; dbms_output.put_line('minimum von 12 und -7: ' minimum(12,-7)); maximum(2,-4, m); dbms_output.put_line('maximum von 2 und -4: ' m); Andreas Schmidt Einführung in PLSQL 1922
ProzedurenFunktionen als Datenbankobjekte Abspeichern von FunktionenProzeduren als benannte Datenbankobjekte FunktionenProzeduren können von SQLPLUS TOAD..., PLSQL Code oder auch über OCI, ODBC, JDBC aus aufgerufen werden. Aufruf (Definition rechte Seite); SQL> dbms_output.put_line('fak(5)=' fak(5)); Beispiel einer Funktionsdeklaration: create or replace function fak(z in integer) return number is f number := 1; for i in 2..z loop f := f * i; end loop; return f; alternative kurzform (1-Zeiler): SQL> exec dbms_output.put_line('fak(5)=' fak(5)); Andreas Schmidt Einführung in PLSQL 2022
ProzedurenFunktionen als Datenbankobjekte Fehler bei Definition einer ProzedurFunktion können mit dem SQLPLUS Kommando show errors angezeigt werden Aufruf von PLSQL Funktionen auch innerhalb von SQL Statements Funktionen können mit Ausführungsrechten versehen werden (Kapselung) FunktionenProzeduren können als EXTERN deklariert sein (Implementierung in Java, C++,...) Tabelle user_source enthält alll benutzerdefinierten Datenbankobjekte SQL> desc user_source Name Typ ------------------------- NAME VARCHAR2(30) TYPE VARCHAR2(12) LINE NUMBER TEXT VARCHAR2(4000) select text from user_source where name='fak' and type='function' order by line; Andreas Schmidt Einführung in PLSQL 2122
Literaturweitere Informationsquellen Einführung in PLSQL: http:www.a-wilde.dehpstudiumdbplsql1.htm Oracle PLSQL Programmierung, 2. Auflage; Steven Feuerstein & Bill Pribyl; Deutsche Übersetzung von Dorothea Reder; O Reilly; 2. Auflage April 2003; ISBN 3-89721-184-X; Seiten 1084; 64.00 Oracle PLSQL - kurz & gut, 2. Auflage; Steven Feuerstein, Bill Pribyl & Chip Dawes; Deutsche Übersetzung von Wolfgang Gabriel & Lars Schulten; 2. Auflage September 2003; ISBN 3-89721-260-9; Seiten 134; 8.90 Overview of PLSQL (Oracle Seiten): http:otn.oracle.comtechpl_sqlindex.html Andreas Schmidt Einführung in PLSQL 2222