Prozeduren und Trigger in Datenbanken

Größe: px
Ab Seite anzeigen:

Download "Prozeduren und Trigger in Datenbanken"

Transkript

1 Prozeduren und Trigger in Datenbanken Holger Jakobs Prozeduren (stored procedures) bringen bei Datenbanken prinzipiell dasselbe, was sie bei gewöhnlichen Programmiersprachen auch bringen: nämlich eine einfache Möglichkeit, mehrere Anweisungen durch eine einzige Anweisung auszuführen. Dabei ist auch eine Parametrisierung möglich. Die Prozeduren werden in der Datenbank selbst hinterlegt und laufen demnach auch im Datenbanksystem, d. h. im Backend auf dem Datenbankserver. Die Sprache(n), in denen die Prozeduren geschrieben werden können, variieren je nach Datenbanksystem. Allgemein ist jedoch eine prozedurale Variante von SQL verfügbar, oft die klassische Programmiersprache C, ggf. noch weitere, z. B. Java oder Scriptsprachen. Trigger (Auslöser) werden durch bestimmte Ereignisse abgefeuert, d. h. im Gegensatz zu einer Prozedur nicht explizit, sondern implizit, z. B. durch Einfügen, Ändern oder Löschen von Daten in der Datenbank. Einem Trigger ist entweder ein Stück Code fest zugeordnet, oder aber der Aufruf einer Prozedur. Zweck eines Triggers ist in den meisten Fällen die Sicherstellung der Datenbank-Konsistenz, wenn dies mit Hilfe der üblichen Constraints (primary key, foreign key und check) nicht möglich ist, weil die Bedingung hierfür zu komplex ist. Mit Prozeduren und Triggern kann auch die Anwendungsprogrammierung vereinfacht werden, wenn Teile der Verarbeitungslogik in die Datenbank verlagert werden. Das hat auch den Vorteil, dass dieser Teil der Verarbeitungslogik unabhängig vom verwendeten Frontend wird. Die Quelltexte aus diesem Dokument stehen online 1 zur Verfügung. 1) 1

2 Inhaltsverzeichnis 1 Prozeduren und Funktionen Oracle Syntax von PL/SQL Variablen in PL/SQL Cursor in PL/SQL Parametrisierte Cursor in PL/SQL Ablaufsteuerung in PL/SQL Weitere Möglichkeiten in PL/SQL Einschränkungen bei Funktionen Weitere Beispiele zu Oracle-Prozeduren und -Funktionen Aufruf von Prozeduren aus Programmen Prozeduren und Funktionen im Vergleich Hinweise zur Fehlersuche PostgreSQL Syntax von PL/pgSQL Variablen in PL/pgSQL Aufruf von Funktionen in PL/pgSQL Dynamisches Ausführen von Code in PL/pgSQL Ablaufsteuerung in PL/pgSQL Cursor in PL/pgSQL Fehlerbehandlung in PL/pgSQL Triggerfunktionen Trigger Oracle Erzeugen von Triggern in Oracle Zugriff auf Daten in Triggern bei Oracle instead of-trigger Zugriff auf Daten der aktuellen Tabelle (mutating table) PostgreSQL Erzeugen von Triggern in PostgreSQL Besonderheiten der Triggerfunktionen in PostgreSQL Zugriff auf Daten der aktuellen Tabelle

3 1 Prozeduren und Funktionen 1.1 Prozeduren und Funktionen bei Oracle Neben den benutzerdefinierten Funktionen, die in diesem Dokument erläutert werden, gibt es eine ganze Reihe vordefinierter Funktionen, u. a. zur Konversion zwischen Datentypen, für Berechnungen, zur Zeichenkettenbearbeitung usw. Diese sind in der Originaldokumentation 1 von Oracle recht gut erläutert und werden daher in diesem Dokument ohne weitere Erklärung gelegentlich benutzt. Bei Oracle wird zwischen Prozeduren und Funktionen unterschieden. Um Funktionen oder Prozeduren erzeugen zu dürfen, muss man das CREATE PROCEDURE system privilege haben. Um Funktionen oder Prozeduren innerhalb von fremden Schemas zu erzeugen, benötigt man das CREATE ANY PROCEDURE system privilege; um sie zu ersetzen, benötigt man ALTER ANY PROCEDURE system privilege. Zum Ausführen werden auch entsprechende execute-rechte benötigt Syntax von PL/SQL Die Syntax zum Erzeugen von Prozeduren und von Funktion ist sehr ähnlich: CREATE [ OR REPLACE ] FUNCTION [ schema. ] function_name [ ( argument [ IN OUT IN OUT ] [ NOCOPY ] datatype [,... ] ) ] RETURN datatype AS plsql_function_body ; CREATE [ OR REPLACE ] PROCEDURE [ schema. ] procedure_name [ ( argument [ IN OUT IN OUT ] [ NOCOPY ] datatype [,... ] ) ] AS plsql_sql_procedure_body ; Hierbei stehen plsql_function_body und plsql_procedure_body für den Rumpf der Funktion bzw. Prozedur. Statt dieses Rumpfs kann auch die Deklaration einer C- oder Java-Funktion verwendet werden dies wird hier aber nicht weiter erläutert. Es kann zusätzlich noch angegeben werden, mit wessen Rechten die Funktion bzw. Prozedur laufen soll auch auf diese Besonderheit wird hier nicht weiter eingegangen. Wenn eine Prozedur oder Funktion keine Argumente hat, wird bei der Definition auch keine runde Klammer angegeben. Bei Funktionen werden die runden Klammern allerdings beim Aufruf immer angegeben, auch wenn sie ggf. leer sind. 1) 3

4 1.1. ORACLE KAPITEL 1. PROZEDUREN UND FUNKTIONEN Die Oracle-Beispiele in diesem Dokument sind in PL/SQL geschrieben, einer prozeduralen Variante von SQL, in der man neben den Abfrage- und Cursor-Anweisungen auch Variablen deklarieren und Schleifen benutzen kann. Es gibt auch eine Ausnahmebehandlung und die Möglichkeit, Fehler an die rufende Einheit zurückzuliefern. In PL/SQL sind die üblichen Datenmanipulationskommandos erlaubt. Die PL/SQL-Programmeinheiten können verwendet werden in anonymen Blöcken, Prozeduren, Funktionen und im Anweisungsteil von Triggern (siehe Abschnitt 2.1 auf Seite 22) Variablen in PL/SQL Variablen werden in PL/SQL vor dem BEGIN des Anweisungsteils deklariert. Sie können jeden SQL-Datentyp haben, den Oracle kennt, oder auch den PL/SQL-spezifischen Datentyp BOOLEAN (der eigentlich auch zum SQL-Standard gehört, aber bei Oracle noch nicht enthalten ist). Bei der Variablendeklaration gibt man den Typen und ggf. auch die Größe an. Beispiele: spielernr INTEGER; betrag DECIMAL(10,2); laenge REAL; n DATE; genehmigt BOOLEAN; Statt der hier gezeigten SQL-Standarddatentypen kann man auch die Oracle-spezifischen Typen verwenden, d. h. bei Zahlen immer NUMBER usw. siehe Dokument SQL-Datentypen und ihre Besonderheiten 2. Bei der Angabe des Typs für formale Parameter wird nur der Datentyp selbst verwendet, aber keine Angabe der Größe, also nur DECIMAL und nicht DECIMAL(10,2). Darüber hinaus besteht die Möglichkeit, zusammengesetzte Datentypen zu verwenden, d. h. Tabellen, Arrays, Records. Die Zuweisung von Werten zu Variablen geht über den Operator :=, also spielernr := 44;. Auch die üblichen arithmetischen Berechnungen sind ohne weiteres erlaubt, wobei sowohl Literale als auch Variablen und Konstanten in den Ausdrücken verwendet werden können. Den Wert einer Variablen kann man auch über die INTO-Klausel eines SELECT-Statements verändern oder über den Aufruf einer Prozedur, die einen Ausgabeparameter hat. Wenn man den Typ decimal bei Ausgabeparametern verwendet, kann es passieren, dass der Nachkommateil abgeschnitten wird deshalb hier besser den Oracle-spezifischen Typ number verwenden. laenge := 2.54; SELECT max(betrag) INTO betrag FROM strafen; 2) 4

5 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.1. ORACLE Konstanten werden wie Variablen deklariert, aber mit dem Zusatz CONSTANT und einem Wert versehen. grenze CONSTANT DECIMAL(10,2) := ; Statt einen Datentyp direkt anzugeben, kann man Variablen auch genauso deklarieren wie bereits bestehende Variablen oder Tabellenspalten. Hierzu schreibt man an Stelle des Typen den Namen der Variablen oder Tabellenspalte, gefolgt von %TYPE. Eine Variable kann auch eine ganze Tabellenzeile enthalten. Sie wird als eine Variable vom selben Typ wie eine Tabelle deklariert mit strafensatz strafen%rowtype. Um auf einzelne Spalten zuzugreifen, wird die Punkt-Notation verwendet: nr := strafensatz. spielnr; Bei FETCH-Anweisungen wird eine Zeile in den Strafensatz geladen: FETCH c1 INTO strafensatz; (wobei c1 ein Cursor sein muss, der einen passenden Satz liefert) Cursor in PL/SQL Innerhalb von PL/SQL kann man mit Cursorn ähnlich arbeiten wie bei Embedded SQL in C und bei JDBC. In diesem Zusammenhang werden dann auch die Anweisungen OPEN, FETCH und CLOSE benutzt. Cursor werden ähnlich wie Variablen deklariert. Bei der Deklaration kann bereits eine Abfrage festgelegt werden, aber generischen Cursorn wird die Abfrage erst beim Öffnen zugewiesen. create or replace procedure curstest1 as cursor curs1 is select spielname, ort from sp_spieler where ort='bonn'; name varchar(20); stadt varchar(20); open curs1; fetch curs1 into name, stadt; if curs1%found then insert into tabelle1 values (name, stadt); end if; close curs1; Diese kleine Prozedur enthält einen expliziten Cursor mit einer fest vorgegebenen Abfrage. Der Cursor wird geöffnet. Nach einem fetch-versuch wird geprüft, ob es erfolgreich war. Wenn ja, werden Daten in eine andere Tabelle eingefügt. Am Ende wird der Cursor geschlossen. Tabelle 1.1 auf der nächsten Seite zeigt, welche Informationen über einen Cursor abgerufen werden können. Es wird der Cursorname, direkt gefolgt von einem Prozentzeichen und 5

6 1.1. ORACLE KAPITEL 1. PROZEDUREN UND FUNKTIONEN Tabelle 1.1: Informationsmöglichkeit über Cursor Zeitpunkt %notfound %found %rowcount %isopen vor open Fehler Fehler Fehler false direkt nach null null 0 true open nach erfolgreichem false null Zahl 1 true fetch nach erfolglosem true false Zahl 0 true fetch nach close Fehler Fehler Fehler false einer der genannten Zeichenketten geschrieben, siehe Beispiel im Code oben. In den mit Fehler markierten Situationen wird die Exception invalid_cursor geworfen (Exceptions siehe Tabelle 1.2 auf Seite 9). create or replace procedure curstest2 as type cursortyp1 is ref cursor; curs1 cursortyp1; name varchar(20); stadt varchar(20); open curs1 for select spielname, ort from sp_spieler where ort='duesseldorf'; fetch curs1 into name, stadt; if curs1%found then insert into tabelle1 values (name, stadt); end if; close curs1; Dieses Beispiel ist von der Funktion her wie das obige, nur dass der Cursor hier als Variable deklariert wurde. Hierzu ist es notwendig, zunächst einen Datentypen zu deklarieren. Beim Öffnen der Cursor-Variablen wird dann die Abfrage mitgegeben. Auf diese Weise kann man dieselbe Cursor-Variable für verschiedene Abfragen benutzen. Eine Alternative zu expliziten open-, fetch- und close-anweisungen ist die Verwendung von LOOP. In einem Beispiel sollen hier Angaben aus der Strafentabelle des Sportvereins verarbeitet werden. Ziel ist es, in eine neue Tabelle die Strafen eines Spielers einzutragen, wobei aber nicht die Einzelbeträge, sondern die insgesamt aufgelaufenen Beträge enthalten sind. Dies geschieht innerhalb einer Schleife in der Prozedur. create table str ( 6

7 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.1. ORACLE znr integer primary key, spnr integer not null, datum date not null, sum decimal(10,2) not null ); create procedure p1 (spnr integer) as cursor c1 is select zahlnr, spielnr, datum, betrag from sp_strafen where spielnr = spnr order by datum; betragsum decimal(10,2); betragsum := 0; delete from str; for satz in c1 loop betragsum := betragsum + satz.betrag; insert into str values (satz.zahlnr, satz.spielnr, satz.datum, betragsum); end loop; Nach dem Ausführen der Prozedur mit dem Parameter 44 sind alle Strafen des Spielers 44 in der Tabelle str enthalten. Die Ausführung geschieht interaktiv mit einem anonymen Block: p1 (44); Parametrisierte Cursor in PL/SQL Cursor können auch parametrisiert sein, so dass Werte z. B. in where-bedingungen zur Laufzeit ausgetauscht werden können. create or replace procedure curstest3 (spielort in varchar) as cursor curs1 (wohnort in varchar) is select spielname, ort from sp_spieler where ort = wohnort; name varchar(20); stadt varchar(20); open curs1 (spielort); fetch curs1 into name, stadt; if curs1%found then 7

8 1.1. ORACLE KAPITEL 1. PROZEDUREN UND FUNKTIONEN insert into tabelle1 values (name, stadt); end if; close curs1; In diesem Beispiel wird dem Prozedurparameter spielort ein Wert übergeben, der wiederum an den parametrisierten Cursor weitergegeben wird. Der Rest funktioniert wie gehabt Ablaufsteuerung in PL/SQL Als prozedurale Variante von SQL gibt es in PL/SQL alle üblichen Strukturen zur Ablaufsteuerung, d. h. Verzweigungen und Schleifen. Verzweigung und Schleifen if bedingung then Anweisungen elsif bedingung then Anweisungen else Anweisungen end if; loop Anweisungen exit when bedingung Anweisungen end loop; for i in [ reverse ] klein..gross loop Anweisungen end loop; while gehalt < 1000 loop Anweisungen end loop; Die numerische for-schleife kann vorwärts oder rückwärts ablaufen, aber die untere Grenze steht immer zuerst, auch wenn reverse angegeben ist. Die Schleifen können durch die Anweisung exit verlassen werden. Dies kann in einem if-konstrukt geschehen oder mittels exit when bedingung. Die Existenz des unstrukturierten goto soll hier verschwiegen werden. Hilfreich beim Programmieren ist allerdings die Ausnahmebehandlung. Hierzu schreibt man eine exception-klausel am Ende des end-blocks. Ausnahmen können vom Datenbanksystem 8

9 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.1. ORACLE Tabelle 1.2: Einige der vordefinierten Ausnahmen bei Oracle Exception Code Erläuterung DUP_VAL_ON_INDEX ORA uneindeutiger Wert in einem eindeutigen Index (oder Primärschlüssel) TIMEOUT_ON_RESOURCE ORA Zeitüberschreitung beim Warten, evtl. Deadlock INVALID_CURSOR ORA ungültiger Cursor, Definition vergessen? NOT_LOGGED_ON ORA Anmeldung vergessen? LOGIN_DENIED ORA Einloggen fehlgeschlagen, Kennwort falsch? NO_DATA_FOUND ORA keine Daten gefunden (wie sqlcode=100) ZERO_DIVIDE ORA Division durch Null ROWTYPE_MISMATCH ORA Datentyp des Abfrageergebnisses und der Hostvariablen stimmen nicht überein. CURSOR_ALREADY_OPEN ORA Versuch, einen bereits geöffneten Cursor zu öffnen OTHERS alle anderen Fehler; kann benutzt werden mit einer WHEN OTHERS-Klausel selbst kommen, z. B. die Ausnahme no_data_found oder aber mit Hilfe einer raise- Anweisung vom selbst geschriebenen Code generiert werden. Mit Hilfe der Anweisung raise_application_error (nr, text ); erzeugt man einen Anwendungsfehler, der an das aufrufende Programm weitergegeben wird, also nicht innerhalb der Prozedur selbst behandelt wird. Die angegebene nr muss sich im Bereich bis bewegen und wird als sqlcode zurückgeliefert, der angegebene text in der SQL-Message. Exception Handling create function f2 (spnr in integer) return varchar as titel varchar(5); fehlt exception; select titel into titel from spieler where spielnr = spnr; if titel is null then raise fehlt; else return titel; end if; exception when fehlt then return '(keiner)'; 9

10 1.1. ORACLE KAPITEL 1. PROZEDUREN UND FUNKTIONEN when no_data_found then raise_application_error(-20100, 'Spieler nicht da'); when others then raise_application_error(-20123, SQLERRM); Fängt man die erzeugte Ausnahme nicht ab, so wird ein Fehler geliefert (unhandled userdefined exception). Neben den benutzerdefinierten Ausnahmen gibt es auch eine ganze Reihe von Oracle vordefinierte Exceptions, siehe Tabelle 1.2 auf der vorherigen Seite. Diese führen nicht zu einem Anwendungsfehler, falls man sie nicht abfängt. Im obigen Beispiel wird die Ausnahme no_data_found geworfen, wenn es den Spieler mit der Nummer spnr nicht gibt. Wir erzeugen dann einen Anwendungsfehler, der auch beim Aufrufen über ein interaktives Frontend (z. B. TOra) auftaucht. Beim Auftreten unerwarteter Exceptions wird die Original-Oracle-Meldung (sqlerrm) mit der Fehlernummer geliefert. sqlcode und sqlerrm stehen immer als Variablen zur Verfügung. Innerhalb einer Prozedur oder Funktion kann es auch mehrere Blöcke geben, in denen Exceptions abgefangen werden. Hier ein kleines Beispiel einer Prozedur, die das Datum des letzten Kundenkontakts in der Tabelle kunde pflegen soll. Ist es der erste Kontakt im aktuellen Kalenderjahr, so wird das bislang letzte Kontaktdatum in einer History-Tabelle eingetragen, in der der jeweils letzte Kontakt eines Kunden für die vergangenen Jahre steht. create or replace procedure p2 (kundennr in integer) as datum date; letztesjahr integer; select letzterkontakt into datum from kunde where kdnr = kundennr; if datum < trunc(sysdate, 'YEAR') then select to_number(to_char(sysdate, 'YYYY')) - 1 into letztesjahr from dual; insert into Kontakt values (kundennr, letztesjahr, datum); end if; exception when no_data_found then raise_application_error(-20100, 'Kunde ' kundennr ' nicht da'); update kunde set letzterkontakt = trunc(sysdate) where kdnr = kundennr; Leider gibt es bei Oracle keine direkte Möglichkeit, nach einer Datenmanipulationsanweisung festzustellen, ob und wenn ja wie viele Tupel von ihr betroffen wurden. Ein SELECT 10

11 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.1. ORACLE auf dieselbe Tabelle mit derselben where-klausel muss als umständliches Vehikel dafür angesehen werden Weitere Möglichkeiten in PL/SQL Auf die weiteren Möglichkeiten von PL/SQL, d. h. Object Types, tabellenwertige Variablen und Collections geht dieses Dokument nicht ein Einschränkungen bei Funktionen Benutzerdefinierte Funktionen können nicht verwendet werden ˆ in einem check Constraint ˆ in default-klauseln bei der Tabellendefinition Wenn Funktionen innerhalb einer Abfrage oder einer Datenmanipulationsanweisung verwendet werden, dürfen sie ˆ keine OUT- oder IN OUT-Parameter haben. ˆ kein COMMIT oder ROLLBACK ausführen, auch nicht implizit durch Datendefinitionskommandos. ˆ keine Daten schreiben, wenn sie von einer Abfrage aufgerufen werden. Wohl aber geht das, wenn sie von einer Datenmanipulationsanweisung aus aufgerufen werden. Verwenden Sie insert into x values(funk1(100)); an Stelle von select funk1(100) from dual;, damit die Funktion funk1() innerhalb einer DML-Anweisung und nicht innerhalb einer Abfrage aufgerufen wird. x ist eine Testtabelle, die den Rückgabewert von funk1() aufnimmt, so dass Sie ihn anschließend sichtbar machen können. ˆ nicht auf dieselbe Tabelle schreiben wie die Datenmanipulationsanweisung, die sie aufruft Weitere Beispiele zu Oracle-Prozeduren und -Funktionen create function sum_strafen (spielernr in integer) return decimal as summe decimal(10,2); select sum(betrag) into summe from strafen where spielnr = spielernr; return (summe); 11

12 1.1. ORACLE KAPITEL 1. PROZEDUREN UND FUNKTIONEN select sum_strafen(44) from dual; -- Testaufruf create procedure strafen_betrag (znr in integer, neubetrag in decimal) as update strafen set betrag = neubetrag where zahlnr = znr; -- anonymer Block strafen_betrag (1, 35.00); -- Testaufruf Die select-abfrage nach dem Wert der Funktion sum_strafen bezieht sich auf die Pseudotabelle dual, weil bei Oracle eine Abfrage unbedingt eine from-klausel mit Tabelle haben muss (vgl. select sysdate from dual;). Die Prozedur strafen_betrag wird nach ihrer Definition in einem anonymen end-block ausgeführt. Ein solcher Block ist für den Aufruf notwendig; lediglich bei Verwendung des SQL*Plus-Frontends von Oracle kann man statt dessen auch execute strafen_ betrag (1, 35.00) schreiben Aufruf von Prozeduren aus Programmen Embedded SQL in C Innerhalb von Embedded SQL schreibt man den Aufruf einer Prozedur wie folgt. zahlnr und betrag müssen hier als Hostvariablen vereinbart sein, die innerhalb von SQL-Statements mit einem führenden Doppelpunkt angesprochen werden. exec sql execute call strafen_betrag (:zahlnr, :betrag); Die Prozedur übernimmt die Parameter in der angegebenen Reihenfolge wie bei anderen Programmiersprachen auch. Allerdings kann man von der Reihenfolge abweichen, wenn man die Parameter benennt, hier beispielsweise so: exec sql execute call strafen_betrag (neubetrag=>35.00, znr=>1); Natürlich muss wie immer eine Fehlerbehandlung durchgeführt werden, die hier aber nicht gezeigt ist. 12

13 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.1. ORACLE Java mit JDBC In Java-JDBC-Programmen werden Prozeduren so aufgerufen, wobei conn die bestehende Verbindung zur Datenbank ist: CallableStatement callstmt = conn.preparecall ("{call strafen_betrag (?,?)}"); callstmt.setint ("znr", 1); callstmt.setdouble ("neubetrag", 35.00); callstmt.execute(); Statt der geschweiften Klammern können auch und end verwendet werden, was dann so aussieht: conn.preparecall (" call strafen_betrag (?,?); "); In jedem Fall müssen die Statements als Variable vom Typ CallableStatement deklariert und vorbereitet (prepared) werden. Danach werden die einzelnen Parameter mit Werten versehen und dann das Statement ausgeführt. Natürlich muss wie immer eine Fehlerbehandlung durchgeführt werden, die hier aber nicht gezeigt ist Prozeduren und Funktionen im Vergleich Funktionen werden immer als Bestandteil eines Ausdrucks aufgerufen, während Prozeduraufrufe eigenständige Anweisungen sind. Daher können Prozeduren nicht direkt aus SQL- Anweisungen aufgerufen werden. Allerdings können Funktionen, die Bestandteil eines Ausdrucks sind, ihrerseits wiederum Prozeduren aufrufen. Bei Funktionen werden hinter dem Namen immer runde Klammern verwendet. Bei parameterlosen Funktionen sind sie leer, ansonsten stehen dort die Argumente in derselben Reihenfolge wie in der Funktionsdefinition. Benannte Argumente wie bei Prozeduren sind nicht möglich Hinweise zur Fehlersuche Wenn man Funktionen oder Prozeduren eingerichtet hat, werden manche Fehler sofort gemeldet, manche aber auch nicht oder zum Ausführungszeitpunkt. Falls keine klare Fehlermeldung vom Frontend angezeigt wird, kann man evtl. mit select * from user_errors; ausführlichere Information über den Fehler bekommen. Dort werden auch Zeilen- und Spaltennummer aufgeführt, wo der Fehler aufgetreten ist. Diese Art der Fehlermeldung ist vom Frontend unabhängig, weil sie komplett auf dem Server verwaltet wird. Eine weitere Möglichkeit, Werte sichtbar zu machen, besteht in der Verwendung von dbms_output.put_ line(...), wobei statt der Punkte Zeichenketten oder Variableninhalte ausgegeben werden können. Um die Ausgabe sichtbar zu machen, muss in SQLplus set serveroutput on; eingegeben werden. In TOra wird unter Tools der SQL Output geöffnet. Um in TOra Ausgabeparameter von Prozeduren 13

14 1.2. POSTGRESQL KAPITEL 1. PROZEDUREN UND FUNKTIONEN verwenden zu können, müssen diese deklariert werden. Die Deklaration und der anonyme Block werden gemeinsam markiert und dann durch Klicken auf den grünen Pfeil ausgeführt siehe nebenstehende Abbildung. Das SQL-Output-Fenster in TOra muss manuell aktualisiert werden; ansonsten erscheinen die Ausgaben verzögert. 1.2 Funktionen bei PostgreSQL Bei PostgreSQL wird nicht streng zwischen Funktionen und Prozeduren unterschieden, es ist einfach so, dass immer die Anweisung CREATE FUNCTION verwendet wird, der Rückgabewert aber wahlfrei ist. Der Funktionscode wird als Textstring übergeben. Zusätzlich muss man noch angeben, in welcher Sprache die Prozedur geschrieben wurde, denn es kann mehrere Interpreter innerhalb der Datenbank geben. Bei uns ist auf jeden Fall die PostgreSQL- Variante von PL/SQL namens plpgsql vorhanden, im Folgenden PL/pgSQL genannt Syntax von PL/pgSQL Die Syntax zum Erzeugen von Funktionen in PL/pgSQL lautet: create [ or replace ] function function_name ( datatype [,... ] ) returns datatype AS ' plpgsql_function_body ' language 'plpgsql' ; Hierbei steht plpgsql_function_body für den Rumpf der Funktion in Form eines Textstrings daher auch die Hochkommas drumherum. Statt dieses Rumpfs kann auch die Deklaration einer C-Funktion verwendet werden dies wird hier aber nicht weiter erläutert. Der Rückgabetyp hinter returns ist zwingend erforderlich und stellt einen SQL-Datentyp dar oder lautet void, record, trigger 3 oder setof datentyp letzteres wird hier nicht weiter erläutert. Der Ablauf einer Funktion wird durch eine return-anweisung beendet; sie ist zwingend erforderlich. Die Parameterliste ist immer vorhanden, d. h. die runden Klammern sind ggf. leer, falls keine Parameter verwendet werden. Parameter können Eingabeparameter (IN, ohnehin default), Ausgabeparameter (OUT) oder Ein-/Ausgabeparameter (INOUT) sein. Nur Einund Ein-/Ausgabeparameter werden beim Funktionsaufruf mitgegeben. Funktionen können in SELECT-Anweisungen hinter FROM wie Tabellen angegeben werden. Die PostgreSQL-Beispiele in diesem Dokument sind in PL/pgSQL geschrieben, einer prozeduralen Variante von SQL, in der man neben den Abfrage- und Cursor-Anweisungen auch Variablen deklarieren und Schleifen benutzen kann. Es gibt auch eine Ausnahmebehandlung und die Möglichkeit, Fehler an die rufende Einheit zurückzuliefern. In PL/pgSQL sind 3) siehe Abschnitte auf Seite 20 und 2.2 auf Seite 27 14

15 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.2. POSTGRESQL die üblichen Datenmanipulationskommandos erlaubt. Um festzustellen, auf wie viele Tupel das letzte Kommando einen Effekt hatte, kann man GET DIAGNOSTICS integervariable = ROW_COUNT verwenden. Außerdem setzen alle Kommandos einschließlich SELECT die boolesche Variable FOUND auf true, sofern mindestens 1 Tupel betroffen ist. Ein Funktionsrumpf stellt einen Anweisungsblock dar. Ein Anweisungsblock besteht aus einem wahlfreien declare-teil, in dem Variablen deklariert werden können, und einem Anweisungsteil, der von und end eingerahmt wird. Kommentare können in der in SQL üblichen Variante mit zwei Minuszeichen oder in der C-Variante mit /*... */ eingefügt werden. Funktionen in PL/pgSQL werden immer innerhalb einer Transaktion ausgeführt, daher können die Kommandos transaction, commit und rollback nicht innerhalb der Funktionen vorkommen. Gelöscht werden können Funktionen mittels drop function function_name (typ,...). Da Funktionen überladen werden können, ist die Angabe der Parametertypliste notwendig. Durch Zusatz von cascade würden auch die Trigger, die sie verwenden, automatisch mit gelöscht. Andernfalls müssten die Trigger vorher gelöscht werden, sofern vorhanden Variablen in PL/pgSQL Variablen werden im declare-teil vereinbart. Sie können alle SQL-Datentypen haben, oder auch den Typ einer Tabellenspalte oder gar einer Tabellenzeile. declare spielnr zeile satz plz integer; spieler%rowtype; record; spieler.plz%type; Ob man bei zeile den Zusatz %rowtype hinzufügt oder weglässt, ist ohne Bedeutung, da jede Tabelle automatisch einen gleichnamigen Rowtyp erzeugt. Die Variante mit %rowtype ist der Schreibweise von Oracle ähnlicher. Wahlweise kann man auch einfach record schreiben, was ein Platzhalter-Datentyp ist. Die allgemeine Syntax für eine Variablendeklaration lautet name [ constant] datentyp [ not null ] [default := ausdruck]; Durch Initialisierung mittels := oder default wird die Variable beim Betreten des Blocks mit einem Wert versehen. Durch den Zusatz constant wird eine Konstante statt einer Variablen vereinbart, die natürlich einen Wert bekommen muss, ebenso wie eine Variable, die als not null deklariert wird. Die Initialisierung findet jedes Mal beim Betreten des Blocks statt. Die Parameter einer Funktion haben zunächst keinen Namen, sondern sind durchnumeriert mit $1, $2 usw. Möchte man lieber benannte Parameter haben, so deklariert man lokale Variablen als Alias für sie. 15

16 1.2. POSTGRESQL KAPITEL 1. PROZEDUREN UND FUNKTIONEN create function sum_strafen (integer) returns decimal as ' declare spielernr alias for $1; summe decimal(10,2); select sum(betrag) into summe from strafen where spielnr = spielernr; return summe; ' language 'plpgsql'; Parametertypen und auch Rückgabetyp einer Funktion können auch unbestimmt sein, so dass sie erst zur Laufzeit festgelegt werden. Auf diese Weise kann man polymorphe Funktionen schreiben. Ohne wirklichen Datenbankbezug, aber ein einfaches Beispiel dazu wäre folgendes. Der Funktion kann man alle Argumente übergeben, die zueinander kompatibel und mittels des +-Operators verknüpft werden können. create function add (anyelement, anyelement) returns anyelement as ' return $1 + $2; ' language 'plpgsql'; Zuweisungen geschehen einfach durch den Operator :=, wobei auf der rechten Seite ein gültiger Ausdruck stehen muss, der zum Datentyp der Variablen auf der linken Seite zuweisungskompatibel ist. Auch durch ein select... into... kann eine Variable einen neuen Wert bekommen. laenge := 2.54; select max(betrag) into betrag from strafen; Sollte bei select kein passendes Tupel gefunden worden sein, so wird der Wert null geliefert. Das kann man ggf. abfangen und durch einen anderen Wert ersetzen: select max(betrag) into betrag from strafen; if not found then betrag := -1; end if; Aufruf von Funktionen in PL/pgSQL Funktionen können überall dort eingesetzt werden, wo ein Ausdruck gefordert wird. Liefert eine Funktion aber gar keinen Wert zurück, sondern hat nur einen nützlichen Nebeneffekt, 16

17 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.2. POSTGRESQL kann man sie mittels perform aufrufen. Bei der Angabe von Anführungszeichen ist darauf zu achten, dass diese doppelt gesetzt werden müssen, falls man sich in einem PL/pgSQL- Block befindet, weil ansonsten der Quelltext für diesen Block beendet würde. perform f2 (''Meier'', 17); Dynamisches Ausführen von Code in PL/pgSQL Um PL/pgSQL-Code auszuführen, den man in einer Variablen vom Typ text zusammengebaut hat, verwendet man das Kommando execute. Innerhalb des dahinter angegebenen Kommandostrings findet keinerlei Variablenersetzung statt, so dass man die passenden Werte beim Konstruieren des Strings einbauen muss. Ergebnisse von select-anweisungen innerhalb des Strings überleben das Ende von execute nicht. Leider ist die Verwendung von select into hier nicht erlaubt. Um Ergebnisse aus einem dynamisch erzeugten SQL-Kommando zu erhalten, muss man eine Schleife mit for, in und execute oder einen Cursor mit open, for und execute benutzen, siehe Abschnitt auf der nächsten Seite Ablaufsteuerung in PL/pgSQL Als prozedurale Variante von SQL gibt es in PL/pgSQL alle üblichen Strukturen zur Ablaufsteuerung, d. h. Verzweigungen und Schleifen. if bedingung then Anweisungen elsif bedingung then Anweisungen else Anweisungen end if; loop Anweisungen exit when bedingung Anweisungen end loop; for i in [ reverse ] klein..gross loop Anweisungen end loop; for i in selectanweisung loop Anweisungen 17

18 1.2. POSTGRESQL KAPITEL 1. PROZEDUREN UND FUNKTIONEN end loop; while gehalt < 1000 loop Anweisungen end loop; Die numerische for-schleife kann vorwärts oder rückwärts ablaufen, aber die untere Grenze steht immer zuerst, auch wenn reverse angegeben ist. Die Schleifen können durch die Anweisung exit verlassen werden. Dies kann in einem if-konstrukt geschehen oder mittels exit when bedingung Cursor in PL/pgSQL Cursor dienen der sequentiellen Verarbeitung von Abfrageergebnissen.. Sie können gebunden sein, ungebunden oder parametrisiert, so dass man insgesamt drei verschiedene Arten der Cursordeklaration verwenden kann: declare cursor1 refcursor; cursor2 cursor for select * from strafen; cursor3 cursor (nr integer) is select * from strafen where spielnr=nr; cursor1 kann mit jeder beliebigen Abfrage verwendet werden, die dann beim Öffnen des Cursors angegeben werden muss. cursor2 ist ein gebundener Cursor, weil die Abfrage schon feststeht, während cursor3 ein parametrisierter Cursor ist, dem man beim Öffnen nur noch die passenden Werte für die Parameter mitgibt. So könnte man sie öffnen: open cursor1 for select * from teams where spielnr = nummer; Beim Öffnen von cursor1 muss nummer eine PL/pgSQL-Variable von einem zu spielnr passenden Typ sein. Sie wird durch ihren aktuellen Wert ersetzt. open cursor1 for execute ''select * from '' quote_ident(param1); param1 muss jetzt ein benannter Parameter oder eine andere Variable in der aktuellen Funktion sein; wenn der Parameter unbenannt ist, tut es natürlich auch ein $n für den n- ten Parameter. Die Funktion quote_ident() sorgt dafür, dass der Name richtig übergeben wird. Einen gebundenen Cursor öffnet man einfach durch Angabe des Namens; wenn er parametrisiert ist, gibt man die Parameter in Klammern dahinter an: open cursor2; open cursor3 (44); 18

19 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.2. POSTGRESQL Nachdem die Cursor geöffnet wurden bitte darauf achten, keine Cursor zu öffnen, die schon offen sind, kann man mittels fetch die Ergebnistupel abholen, wobei die hinter into angegebenen Variablen vom Typ und von der Anzahl her zur Abfrage passen müssen, oder es wird ein passender Rowtyp verwendet. Anschließend muss der Cursor wieder geschlossen werden. Bei fetch und close unterscheiden sich die drei Cursorarten nicht. fetch cursor1 into tnr, snr, liga; close cursor1; Cursor können auch als Funktionswert an die rufende Einheit zurückgeliefert werden. Das ist sinnvoll, um mehrere Tupel oder Spalten zurückzugeben, gerade bei großen Ergebnismengen. Wie bereits oben bei der Deklaration des ungebundenen Cursors gesehen ist der passende Datentyp hierfür refcursor. Hier ein Beispiel, das zeigt, wie man einen Cursornamen an eine Funktion übergeben kann: create function getcursor (refcursor) returns refcursor AS ' declare cursor_name alias for $1; open cursor_name for select teamnr from teams; return cursor_name; END; ' language 'plpgsql'; transaction; select getcursor('beispielcursor'); fetch all in beispielcursor; commit transaction; Bei der Ausführung der Funktion getcursor() ist darauf zu achten, dass dies innerhalb einer Transaktion geschieht (also nicht mit autocommit), weil bei Transaktionsende der Cursor automatisch geschlossen würde. Dann liefert das fetch die Meldung ERROR: cursor "beispielcursor" does not exist. Eine einfache Möglichkeit, Werte eines Abfrageergebnisses zu verarbeiten, ist die zweite Variante der for-schleife. create table str ( znr integer primary key, spnr integer not null, datum date not null, sum decimal(10,2) not null ); create function s1 (integer) returns void as ' 19

20 1.2. POSTGRESQL KAPITEL 1. PROZEDUREN UND FUNKTIONEN declare satz record; spnr alias for $1; betragsum decimal := 0; delete from str; for satz in select zahlnr, spielnr, datum, betrag from strafen where spielnr = spnr order by datum loop betragsum := betragsum + satz.betrag; insert into str values (satz.zahlnr, satz.spielnr, satz.datum, betragsum); end loop; return; ' language 'plpgsql'; Nach dem Ausführen der Prozedur mit dem Parameter 44 sind alle Strafen des Spielers 44 in der Tabelle str enthalten. Die Deklaration eines Cursors ist hier nicht einmal erforderlich, denn das geschieht automatisch intern Fehlerbehandlung in PL/pgSQL PL/pgSQL hat keine umfangreichen Möglichkeiten der Fehlerbehandlung. Fehler führen immer dazu, dass eine Funktion abgebrochen und damit auch die Transaktion zurückgefahren wird. Meldungen können vom Datenbanksystem erzeugt werden oder auch von selbst geschriebenen Anweisungen. Es wird zwischen verschiedenen Stufen (level) unterschieden, ob es nur ein Hinweis oder ein schwerer Fehler ist. Folgende Stufen gibt es: debug, log, info, notice, warning, exception. Nur exception führt zum Abbruch der Funktion und damit der Transaktion, die anderen erscheinen z. B. in der Log-Datei des Datenbankservers. Die Aufrufsyntax sieht so aus: raise level format [, variable...]; Innerhalb der Formatangabe werden Prozentzeichen durch den Inhalt der entsprechenden Variablen ersetzt ganz analog zu printf() in C, aber ohne Angabe von irgendwelchen Typ- oder Längenangaben. Beispiel: raise exception 'Fehler: Wert (%) nicht eindeutig', spielnr; Triggerfunktionen Funktionen, die für Trigger (siehe Abschnitt 2.2 auf Seite 27) benutzt werden, haben keine Parameter und den Rückgabetyp trigger. Eine Triggerfunktion für das Prüfen der Zimmerbelegung in der Krankenhaus-Datenbank sieht wie folgt aus: 20

21 KAPITEL 1. PROZEDUREN UND FUNKTIONEN 1.2. POSTGRESQL create function freibetten () returns trigger AS ' declare anzfrei integer; select betten - count(*) into anzfrei from zimmer natural join patient where zimmer.znr=new.znr group by zimmer.znr, betten; if anzfrei < 0 then raise exception ''% für Tabelle "%": Zimmer % würde überbelegt'', TG_OP, TG_RELNAME, new.znr; end if; return new; END; ' language 'plpgsql'; Zunächst wird eine Variable anzfrei deklariert. Es können hier alle in PostgreSQL zulässigen Datentypen verwendet werden. Zwischen und end steht der auszuführende Code, der mit einem select-statement nt. Wegen der into-klausel sieht es fast aus wie ein Embedded SQL Kommando, allerdings hat die Variable anzfrei hinter dem into keinen führenden Doppelpunkt, denn es ist eine SQL-Variable und keine aus einer anderen Sprache, die in SQL eingebettet wurde. In der Verzweigung mit if wird das Ergebnis der Abfrage mit 0 verglichen. Für den Fall, dass das Zimmer also überbelegt ist, wird mittels raise exception ein Fehler erzeugt, der dann an das Anwendungsprogramm (oder auch an psql) weitergegeben wird. Die Fehlermeldung muss in doppelt geschriebenen einfachen Hochkommas stehen. Das Doppeltsetzen ist notwendig, weil der gesamte Code schon in Hochkommas steht. In den Fehlertext werden drei Systemvariablenwerte eingefügt: TG_OP ist die aktuell ausgeführte Operation (INSERT, UPDATE, DELETE), TG_RELNAME ist der Name der Relation (Tabelle), new bezeichnet allgemein das neu eingefügte Tupel (bei einem UPDATE gibt es auch old, bei DELETE gibt es nur old), wir greifen hier auf das Attribut znr zu. Andernfalls wird kein Fehler erzeugt, so dass die Anweisung, die den Trigger abgefeuert hat, wirksam durchgeführt wird. Nach Abschluss des Hochkommas für den Programmcode muss noch die Sprache angegeben werden. Näheres zu Triggern in PostgreSQL siehe Abschnitt 2.2 auf Seite

22 2 Trigger Trigger sind ein vielfältiges Mittel zur Absicherung der Konsistenz bei komplexeren Prüfungen als es die einfachen Constraints vermögen. Beispiel in unserer Krankenhaus-Datenbank ist beispielsweise die Absicherung, dass einem Zimmer nicht mehr Patienten zugewiesen werden können als das Zimmer Betten hat. Dieses Beispiel soll im Folgenden auch verwendet werden. Trigger können definiert sein, um vor (before) oder nach (after) dem Abarbeiten der gesamten Anweisung (statement) oder vor oder nach dem Verarbeiten jedes einzelnen Tupels (row) abgefeuert zu werden. Es gibt also insgesamt vier verschiedene Möglichkeiten, den Abfeuerungszeitpunkt zu bestimmen: ˆ before statement wird 1x pro Anweisung ausgeführt, und zwar ganz am Anfang, auch wenn diese Anweisung viele Tupel betrifft oder auch gar keins. ˆ before row wird 1x pro Tupel ausgeführt, und zwar vor der eigentlichen Datenbankoperation. ˆ after row wird 1x pro Tupel ausgeführt, und zwar nach der eigentlichen Datenbankoperation. ˆ after statement wird 1x pro Anweisung ausgeführt, und zwar ganz am Ende, nachdem alle Tupel verarbeitet wurden (auch wenn es keine waren). 2.1 Trigger bei Oracle Erzeugen von Triggern in Oracle Bei Oracle umfasst die Erzeugung eines Triggers gleich den zugehörigen Anweisungsblock. Prinzipiell sieht die Erzeugung eines Triggers daher fast so aus wie die Erzeugung einer Prozedur. Es ist nicht notwendig, den Codeblock als Prozedur abzulegen. Die Syntax zum Erzeugen eines Triggers lautet: create [ or replace ] trigger triggername { after before } { insert update delete [ or { insert update delete }... ] } ON tabellenname [ for each row [ when bedingung ] ] [ declare deklarationsteil ] 22

23 KAPITEL 2. TRIGGER 2.1. ORACLE anweisungen [ exception ausnahmebehandlungsteil ] end [ triggername ] ; / Triggernamen müssen innerhalb eines Schemas eindeutig sein, d. h. auch wenn sie sich auf verschiedene Tabellen beziehen, dürfen sie nicht den selben Namen tragen. Wenn man Trigger in einem interaktiven Tool eingibt, muss hinter dem noch ein Slash (/) allein in der nächsten Zeile stehen andernfalls erhält man die unspezifische Meldung success with compilation error. Trigger können vor oder nach der Verarbeitung der gesamten Anweisung (sogenannte Anweisungstrigger) oder vor oder nach Verarbeitung jedes einzelnen Tupels (sogenannte Zeilentrigger) abgefeuert werden. Bei Zeilentriggern wird der Zusatz for each row) verwendet, bei Anweisungstriggern nicht. Durch eine hinter when angegebene Bedingung kann die Abfeuerung eingeschränkt werden, was aber auch eine if-bedingung am Anfang des Triggers kann. Trigger können gelöscht werden mittels drop trigger triggername. Möchte man einen Trigger nur temporär außer Kraft setzen, so verwendet man alter trigger triggername { disable enable }. Ein Umbenennen von Triggern ist nicht vorgesehen. Um alle Trigger für eine Tabelle zu deaktivieren oder wieder zu aktivieren, verwendet man alter table tabellenname { disable enable } all triggers; Zugriff auf Daten in Triggern bei Oracle Bei Zeilentriggern kann man auf die Pseudo-Datensätze :old und :new zugreifen, die automatisch zur Verfügung stehen. Sie sind vom Rowtyp der aktuellen Tabelle und beinhalten das aktuelle Tupel vor :old bzw. nach :new der Änderung. Bei Einfügeoperationen gibt es naturgemäß nur :new, bei Löschoperationen nur :old. Die Datensätze heißen Pseudo- Datensätze, weil man nur auf ihre Felder :new.spielnr zugreifen kann, aber nicht auf den Datensatz als Ganzes, um ihn z. B. einer anderen Variable vom selben Rowtyp zuzuweisen oder ihn damit zu vergleichen. Die Werte im :new-pseudodatensatz kann man verändern. Geschieht das in einem before- Trigger, so wird die Datenbankoperation mit den veränderten Daten weitergeführt. Das wird beispielsweise beim automatischen Hochzählen von künstlich erzeugten Schlüsseln verwendet. Ein Beispiel dazu ist im Dokument Auto-Increment-Spalten in Datenbanken enthalten. In Anweisungstriggern kann man die Pseudodatensätze nicht verwenden. Um festzustellen, von welcher Art Datenbankoperation der Trigger gerade abgefeuert wurde, kann man einige boolesche Prädikate abfragen. Um das Beispiel zur Erzeugung einer History aus dem Dokument History-Funktion in Datenbanken dort gezeigt mit Hilfe von PostgreSQL-Regeln unter Verwendung eines Oracle-Triggers und der Prädikate zu realisieren, programmiert man so: 23

24 2.1. ORACLE KAPITEL 2. TRIGGER create trigger artikel_history before update or delete on artikel for each row declare aktion char(1); if updating then aktion := 'U'; else aktion := 'D'; end if; insert into artikel_history (artnr, bezeichnung, vkpreis, aktion) values (:old.artnr, :old.bezeichnung, :old.vkpreis, aktion); / Genau wie im Beispiel aus dem History-Dokument muss die Tabelle artikel_history mit einer Autoincrement-Spalte versehen sein, was wiederum im entsprechenden Dokument erläutert wird und bei Oracle etwas mehr Aufwand erfordert als bei anderen Datenbanken instead of-trigger Diese Art von Triggern existieren speziell für Views, um diese auch dann schreibfähig zu machen, wenn sie Aggregatfunktionen oder Verbundoperationen enthalten. Ein Beispiel hierzu findet sich im Dokument Views in SQL Zugriff auf Daten der aktuellen Tabelle (mutating table) Bei Oracle (und nach aktuellem Kenntnisstand ausschließlich dort) gibt es das sogenannte Mutating Table -Problem. Es ist nicht erlaubt, mittels Anweisungen innerhalb eines Zeilentriggers auf sich verändernde Tabellen schreibend oder auch nur lesend zuzugreifen. Als sich verändernde Tabellen gilt zunächst einmal die Tabelle, für die der Zeilentrigger definiert wurde, aber auch alle Tabellen, die durch ein on delete cascade ebenfalls verändert werden. Falls man gegen diese Regeln verstößt, bekommt man den Fehler ORA Zitat aus dem ZDNet-Artikel Learn to avoid the mutating table problem in Oracle: Mutating tables in Oracle can drive any IT database manager insane when it comes to tracking down the culprit. With a clear idea of the table design required, however, this problem can be avoided. Ebenfalls verboten ist ein schreibender oder auch lesender Zugriff auf die eindeutigen Schlüssel-, Primärschlüssel- oder Fremdschlüsselattribute einer die triggernde Tabelle einschränkenden Tabelle. Dies sind die Tabellen, die zwecks Fremdschlüsselprüfung ausgelesen werden müssen. 24

25 KAPITEL 2. TRIGGER 2.1. ORACLE Diese Einschränkungen gelten für alle Zeilentrigger; bei Anweisungstriggern nur dann, wenn sie auf Grund eines delete cascade abgefeuert wurden. Wenn eine insert-anweisung nur eine einzige Zeile betrifft, dann gilt die Tabelle nicht als sich verändernd. Falls aber insert into tabelle select... verwendet wird, ist die tabelle eine sich verändernde Tabelle, auch wenn das Ergebnis der select-anweisung nur ein einziges Tupel ist. Das Beispiel mit der Überprüfung der Zimmerbelegung ist in PostgreSQL überhaupt kein Problem (siehe Abschnitt auf Seite 28), bei Oracle erfordert es mehr Aufwand. Man muss ein Package definieren, um eine Variable zu bekommen, die länger lebt als ein Prozeduraufruf. Dann kann man in einem Anweisungstrigger nach der Durchführung aller anderen Teile der Anweisung die Konsistenz überprüfen. Es gibt zwei Möglichkeiten, das Problem der sich verändernden Tabelle zu umgehen. Erstens kann man den Zeilentrigger zu einer autonomen Transaktion machen, zweitens kann man ein Package anlegen und sowohl Zeilen- als auch Anweisungstrigger benutzen. Wir schauen uns beide Varianten an und beurteilen danach, welche zu einer zufrieden stellenden Lösung führen. Trigger mit autonomer Transaktion create or replace trigger mut1 before insert on k_patient for each row declare anzfrei integer; pragma autonomous_transaction; select betten - count(*) into anzfrei from k_zimmer z, k_patient p where z.znr = p.znr and z.znr = :new.znr group by z.znr, betten; if anzfrei <= 0 then raise_application_error (-20001, 'Zimmer ' :new.znr ' überbelegt'); end if; commit work; exception when no_data_found then return; / Der Trigger wird hier als autonome Transaktion ausgeführt. Dabei sieht er bei der Verarbeitung jeder einzelnen Zeile den Zustand der Datenbank, wie er vor dem Beginn der 25

26 2.1. ORACLE KAPITEL 2. TRIGGER gesamten Transaktion war. Durch diesen Kunstgriff wird vermieden, dass die Tabelle k_ patient als sich verändernde Tabelle wahrgenommen wird. Beim Einfügen eines neuen Patienten wird also geprüft, ob noch mindestens 1 Bett im Zimmer frei ist. Die Ablauflogik unterscheidet drei Fälle: Wird beim select nichts gefunden, so wird die Ausnahme no_data_found erzeugt und anschließend gefangen. Wird festgestellt, dass zwar Betten belegt sind, es aber noch freie Betten gibt, wird die autonome Transaktion mittels commit work beendet, also das Einfügen durchgeführt. Im dritten Fall, dass die Variable anzfrei einen Wert kleiner als 0 bekommt, wird ein Anwendungsfehler erzeugt, der dazu führt, dass das Einfügen des Tupels rückgängig gemacht wird. So weit, so gut. Die Tücke steckt aber im Detail. Fügen wir mehrere Patienten in einer einzigen Transaktion ein (evtl. sogar auf mehrere Anweisungen verteilt), so wird für jeden einzelnen Patienten geprüft, ob zu Beginn der Transaktion noch ein Bett im jeweiligen Zimmer frei war. Das genügt aber nicht! Denn wenn nur ein Bett frei war, kann ich dem Zimmer beliebig viele neue Patienten innerhalb der Transaktion hinzufügen was zweifelsohne zu einer Überbelegung führen kann. Der Ansatz mit autonomer Transaktion führt also zu einer völlig inakzeptablen Scheinlösung! Trigger mit Package create or replace package mutpack1 as type zimmernr_t is table of k_zimmer.znr%type index by binary_integer; zimmernr zimmernr_t; anzahl binary_integer := 0; create or replace trigger mut_row before insert on k_patient for each row mutpack1.anzahl := mutpack1.anzahl + 1; mutpack1.zimmernr(mutpack1.anzahl) := :new.znr; / create or replace trigger mut_stat after insert on k_patient declare anzfrei integer; zimmernr k_zimmer.znr%type; for i in 1..mutpack1.anzahl loop 26

27 KAPITEL 2. TRIGGER 2.2. POSTGRESQL zimmernr := mutpack1.zimmernr(i); select betten - count(*) into anzfrei from k_zimmer z, k_patient p where z.znr = p.znr and z.znr = zimmernr group by z.znr, betten; if anzfrei < 0 then mutpack1.anzahl := 0; raise_application_error (-20001, 'Zimmer ' zimmernr ' überbelegt'); end if; end loop; mutpack1.anzahl := 0; / Der zweite Ansatz ist leider etwas aufwendiger. Es wird ein Package generiert, das eine tabellenwertige Variable enthält und eine Variable mit der Anzahl der Tupel in dieser Variablen. Jede Transaktion, die das Package verwendet, sieht eine eigene Instanz dieser Variablen, so dass parallele Transaktionen hier kein Problem darstellen. Es werden zwei Trigger verwendet: ein Zeilen- und ein Anweisungstrigger. Der Zeilentrigger fügt die Nummer des betroffenen Zimmers zum Array zimmernr hinzu und erhöht die Variable anzahl um 1. Der Anweisungstrigger, der ausgeführt wird, nachdem alle Tupel aus der Anweisung eingefügt worden sind, hat kein Problem mit der sich verändernden Tabelle. Er durchläuft das Array und prüft für jede dort gespeicherte Zimmernummer (evtl. also mehrfach, falls mehrere Patienten in dasselbe Zimmer gekommen sind, aber das stört nicht weiter), ob mittlerweile die Anzahl der freien Betten unter 0 gesunken ist. Sollte das der Fall sein, wird ein Anwendungsfehler generiert und damit die gesamte Anweisung zurückgefahren. Für den Fall, dass es gut gegangen ist, wird die Package-Variable anzahl wieder auf 0 gesetzt für einen evtl. zweiten Durchlauf innerhalb derselben Transaktion. Bei einem Ende der Transaktion werden die Variablen des Package ohnehin gelöscht. Nur diese Variante liefert also eine sinnvolle Überprüfung für den Fall des Einfügens neuer Patienten. (Die Konsistenz der Datenbank diesbezüglich ist mit diesem einen Package mit seinen zwei Triggern aber noch nicht gesichert, denn auch beim Verlegen von Patienten von einem Zimmer in ein anderes kann es zu Überbelegungen kommen.) 2.2 Trigger bei PostgreSQL Nicht für alle automatisch ausgelösten Aktionen ist es bei PostgreSQL notwendig, einen Trigger zu verwenden. Um beispielsweise Views schreibfähig zu machen oder eine History- 27

Prozedurale Datenbank- Anwendungsprogrammierung

Prozedurale Datenbank- Anwendungsprogrammierung Idee: Erweiterung von SQL um Komponenten von prozeduralen Sprachen (Sequenz, bedingte Ausführung, Schleife) Bezeichnung: Prozedurale SQL-Erweiterung. In Oracle: PL/SQL, in Microsoft SQL Server: T-SQL.

Mehr

Views in SQL. 2 Anlegen und Verwenden von Views 2

Views in SQL. 2 Anlegen und Verwenden von Views 2 Views in SQL Holger Jakobs bibjah@bg.bib.de, holger@jakobs.com 2010-07-15 Inhaltsverzeichnis 1 Wozu dienen Views? 1 2 Anlegen und Verwenden von Views 2 3 Schreibfähigkeit von Views 3 3.1 Views schreibfähig

Mehr

Dynamisches SQL. Folien zum Datenbankpraktikum Wintersemester 2009/10 LMU München

Dynamisches SQL. Folien zum Datenbankpraktikum Wintersemester 2009/10 LMU München Kapitel 4 Dynamisches SQL Folien zum Datenbankpraktikum Wintersemester 2009/10 LMU München 2008 Thomas Bernecker, Tobias Emrich unter Verwendung der Folien des Datenbankpraktikums aus dem Wintersemester

Mehr

Dipl. Inf. Dipl. Math. Y. Orkunoglu Datum: 11.09.2009

Dipl. Inf. Dipl. Math. Y. Orkunoglu Datum: 11.09.2009 Hochschule Darmstadt DATENBANKEN Fachbereich Informatik Praktikum 3 Dipl. Inf. Dipl. Math. Y. Orkunoglu Datum: 11.09.2009 PL/SQL Programmierung Anwendung des Cursor Konzepts und Stored Procedures Und Trigger

Mehr

Gesicherte Prozeduren

Gesicherte Prozeduren Gesicherte Prozeduren Wenn eine Anwendung auf einer Client-Maschine läuft, wird normalerweise jede SQL-Anweisung einzeln vom Client an den Server gesandt, und jedes Ergebnistupel wird einzeln zurückgeliefert.

Mehr

5 DATEN. 5.1. Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

5 DATEN. 5.1. Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu Daten Makro + VBA effektiv 5 DATEN 5.1. Variablen Variablen können beliebige Werte zugewiesen und im Gegensatz zu Konstanten jederzeit im Programm verändert werden. Als Variablen können beliebige Zeichenketten

Mehr

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen: VBA Programmierung mit Excel Schleifen 1/6 Erweiterung der Aufgabe Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen: Es müssen also 11 (B L) x 35 = 385 Zellen berücksichtigt

Mehr

Oracle Datenbankprogrammierung mit PL/SQL Grundlagen

Oracle Datenbankprogrammierung mit PL/SQL Grundlagen Oracle Datenbankprogrammierung mit PL/SQL Grundlagen Seminarunterlage Version: 12.05 Version 12.05 vom 29. Januar 2015 Dieses Dokument wird durch die veröffentlicht.. Alle Rechte vorbehalten. Alle Produkt-

Mehr

1 Vom Problem zum Programm

1 Vom Problem zum Programm Hintergrundinformationen zur Vorlesung GRUNDLAGEN DER INFORMATIK I Studiengang Elektrotechnik WS 02/03 AG Betriebssysteme FB3 Kirsten Berkenkötter 1 Vom Problem zum Programm Aufgabenstellung analysieren

Mehr

Bereich METIS (Texte im Internet) Zählmarkenrecherche

Bereich METIS (Texte im Internet) Zählmarkenrecherche Bereich METIS (Texte im Internet) Zählmarkenrecherche Über die Zählmarkenrecherche kann man nach der Eingabe des Privaten Identifikationscodes einer bestimmten Zählmarke, 1. Informationen zu dieser Zählmarke

Mehr

Objektorientierte Programmierung

Objektorientierte Programmierung Objektorientierte Programmierung 1 Geschichte Dahl, Nygaard: Simula 67 (Algol 60 + Objektorientierung) Kay et al.: Smalltalk (erste rein-objektorientierte Sprache) Object Pascal, Objective C, C++ (wiederum

Mehr

3. Stored Procedures und PL/SQL

3. Stored Procedures und PL/SQL 3. Stored Procedures und PL/SQL Wenn eine Anwendung auf einer Client-Maschine läuft, wird normalerweise jede SQL-Anweisung einzeln vom Client an den Server gesandt, und jedes Ergebnistupel wird einzeln

Mehr

Funktionen. Überblick über Stored Functions. Syntax zum Schreiben einer Funktion. Schreiben einer Funktion

Funktionen. Überblick über Stored Functions. Syntax zum Schreiben einer Funktion. Schreiben einer Funktion Überblick über Stored Functions Funktionen Eine Funktion ist ein benannter PL/SQL- Block, der einen Wert zurückgibt. Eine Funktion kann in der Datenbank als Objekt zur wiederholbaren Ausführung gespeichert

Mehr

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Java Kurs für Anfänger Einheit 4 Klassen und Objekte Java Kurs für Anfänger Einheit 4 Klassen und Ludwig-Maximilians-Universität München (Institut für Informatik: Programmierung und Softwaretechnik von Prof.Wirsing) 13. Juni 2009 Inhaltsverzeichnis klasse

Mehr

Mengenvergleiche: Alle Konten außer das, mit dem größten Saldo.

Mengenvergleiche: Alle Konten außer das, mit dem größten Saldo. Mengenvergleiche: Mehr Möglichkeiten als der in-operator bietet der θany und der θall-operator, also der Vergleich mit irgendeinem oder jedem Tupel der Unteranfrage. Alle Konten außer das, mit dem größten

Mehr

Whitepaper. Produkt: combit Relationship Manager. Datensatzhistorie mit dem SQL Server 2000 und 2005. combit GmbH Untere Laube 30 78462 Konstanz

Whitepaper. Produkt: combit Relationship Manager. Datensatzhistorie mit dem SQL Server 2000 und 2005. combit GmbH Untere Laube 30 78462 Konstanz combit GmbH Untere Laube 30 78462 Konstanz Whitepaper Produkt: combit Relationship Manager Datensatzhistorie mit dem SQL Server 2000 und 2005 Datensatzhistorie mit dem SQL Server 2000 und 2005-2 - Inhalt

Mehr

Fallbeispiel: Eintragen einer Behandlung

Fallbeispiel: Eintragen einer Behandlung Fallbeispiel: Eintragen einer Behandlung Im ersten Beispiel gelernt, wie man einen Patienten aus der Datenbank aussucht oder falls er noch nicht in der Datenbank ist neu anlegt. Im dritten Beispiel haben

Mehr

4. BEZIEHUNGEN ZWISCHEN TABELLEN

4. BEZIEHUNGEN ZWISCHEN TABELLEN 4. BEZIEHUNGEN ZWISCHEN TABELLEN Zwischen Tabellen können in MS Access Beziehungen bestehen. Durch das Verwenden von Tabellen, die zueinander in Beziehung stehen, können Sie Folgendes erreichen: Die Größe

Mehr

Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten

Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten 2008 netcadservice GmbH netcadservice GmbH Augustinerstraße 3 D-83395 Freilassing Dieses Programm ist urheberrechtlich geschützt. Eine Weitergabe

Mehr

ecaros2 - Accountmanager

ecaros2 - Accountmanager ecaros2 - Accountmanager procar informatik AG 1 Stand: FS 09/2012 Inhaltsverzeichnis 1 Aufruf des ecaros2-accountmanager...3 2 Bedienung Accountmanager...4 procar informatik AG 2 Stand: FS 09/2012 1 Aufruf

Mehr

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen Binäre Bäume 1. Allgemeines Binäre Bäume werden grundsätzlich verwendet, um Zahlen der Größe nach, oder Wörter dem Alphabet nach zu sortieren. Dem einfacheren Verständnis zu Liebe werde ich mich hier besonders

Mehr

Erwin Grüner 09.02.2006

Erwin Grüner 09.02.2006 FB Psychologie Uni Marburg 09.02.2006 Themenübersicht Folgende Befehle stehen in R zur Verfügung: {}: Anweisungsblock if: Bedingte Anweisung switch: Fallunterscheidung repeat-schleife while-schleife for-schleife

Mehr

Mediator 9 - Lernprogramm

Mediator 9 - Lernprogramm Mediator 9 - Lernprogramm Ein Lernprogramm mit Mediator erstellen Mediator 9 bietet viele Möglichkeiten, CBT-Module (Computer Based Training = Computerunterstütztes Lernen) zu erstellen, z. B. Drag & Drop

Mehr

Informatik 12 Datenbanken SQL-Einführung

Informatik 12 Datenbanken SQL-Einführung Informatik 12 Datenbanken SQL-Einführung Gierhardt Vorbemerkungen Bisher haben wir Datenbanken nur über einzelne Tabellen kennen gelernt. Stehen mehrere Tabellen in gewissen Beziehungen zur Beschreibung

Mehr

Hilfedatei der Oden$-Börse Stand Juni 2014

Hilfedatei der Oden$-Börse Stand Juni 2014 Hilfedatei der Oden$-Börse Stand Juni 2014 Inhalt 1. Einleitung... 2 2. Die Anmeldung... 2 2.1 Die Erstregistrierung... 3 2.2 Die Mitgliedsnummer anfordern... 4 3. Die Funktionen für Nutzer... 5 3.1 Arbeiten

Mehr

Wir arbeiten mit Zufallszahlen

Wir arbeiten mit Zufallszahlen Abb. 1: Bei Kartenspielen müssen zu Beginn die Karten zufällig ausgeteilt werden. Wir arbeiten mit Zufallszahlen Jedesmal wenn ein neues Patience-Spiel gestartet wird, muss das Computerprogramm die Karten

Mehr

SQL (Structured Query Language) Schemata Datentypen

SQL (Structured Query Language) Schemata Datentypen 2 SQL Sprachelemente Grundlegende Sprachelemente von SQL. 2.1 Übersicht Themen des Kapitels SQL Sprachelemente Themen des Kapitels SQL (Structured Query Language) Schemata Datentypen Im Kapitel SQL Sprachelemente

Mehr

Einführung in die Java- Programmierung

Einführung in die Java- Programmierung Einführung in die Java- Programmierung Dr. Volker Riediger Tassilo Horn riediger horn@uni-koblenz.de WiSe 2012/13 1 Wichtig... Mittags keine Pommes... Praktikum A 230 C 207 (Madeleine + Esma) F 112 F 113

Mehr

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = 0.51129 Euro ergeben.

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = 0.51129 Euro ergeben. Aufgabe 1.30 : Schreibe ein Programm DM_in_Euro.java zur Umrechnung eines DM-Betrags in Euro unter Verwendung einer Konstanten für den Umrechnungsfaktor. Das Programm soll den DM-Betrag als Parameter verarbeiten.

Mehr

Java Kurs für Anfänger Einheit 5 Methoden

Java Kurs für Anfänger Einheit 5 Methoden Java Kurs für Anfänger Einheit 5 Methoden Ludwig-Maximilians-Universität München (Institut für Informatik: Programmierung und Softwaretechnik von Prof.Wirsing) 22. Juni 2009 Inhaltsverzeichnis Methoden

Mehr

mit Musterlösungen Prof. Dr. Gerd Stumme, Dipl.-Inform. Christoph Schmitz 11. Juni 2007

mit Musterlösungen Prof. Dr. Gerd Stumme, Dipl.-Inform. Christoph Schmitz 11. Juni 2007 6. Übung zur Vorlesung Datenbanken im Sommersemester 2007 mit Musterlösungen Prof. Dr. Gerd Stumme, Dipl.-Inform. Christoph Schmitz 11. Juni 2007 Aufgabe 1: Rekursion Betrachten Sie die folgende Tabelle

Mehr

Universität Stuttgart Abteilung Anwendersoftware 01.07.2002. - Steht für Embedded SQL in Java. - Java-Methoden als SQL Stored-Procedures

Universität Stuttgart Abteilung Anwendersoftware 01.07.2002. - Steht für Embedded SQL in Java. - Java-Methoden als SQL Stored-Procedures SQLJ Basics Universität Stuttgart Abteilung Anwendersoftware 01.07.2002 Was ist SQLJ? SQLJ Part 0: - Steht für Embedded SQL in Java SQLJ Part 1: - Java-Methoden als SQL Stored-Procedures SQLJ Part 2: -

Mehr

Anleitung über den Umgang mit Schildern

Anleitung über den Umgang mit Schildern Anleitung über den Umgang mit Schildern -Vorwort -Wo bekommt man Schilder? -Wo und wie speichert man die Schilder? -Wie füge ich die Schilder in meinen Track ein? -Welche Bauteile kann man noch für Schilder

Mehr

Einführung in die Programmierung

Einführung in die Programmierung Technische Universität München WS 2003/2004 Institut für Informatik Prof. Dr. Christoph Zenger Testklausur Einführung in die Programmierung Probeklausur Java (Lösungsvorschlag) 1 Die Klasse ArrayList In

Mehr

Funktion definieren Gibt Summe der Gehälter zurück. Aufruf in einem SQL-Statement

Funktion definieren Gibt Summe der Gehälter zurück. Aufruf in einem SQL-Statement Funktion definieren Gibt Summe der Gehälter zurück Aufruf in einem SQL-Statement Dr. Christian Senger Einführung PL/SQL 1 Procedures & Transaktionen CREATE OR REPLACE PROCEDURE write_log ( log_code IN

Mehr

Datenbanken Kapitel 2

Datenbanken Kapitel 2 Datenbanken Kapitel 2 1 Eine existierende Datenbank öffnen Eine Datenbank, die mit Microsoft Access erschaffen wurde, kann mit dem gleichen Programm auch wieder geladen werden: Die einfachste Methode ist,

Mehr

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: 24.09.2014)

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: 24.09.2014) Handbuch NAFI Online-Spezial 1. Auflage (Stand: 24.09.2014) Copyright 2016 by NAFI GmbH Unerlaubte Vervielfältigungen sind untersagt! Inhaltsangabe Einleitung... 3 Kundenauswahl... 3 Kunde hinzufügen...

Mehr

Aufklappelemente anlegen

Aufklappelemente anlegen Aufklappelemente anlegen Dieses Dokument beschreibt die grundsätzliche Erstellung der Aufklappelemente in der mittleren und rechten Spalte. Login Melden Sie sich an der jeweiligen Website an, in dem Sie

Mehr

Universität Duisburg-Essen Informationssysteme Prof. Dr.-Ing. N. Fuhr. Praktikum Datenbanken / DB2 Woche 8: Trigger, SQL-PL

Universität Duisburg-Essen Informationssysteme Prof. Dr.-Ing. N. Fuhr. Praktikum Datenbanken / DB2 Woche 8: Trigger, SQL-PL Betreuer: Sascha Kriewel, Tobias Tuttas Raum: LF 230 Bearbeitung: 26., 27. und 29. Juni 2006 Datum Team (Account) Vorbereitung Präsenz Aktuelle Informationen, Ansprechpartner und Material unter: http://www.is.inf.uni-due.de/courses/dbp_ss07/index.html

Mehr

Kapitel 33. Der xml-datentyp. In diesem Kapitel: Der xml-datentyp 996 Abfragen aus xml-datentypen 1001 XML-Indizierung 1017 Zusammenfassung 1023

Kapitel 33. Der xml-datentyp. In diesem Kapitel: Der xml-datentyp 996 Abfragen aus xml-datentypen 1001 XML-Indizierung 1017 Zusammenfassung 1023 Kapitel 33 Der xml-datentyp In diesem Kapitel: Der xml-datentyp 996 Abfragen aus xml-datentypen 1001 XML-Indizierung 1017 Zusammenfassung 1023 995 996 Kapitel 33: Der xml-datentyp Eine der wichtigsten

Mehr

Oracle: Abstrakte Datentypen:

Oracle: Abstrakte Datentypen: Oracle: Abstrakte Datentypen: Oracle bietet zwei mögliche Arten um abstrakte Datentypen zu implementieren: Varying Array Nested Table Varying Array (kunde) kdnr kdname gekaufteart 1 Mustermann 1 4 5 8

Mehr

Einführung in PL/SQL

Einführung in PL/SQL Einführung in PL/SQL Procedural Language/Structured Query Language Prozedurale Erweiterung der Sprache SQL für Elemente wie Variablen, Schleifen, Bedingungen, Ausnahmebehandlung Dr. Christian Senger Einführung

Mehr

10.6 Programmier-Exits für Workitems

10.6 Programmier-Exits für Workitems 10.6 Programmier-Exits für Workitems 279 10.6 Programmier-Exits für Workitems 10.6.1 Das Interface IF_SWF_IFS_WORKITEM_EXIT Am Schritt einer Workflow-Definition im Reiter»Programmier-Exits«können verschiedene

Mehr

Access [basics] Aktionsabfragen per VBA ausführen. Beispieldatenbank. Aktionsabfragen. Die Execute-Methode. Datenzugriff per VBA

Access [basics] Aktionsabfragen per VBA ausführen. Beispieldatenbank. Aktionsabfragen. Die Execute-Methode. Datenzugriff per VBA Aktionsabfragen lassen sich bequem mit der Entwurfsansicht für Abfragen zusammenstellen. Sie können damit Daten an Tabellen anfügen, bestehende Daten ändern oder löschen und sogar gleich die passende Tabelle

Mehr

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 von Markus Mack Stand: Samstag, 17. April 2004 Inhaltsverzeichnis 1. Systemvorraussetzungen...3 2. Installation und Start...3 3. Anpassen der Tabelle...3

Mehr

Einführung in PL/SQL

Einführung in PL/SQL 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

Mehr

Datentypen. Agenda für heute, 4. März, 2010. Pascal ist eine streng typisierte Programmiersprache

Datentypen. Agenda für heute, 4. März, 2010. Pascal ist eine streng typisierte Programmiersprache Agenda für heute, 4. März, 2010 Zusammengesetzte if-then-else-anweisungen Datentypen Pascal ist eine streng typisierte Programmiersprache Für jeden Speicherplatz muss ein Datentyp t (Datenformat) t) definiert

Mehr

Primzahlen und RSA-Verschlüsselung

Primzahlen und RSA-Verschlüsselung Primzahlen und RSA-Verschlüsselung Michael Fütterer und Jonathan Zachhuber 1 Einiges zu Primzahlen Ein paar Definitionen: Wir bezeichnen mit Z die Menge der positiven und negativen ganzen Zahlen, also

Mehr

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster Es gibt in Excel unter anderem die so genannten Suchfunktionen / Matrixfunktionen Damit können Sie Werte innerhalb eines bestimmten Bereichs suchen. Als Beispiel möchte ich die Funktion Sverweis zeigen.

Mehr

Zur drittletzten Zeile scrollen

Zur drittletzten Zeile scrollen 1 Fragen und Antworten zur Computerbedienung Thema : Zur drittletzten Zeile scrollen Thema Stichwort Programm Letzte Anpassung Zur drittletzten Zeile scrollen Scrollen VBA Excel 1.02.2014 Kurzbeschreibung:

Mehr

Zwischenablage (Bilder, Texte,...)

Zwischenablage (Bilder, Texte,...) Zwischenablage was ist das? Informationen über. die Bedeutung der Windows-Zwischenablage Kopieren und Einfügen mit der Zwischenablage Vermeiden von Fehlern beim Arbeiten mit der Zwischenablage Bei diesen

Mehr

M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung

M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung M. Graefenhan 2000-12-07 Aufgabe Lösungsweg Übungen zu C Blatt 3 Musterlösung Schreiben Sie ein Programm, das die Häufigkeit von Zeichen in einem eingelesenen String feststellt. Benutzen Sie dazu ein zweidimensionales

Mehr

Übungen 19.01.2012 Programmieren 1 Felix Rohrer. Übungen

Übungen 19.01.2012 Programmieren 1 Felix Rohrer. Übungen Übungen if / else / else if... 2... 2 Aufgabe 2:... 2 Aufgabe 3:... 2 Aufgabe 4:... 2 Aufgabe 5:... 2 Aufgabe 6:... 2 Aufgabe 7:... 3 Aufgabe 8:... 3 Aufgabe 9:... 3 Aufgabe 10:... 3 switch... 4... 4 Aufgabe

Mehr

Stammdatenanlage über den Einrichtungsassistenten

Stammdatenanlage über den Einrichtungsassistenten Stammdatenanlage über den Einrichtungsassistenten Schritt für Schritt zur fertig eingerichteten Hotelverwaltung mit dem Einrichtungsassistenten Bitte bereiten Sie sich, bevor Sie starten, mit der Checkliste

Mehr

Programmierkurs Java

Programmierkurs Java Programmierkurs Java Dr. Dietrich Boles Aufgaben zu UE16-Rekursion (Stand 09.12.2011) Aufgabe 1: Implementieren Sie in Java ein Programm, das solange einzelne Zeichen vom Terminal einliest, bis ein #-Zeichen

Mehr

In diesem Thema lernen wir die Grundlagen der Datenbanken kennen und werden diese lernen einzusetzen. Access. Die Grundlagen der Datenbanken.

In diesem Thema lernen wir die Grundlagen der Datenbanken kennen und werden diese lernen einzusetzen. Access. Die Grundlagen der Datenbanken. In diesem Thema lernen wir die Grundlagen der Datenbanken kennen und werden diese lernen einzusetzen. Access Die Grundlagen der Datenbanken kurspc15 Inhaltsverzeichnis Access... Fehler! Textmarke nicht

Mehr

Datenbanken für Online Untersuchungen

Datenbanken für Online Untersuchungen Datenbanken für Online Untersuchungen Im vorliegenden Text wird die Verwendung einer MySQL Datenbank für Online Untersuchungen beschrieben. Es wird davon ausgegangen, dass die Untersuchung aus mehreren

Mehr

Webalizer HOWTO. Stand: 18.06.2012

Webalizer HOWTO. Stand: 18.06.2012 Webalizer HOWTO Stand: 18.06.2012 Copyright 2003 by manitu. Alle Rechte vorbehalten. Alle verwendeten Bezeichnungen dienen lediglich der Kennzeichnung und können z.t. eingetragene Warenzeichen sein, ohne

Mehr

Arge Betriebsinformatik GmbH & Co.KG, CAP News 40, Februar 2013. CAP-News 40

Arge Betriebsinformatik GmbH & Co.KG, CAP News 40, Februar 2013. CAP-News 40 CAP-News 40 CAP-News ist in unrägelmäßigen Abständen erscheinende Information zum Produktkonfigurator CAP/VARIANTS. Hier werden die neuen Befehle, Funktionen und Möglichkeiten beschrieben. In CAP-News

Mehr

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang sysplus.ch outlook - mail-grundlagen Seite 1/8 Outlook Mail-Grundlagen Posteingang Es gibt verschiedene Möglichkeiten, um zum Posteingang zu gelangen. Man kann links im Outlook-Fenster auf die Schaltfläche

Mehr

Übersicht Programmablaufsteuerung

Übersicht Programmablaufsteuerung Übersicht Programmablaufsteuerung Konditionale Verzweigung: if - else switch-anweisung Schleifenkonstrukte: while, do - while for Schleife Sprung-Anweisungen: break, continue, goto, return Anweisungen

Mehr

Internationales Altkatholisches Laienforum

Internationales Altkatholisches Laienforum Internationales Altkatholisches Laienforum Schritt für Schritt Anleitung für die Einrichtung eines Accounts auf admin.laienforum.info Hier erklären wir, wie ein Account im registrierten Bereich eingerichtet

Mehr

11 Funktionen. 11.1 Vorteile von Funktionen. Leseprobe aus Access und SQL Server http://www.acciu.de/asqllesen

11 Funktionen. 11.1 Vorteile von Funktionen. Leseprobe aus Access und SQL Server http://www.acciu.de/asqllesen Leseprobe aus Access und SQL Server http://www.acciu.de/asqllesen 11 Funktionen Bestimmt enthält Ihre Access-Applikation einige VBA-Funktionen. Funktionen, in denen Sie wie derkehrende Funktionalität,

Mehr

Virtuelle COM-Schnittstelle umbenennen

Virtuelle COM-Schnittstelle umbenennen Virtuelle COM-Schnittstelle umbenennen COM-Nummer eines USB/Seriell-Wandlers verändern Wenn man ein Gerät mit einem USB/Seriell-Wandler neu anschließt, wird meist eine neue virtuelle COM- Schnittstelle

Mehr

Einführung in die Programmierung

Einführung in die Programmierung : Inhalt Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund - mit / ohne Parameter - mit / ohne Rückgabewerte

Mehr

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als

Mehr

Professionelle Seminare im Bereich MS-Office

Professionelle Seminare im Bereich MS-Office Der Name BEREICH.VERSCHIEBEN() ist etwas unglücklich gewählt. Man kann mit der Funktion Bereiche zwar verschieben, man kann Bereiche aber auch verkleinern oder vergrößern. Besser wäre es, die Funktion

Mehr

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank In den ersten beiden Abschnitten (rbanken1.pdf und rbanken2.pdf) haben wir uns mit am Ende mysql beschäftigt und kennengelernt, wie man

Mehr

Menü Macro. WinIBW2-Macros unter Windows7? Macros aufnehmen

Menü Macro. WinIBW2-Macros unter Windows7? Macros aufnehmen Menü Macro WinIBW2-Macros unter Windows7?... 1 Macros aufnehmen... 1 Menübefehle und Schaltflächen in Macros verwenden... 4 Macros bearbeiten... 4 Macros löschen... 5 Macro-Dateien... 5 Macros importieren...

Mehr

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Suche schlecht beschriftete Bilder mit Eigenen Abfragen Suche schlecht beschriftete Bilder mit Eigenen Abfragen Ist die Bilderdatenbank über einen längeren Zeitraum in Benutzung, so steigt die Wahrscheinlichkeit für schlecht beschriftete Bilder 1. Insbesondere

Mehr

SQL für Trolle. mag.e. Dienstag, 10.2.2009. Qt-Seminar

SQL für Trolle. mag.e. Dienstag, 10.2.2009. Qt-Seminar Qt-Seminar Dienstag, 10.2.2009 SQL ist......die Abkürzung für Structured Query Language (früher sequel für Structured English Query Language )...ein ISO und ANSI Standard (aktuell SQL:2008)...eine Befehls-

Mehr

104 WebUntis -Dokumentation

104 WebUntis -Dokumentation 104 WebUntis -Dokumentation 4.1.9.2 Das elektronische Klassenbuch im Betrieb Lehrer Aufruf Melden Sie sich mit Ihrem Benutzernamen und Ihrem Passwort am System an. Unter den aktuellen Tagesmeldungen erscheint

Mehr

affilinet_ Flash-Spezifikationen

affilinet_ Flash-Spezifikationen affilinet_ Flash-Spezifikationen Inhaltsverzeichnis Allgemeines...2 Klickzählung...2 Lead/Sale Programme... 2 PPC und Kombi Programme...3 Übergabe von Formulardaten...4 clicktag Variante Sale/Lead Programm...4

Mehr

Stand: 28.11.2012. Adressnummern ändern Modulbeschreibung

Stand: 28.11.2012. Adressnummern ändern Modulbeschreibung Seite 1 Inhalt Allgemein...3 Installation...3 manuelle Eingabe von alten und neuen Adressnummern...4 Vorbereiten von Adressnummern-Änderungen in Tabellen...5 Seite 2 Allgemein Das INKS-Modul ermöglicht

Mehr

SQL: statische Integrität

SQL: statische Integrität SQL: statische Integrität.1 SQL: statische Integrität Im allgemeinen sind nur solche Instanzen einer Datenbank erlaubt, deren Relationen die der Datenbank bekannten Integritätsbedingungen erfüllen. Integritätsbedingungen

Mehr

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Objektorientierte Programmierung für Anfänger am Beispiel PHP Objektorientierte Programmierung für Anfänger am Beispiel PHP Johannes Mittendorfer http://jmittendorfer.hostingsociety.com 19. August 2012 Abstract Dieses Dokument soll die Vorteile der objektorientierten

Mehr

Hinweise zum Übungsblatt Formatierung von Text:

Hinweise zum Übungsblatt Formatierung von Text: Hinweise zum Übungsblatt Formatierung von Text: Zu den Aufgaben 1 und 2: Als erstes markieren wir den Text den wir verändern wollen. Dazu benutzen wir die linke Maustaste. Wir positionieren den Mauszeiger

Mehr

Auf der linken Seite wählen Sie nun den Punkt Personen bearbeiten.

Auf der linken Seite wählen Sie nun den Punkt Personen bearbeiten. Personenverzeichnis Ab dem Wintersemester 2009/2010 wird das Personenverzeichnis für jeden Mitarbeiter / jede Mitarbeiterin mit einer Kennung zur Nutzung zentraler Dienste über das LSF-Portal druckbar

Mehr

Änderungen im Vertrags-Manager

Änderungen im Vertrags-Manager Änderungen im Vertrags-Manager 2009-01-27 Version 1.0.0.13... 2 2007-08-09 Version 1.0.0.12... 3 2007-07-25 Version 1.0.0.11... 4 2006-11-07 Version 1.0.0.10... 5 2006-09-27 Version 1.0.0.9... 7 2006-06-28

Mehr

Powerful PL/SQL: Collections indizieren mit VARCHAR2- Indizes ein Praxisbeispiel

Powerful PL/SQL: Collections indizieren mit VARCHAR2- Indizes ein Praxisbeispiel Powerful PL/SQL: Collections indizieren mit VARCHAR2- Indizes ein Praxisbeispiel Schlagworte Autor: Klaus Friemelt, MT AG dynamisches BULK SQL, VARCHAR2-indizierte PL/SQL-Tabellen Einleitung Mit den letzten

Mehr

SRM - Ausschreibung (Lieferant)

SRM - Ausschreibung (Lieferant) Inhalt 0. Systemlandschaft 2 1. Benachrichtigung über neue Ausschreibungen 2 2. Anmeldung am Lieferantenportal 2 3. Ausschreibung bearbeiten 3 3.1 Übersicht über alle Ausschreibungen 3 3.2 Teilnahme avisieren

Mehr

Kundenspezifische Preise im Shop WyRu Online-Shop

Kundenspezifische Preise im Shop WyRu Online-Shop Kundenspezifische Preise im Shop WyRu Online-Shop Team WyRu Christian Wyk / Günter Rubik SCS Bürocenter B1, A-2334 Vösendorf Internet http://www.wyru.at Kundenspezifische Preise sind ein Feature des WyRu

Mehr

2. Datenbank-Programmierung

2. Datenbank-Programmierung 2. Datenbank-Programmierung SQL ist eingeschränkt bezüglich der algorithmischen Mächtigkeit, z.b. Berechnung einer transitiven Hülle ist in Standard-SQL nicht möglich. Die Einschränkung ist von Bedeutung

Mehr

Suchmaschinen. Universität Augsburg, Institut für Informatik SS 2014 Prof. Dr. W. Kießling 23. Mai 2014 Dr. M. Endres, F. Wenzel Lösungsblatt 6

Suchmaschinen. Universität Augsburg, Institut für Informatik SS 2014 Prof. Dr. W. Kießling 23. Mai 2014 Dr. M. Endres, F. Wenzel Lösungsblatt 6 Universität Augsburg, Institut für Informatik SS 2014 Prof. Dr. W. Kießling 23. Mai 2014 Dr. M. Endres, F. Wenzel Lösungsblatt 6 Aufgabe 1: Pareto mit SV-Semantik Suchmaschinen Pareto Definition: x < P

Mehr

2.5.2 Primärschlüssel

2.5.2 Primärschlüssel Relationale Datenbanken 0110 01101110 01110 0110 0110 0110 01101 011 01110 0110 010 011011011 0110 01111010 01101 011011 0110 01 01110 011011101 01101 0110 010 010 0110 011011101 0101 0110 010 010 01 01101110

Mehr

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1 Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1 Wenn der Name nicht gerade www.buch.de oder www.bmw.de heißt, sind Internetadressen oft schwer zu merken Deshalb ist es sinnvoll, die Adressen

Mehr

4 Aufzählungen und Listen erstellen

4 Aufzählungen und Listen erstellen 4 4 Aufzählungen und Listen erstellen Beim Strukturieren von Dokumenten und Inhalten stellen Listen und Aufzählungen wichtige Werkzeuge dar. Mit ihnen lässt sich so ziemlich alles sortieren, was auf einer

Mehr

Programmieren in C. Felder, Schleifen und Fließkommaarithmetik. Prof. Dr. Nikolaus Wulff

Programmieren in C. Felder, Schleifen und Fließkommaarithmetik. Prof. Dr. Nikolaus Wulff Programmieren in C Felder, Schleifen und Fließkommaarithmetik Prof. Dr. Nikolaus Wulff Addition von Zahlen 1 2 3 4 5 #include int main() { int x,y,z,sum; x = 1; y = 2; z = 4; sum = x + y + z;

Mehr

Textgestaltung mit dem Editor TinyMCE Schritt für Schritt

Textgestaltung mit dem Editor TinyMCE Schritt für Schritt Textgestaltung mit dem Editor TinyMCE Schritt für Schritt Folgender Artikel soll veröffentlicht und mit dem Editor TinyMCE gestaltet werden: Eine große Überschrift Ein Foto Hier kommt viel Text. Hier kommt

Mehr

Programme im Griff Was bringt Ihnen dieses Kapitel?

Programme im Griff Was bringt Ihnen dieses Kapitel? 3-8272-5838-3 Windows Me 2 Programme im Griff Was bringt Ihnen dieses Kapitel? Wenn Sie unter Windows arbeiten (z.b. einen Brief schreiben, etwas ausdrucken oder ein Fenster öffnen), steckt letztendlich

Mehr

Die besten Excel-Tastenkombinationen im Überblick

Die besten Excel-Tastenkombinationen im Überblick Die besten Excel-Tastenkombinationen im Überblick Erfahrungsgemäß sind es nicht unbedingt die umfangreichen Tipps, die den Nutzen haben. So kann dir häufig schon eine kleine Hilfe bei der täglichen Arbeit

Mehr

1.4.12 Sin-Funktion vgl. Cos-Funktion

1.4.12 Sin-Funktion vgl. Cos-Funktion .4. Sgn-Funktion Informatik. Semester 36 36.4.2 Sin-Funktion vgl. Cos-Funktion Informatik. Semester 37 37 .4.3 Sqr-Funktion Informatik. Semester 38 38.4.4 Tan-Funktion Informatik. Semester 39 39 .5 Konstanten

Mehr

DYNAMISCHE SEITEN. Warum Scriptsprachen? Stand: 11.04.2005. CF Carola Fichtner Web-Consulting http://www.carola-fichtner.de

DYNAMISCHE SEITEN. Warum Scriptsprachen? Stand: 11.04.2005. CF Carola Fichtner Web-Consulting http://www.carola-fichtner.de DYNAMISCHE SEITEN Warum Scriptsprachen? Stand: 11.04.2005 CF Carola Fichtner Web-Consulting http://www.carola-fichtner.de I N H A L T 1 Warum dynamische Seiten?... 3 1.1 Einführung... 3 1.2 HTML Seiten...

Mehr

5. Tutorium zu Programmieren

5. Tutorium zu Programmieren 5. Tutorium zu Programmieren Dennis Ewert Gruppe 6 Universität Karlsruhe Institut für Programmstrukturen und Datenorganisation (IPD) Lehrstuhl Programmierparadigmen WS 2008/2009 c 2008 by IPD Snelting

Mehr

Zahlen auf einen Blick

Zahlen auf einen Blick Zahlen auf einen Blick Nicht ohne Grund heißt es: Ein Bild sagt mehr als 1000 Worte. Die meisten Menschen nehmen Informationen schneller auf und behalten diese eher, wenn sie als Schaubild dargeboten werden.

Mehr

Modellierung und Programmierung 1

Modellierung und Programmierung 1 Modellierung und Programmierung 1 Prof. Dr. Sonja Prohaska Computational EvoDevo Group Institut für Informatik Universität Leipzig 19. November 2015 Gültigkeitsbereich (Scope) von Variablen { int m; {

Mehr

Dokument Lob erstellen

Dokument Lob erstellen Dokument Lob erstellen Vorbemerkung Ein Lob wird immer mit einem Abschlusszeugnis ausgestellt und auch mit diesem Verteilt. Um ein Lob zu dokumentieren müssen folgende Bausteine definiert und eingerichtet

Mehr

Erstellen von x-y-diagrammen in OpenOffice.calc

Erstellen von x-y-diagrammen in OpenOffice.calc Erstellen von x-y-diagrammen in OpenOffice.calc In dieser kleinen Anleitung geht es nur darum, aus einer bestehenden Tabelle ein x-y-diagramm zu erzeugen. D.h. es müssen in der Tabelle mindestens zwei

Mehr