PL/SQL- Funktionen von. SQL aus aufrufen. Das Problem. In diesem Kapitel: Das Problem

Größe: px
Ab Seite anzeigen:

Download "PL/SQL- Funktionen von. SQL aus aufrufen. Das Problem. In diesem Kapitel: Das Problem"

Transkript

1 In diesem Kapitel: Das Problem Die Syntax für den Aufruf gespeicherter Funktionen in SQL Bedingungen an gespeicherte Funktionen in SQL Einschränkungen von PL/SQL-Funktionen in SQL Funktionen in Packages von SQL aus aufrufen Die Präzedenz von Spaltenund Funktionsnamen Die rauhe Wirklichkeit: PL/SQL-Funktionen in SQL aufrufen Beispiele eingebetteten PL/SQL-Codes 17 PL/SQL- Funktionen von SQL aus aufrufen PL/SQL ist eine prozedurale Spracherweiterung zu SQL. Daher können Sie aus Ihren PL/SQL-Programmen auch native SQL-Anweisungen wie SELECT, INSERT oder UPDATE aufrufen. Bis zur Version 2.1 von PL/SQL (die zur Oracle-Datenbank 7.1 gehört) konnten Sie allerdings keine eigenen PL/SQL-Funktionen in einer SQL-Anweisung verwenden. HINWE Die in diesem Kapitel beschriebenen Möglichkeiten stehen erst ab PL/SQL Version 2.1 zur Verfügung. Das Problem Die fehlende Möglichkeit, PL/SQL-Funktionen in SQL-Anweisungen verwenden zu können, führte oft zu häßlichen SQL-Anweisungen und redundanten Implementierungen von Geschäftsregeln. Nehmen wir beispielsweise an, Sie müssen das Gesamtgehalt eines Mitarbeiters sowohl in nativem SQL als auch in Ihren Formularen berechnen. Die Berechnung selbst ist einfach genug: Total compensation = salary + bonus Meine SQL-Anweisung würde diese Formel enthalten SELECT employee_name, salary + NVL (bonus, 0) FROM employee; 579

2 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen während mein Post-Query-Trigger in meiner Oracle Forms-Anwendung den folgenden PL/SQL-Code verwenden würde: :employee.total_comp := :employee.salary + NVL (:employee.bonus, 0); In diesem Fall ist die Berechnung sehr einfach, aber trotzdem müssen Sie all diese hartkodierten Berechnungen sowohl in den SQL-Anweisungen als auch in den Anwendungskomponenten im Frontend einzeln ändern, wenn sich die Formel zur Berechnung des Gesamtgehalts aus irgendeinem Grunde ändern sollte. Sehr viel besser ist es, eine Funktion zu schreiben, die das Gesamtgehalt zurückgibt: FUNCTION total_comp (salary_in IN employee.salary%type, bonus_in IN employee.bonus%type) RETURN NUMBER BEGIN RETURN salary_in + NVL (bonus_in, 0); END; Diese Formel kann ich dann folgendermaßen in meinem Code einsetzen: SELECT employee_name, total_comp (salary, bonus) FROM employee; :employee.total_comp := total_comp (:employee.salary, :employee.bonus); Vor der Version 2.1 von PL/SQL führte das zu folgendem Fehler ORA-00919: invalid function weil es in SQL keinen Mechanismus gab, Referenzen auf in der Datenbank abgespeicherte, vom Programmierer definierte Funktionen aufzulösen. Inzwischen ist die Verbindung zwischen PL/SQL und SQL aber ausgeglichener. Das ist auch sinnvoll so, denn die Funktionen werden ohnehin in der Datenbank abgelegt (wie nicht anders zu erwarten, in einer Tabelle) und stehen daher der SQL-Schicht über eine SELECT-Anweisung zur Verfügung. Seit der Version 2.1 von PL/SQL können Sie jetzt an jeder Stelle in einer SQL-Anweisung, in der ein Ausdruck erlaubt ist, gespeicherte Funktionen aufrufen, darunter in den SELECT-, WHERE-, START WITH-, GROUP BY-, HAVING-, ORDER BY-, SET- und VALUES-Klauseln (weil gespeicherte Prozeduren selbst ausführbare PL/SQL-Anweisungen sind, können diese nicht in eine SQL-Anweisung eingebettet werden). Sie können Ihre eigenen Funktionen genauso wie die Built-in- SQL-Funktionen wie etwa TO_DATE, SUBSTR oder LENGTH verwenden. Auf der Begleitdiskette ist ein Package namens ps.parse (bestehend aus den Dateien psparse.sps und psparse.spb) enthalten, in dem es eine Funktion gibt, welche die Anzahl der Atome (Worte und/oder Begrenzungszeichen) in einem String zurückgibt. Das kann ich direkt in einer SQL-Anweisung verwenden, um die Verteilung der Worte in einer Reihe von Textnotizen anzuzeigen: 580

3 Das Problem SELECT line_number, ps_parse.number_of_atomics (line_text) AS num_words FROM notes ORDER BY num_words DESC; Beachten Sie, daß ich in diesem Fall dem Funktionsaufruf mit der»as«-syntax einen Spaltenalias zugewiesen habe. Diesen kann ich dann in ORDER BY verwenden, ohne die Syntax des Funktionsaufrufs selbst erneut angeben zu müssen. Die Möglichkeit, programmiererdefinierte PL/SQL-Funktionen in SQL zu verwenden, ist eine sehr mächtige Erweiterung der Oracle-Entwicklungsumgebung. Mit diesen Funktionen können Sie folgendes tun: Die Logik von Geschäftsregeln in einer kleinen Anzahl optimierter und leicht wartbarer Funktionen zusammenfassen. Sie müssen diese Logik nicht über die einzelnen SQL-Anweisungen und PL/SQL-Programme verteilen. Dieser Punkt ist wahrscheinlich der weitreichendste und wichtigste Vorteil bei der Verwendung von Funktionen. Die Performanz Ihrer SQL-Anweisungen verbessern. SQL ist eine nichtprozedurale Sprache, aber die Anforderungen der Anwendung bedingen doch oft prozedurale Logik in Ihrem SQL-Code. SQL ist robust genug, so daß Sie immer irgendwie an die Antwort kommen können, aber in manchen Situationen ist das zu ineffizient. Eingebettetes PL/SQL kann den Job manchmal schneller erledigen. Natürlich kostet es auch ein wenig, diese Funktionen aufzurufen, weswegen Sie sorgfältig abwägen und ausprobieren müssen, wo und wann PL/SQL-Funktionen in SQL am meisten nützen. Ihre SQL-Anweisungen vereinfachen. All die Gründe, aus denen sie PL/SQL-Code verwenden sollten, gelten auch für SQL, insbesondere wenn es darum geht, komplizierte Ausdrücke und komplizierte Logik hinter einer Funktionsspezifikation zu verstecken. Von der DECODE-Anweisung bis zu verschachtelten, korrelierten Subselects können programmiererdefinierte Funktionen die Lesbarkeit vieler SQL- Anweisungen verbessern. Aktionen in SQL durchführen, die sonst unmöglich wären. SQL ist eine Sprache, die immer eine Menge zur Zeit bearbeitet, die aus Zeilen besteht, auf die dann irgendwelche Aktionen angewendet werden. Iterative Verarbeitung über einzelne Spaltenwerte ist nicht möglich. Wenn Sie beispielsweise die Anzahl der Vorkommnisse eines Substrings in den Namen von Firmen ermitteln wollen, dann geht das mit reinem SQL nicht. Sie können aber in einer SELECT-Liste eine PL/SQL-Funktion über den Firmennamen laufen lassen, der diese Art von iterativer Verarbeitung durchführen kann. Sie können Funktionen in einer VALUES-Liste, einer SET-Klausel oder einer GROUP BY-Klausel verwenden. Hier folgen ein paar Beispiele dazu: VALUES-Liste. Schauen Sie sich das folgende Beispiel an: INSERT INTO notes (call_id, line_text, line_number) 581

4 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen VALUES (:call.call_id, :note.text, next_line_number (:call.call_id)); Die Funktion next_line_number holt die nächste laufende Nummer der Notizen zu diesem Vorfall (Sie könnten zwar einen Folgenummerngenerator verwenden, um die nächste eindeutige Vorfallnummer zu erhalten, aber die line_number für Notizen fängt immer wieder bei 1 an, so daß man hier keinen Folgenummerngenerator verwenden kann). SET-Klausel. Die Funktion max_compensation gibt das höchstmögliche Gehalt in der Abteilung eines Angestellten wieder. UPDATE employee SET salary = max_compensation (department_id) WHERE employee_id = 1005; In diesem Fall ersetzt die Funktion max_compensation ein Subselect, das die Funktion AVG verwenden würde, um den Wert zu berechnen. GROUP BY-Klausel. Meine Firma hat die Vereinheitlichung der Titel nicht besonders gut hinbekommen; es gibt 15 verschiedene Versionen von stellvertretenden Geschäftsführern, 20 verschiedene Manager usw. Die folgende SELECT-Anweisung räumt mit dieser Verwirrung auf und zeigt das Gesamtgehalt für jede Job-»Kategorie«an. SELECT job_category (job_title_id) as title, SUM (salary) FROM employee GROUP BY title; Die Funktion wird sowohl in der SELECT-Liste als auch in der GROUP BY-Klausel verwendet. Die Syntax für den Aufruf gespeicherter Funktionen in SQL Eine gespeicherte Funktion wird aus einem SQL-Ausdruck mit der gleichen Syntax wie in einem PL/SQL-Ausdruck aufgerufen: [schema_name.][package_name.][funktions_name[@db_link_name][parameter_liste] Hierbei ist schema_name der optionale Name des Datenbankschemas, in dem die Funktion definiert ist (üblicherweise Ihr Oracle-Benutzerkonto), Package_name ist der optionale Name des Packages, in dem die Funktion definiert ist (wenn es sich nicht um eine freistehende Funktion handelt), funktions_name ist der Name der Funktion, db_link_name ist der optionale Name der Datenbankverbindung, wenn Sie einen entfernten Prozeduraufruf (remote procedure call) ausführen, und parameter_liste ist die optionale Liste der Parameter der Funktion. Wenn die Funktion calc_sales folgendermaßen definiert ist 582

5 Bedingungen an gespeicherte Funktionen in SQL FUNCTION calc_sales (company_id_in IN company.company_id%type, status_in IN order.status_code%type := NULL) RETURN NUMBER; dann kann diese Funktion von SQL aus wie folgt aufgerufen werden: Als freistehende Funktion: SELECT calc_sales (1001, 'O') FROM orders; Als Funktion in einem Package: SELECT sales_pkg.calc_sales (1001, 'O') FROM orders; Als entfernter Aufruf einer Funktion in einem Package: SELECT (1001, 'O') FROM orders; Als freistehende Funktion in einem bestimmten Schema: SELECT scott.calc_sales (1001, 'O') FROM orders; SQL kann all diese Variationen korrekt parsen, aber Sie sollten es vermeiden, das Schema des Moduls und die Datenbankverbindung in Ihren SQL-Anweisungen hart zu kodieren (wie es im dritten und vierten Punkt gemacht wurde). Statt dessen sollten Sie Synonyme dafür anlegen, die diese Information verstecken. Damit müssen Sie nur das Synonym ändern, und nicht alle einzelnen SQL-Anweisungen, die diese Funktion aufrufen, wenn Sie jemals den Eigentümer der Funktion ändern oder zu einer anderen Datenbankinstanz wechseln sollten. Wenn Sie eine gespeicherte Funktion in einer SQL-Anweisung verwenden, dann müssen Sie die Zuordnung über Positionen verwenden, das Mischen der Zuordnung über den Namen und über die Position ist nicht erlaubt. Sie können calc_sales nur durch Angabe der beiden Argumente in der richtigen Reihenfolge aufrufen. Bedingungen an gespeicherte Funktionen in SQL Es gibt eine Reihe von Bedingungen, die eine programmiererdefinierte PL/SQL-Funktion erfüllen muß, damit sie von einer SQL-Anweisung aus aufgerufen werden kann. Die Funktion muß in der Datenbank gespeichert sein. Eine Funktion, die in einer PL/SQL-Bibliothek von Oracle Developer/2000 oder einem einzelnen Formular gespeichert ist, kann nicht von SQL aus aufgerufen werden. SQL hat keine Möglichkeit, die Referenz auf eine solche Funktion aufzulösen. 583

6 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen Die Funktion muß eine zeilenspezifische Funktion sein, keine Spalten- oder Gruppenfunktion. Die Funktion kann nur auf eine einzelne Zeile mit Daten angewendet werden, nicht auf eine gesamte Spalte, die sich über mehrere Zeilen erstreckt. Alle Funktionsparameter müssen den IN-Modus verwenden. Weder IN OUT- noch OUT-Parameter sind in gespeicherten Funktionen erlaubt, die von SQL aus aufgerufen werden sollen; aber Sie sollten ohnehin nie IN OUT- oder OUT-Parameter in Funktionen verwenden. Egal ob Sie die Funktion in einer SQL-Anweisung verwenden oder nicht, erzeugen solche Parameter Seiteneffekte zusätzlich zum Hauptzweck der Funktion, der ja die Rückgabe eines einzigen Wertes ist. Die Datentypen der Parameter der Funktion wie auch der Datentyp der RETURN- Klausel müssen Oracle Server bekannt sein. Während alle Datentypen von Oracle Server in PL/SQL gültig sind, hat PL/SQL neue Datentypen hinzugefügt, die von der Datenbank (noch) nicht unterstützt werden. Zu diesen Datentypen gehören BOO- LEAN, BINARY_INTEGER, PL/SQL-Tabellen, PL/SQL-Datensätze und programmiererdefinierte Subtypen. Funktionen, die in Packages definiert sind, müssen das Pragma RESTRICT_ REFERENCES verwenden. Wenn Sie von SQL aus eine in einem Package definierte Funktion aufrufen wollen, müssen Sie der Package-Spezifikation ein Pragma hinzufügen, das explizit angibt, daß diese Funktion zur Ausführung aus SQL-Anweisungen heraus zugelassen ist. Der Abschnitt»Funktionen in Packages von PL/SQL aus aufrufen«enthält nähere Informationen hierzu. Die folgenden Funktionsspezifikationen würden zurückgewiesen werden, wenn sie in einer SQL-Anweisung verwendet würden: /* SQL weiss nichts ueber PL/SQL-Tabellen */ TYPE string_tabtype TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; FUNCTION temp_table RETURN string_tabtype; /* SQL weiss nichts ueber Boolesche Werte */ FUNCTION call_is_open (call_id_in IN call.call_id%type) RETURN BOOLEAN; FUNCTION calc_sales (company_id_in IN NUMBER, use_closed_orders_in IN BOOLEAN) RETURN NUMBER; Einschränkungen von PL/SQL-Funktionen in SQL Gespeicherte Funktionen in SQL sind sehr mächtig. Aber Sie können sich vielleicht denken, daß diese Mächtigkeit auch die Möglichkeit zum Mißbrauch und die Notwendigkeit verantwortungsvollen Handelns mit sich bringt. Im Zusammenhang mit SQL besteht der Mißbrauch in der Verwendung von Seiteneffekten in einer Funktion. Schauen Sie sich die folgende Funktion an: 584

7 Einschränkungen von PL/SQL-Funktionen in SQL FUNCTION total_comp (salary_in IN employee.salary%type, bonus_in IN employee.bonus%type) RETURN NUMBER BEGIN UPDATE employee SET salary = salary_in / 2; RETURN salary_in + NVL (bonus_in, 0); END; Diese kleine Berechnung, die ich am Anfang des Kapitels schon eingeführt hatte, aktualisiert das Gehalt aller Mitarbeiter auf die Hälfte des angegebenen Wertes. Dieser Vorgang beeinflußt die Ergebnisse der Abfrage, aus der total_comp aufgerufen werden könnte, aber schlimmer noch, er beeinflußt alle anderen SQL-Anweisungen in dieser Sitzung. Neben der Modifikation von Datenbanktabellen ist die Modifikation von Package-Variablen ein anderer Seiteneffekt von gespeicherten Funktionen in SQL. Package-Variablen dienen in der jeweiligen Sitzung als globale Variablen. Eine Funktion, die eine Package- Variable verändert, könnte andere gespeicherte Funktionen oder Prozeduren beeinflussen, was wiederum die SQL-Anweisung beeinflußt, welche die gespeicherte Funktion verwendet. Eine PL/SQL-Funktion könnte auch einen Seiteneffekt in der WHERE-Klausel einer Abfrage verursachen. Der Anfrageoptimierer kann die Reihenfolge der Prädikate in der WHERE-Klausel umstellen, um die Anzahl der zu verarbeitenden Zeilen zu minimieren. Eine Funktion, die in dieser Klausel ausgeführt wird, könnte also den Optimierungsprozeß der Anfrage unterlaufen. Ich würde ganz allgemein empfehlen, daß die Funktion sich ganz eng darauf beschränken sollte, einen Wert zu berechnen und zurückzugeben. Aber eine Empfehlung ist nicht genug, wenn es um die Integrität der Datenbank geht: Um sich gegen häßliche Seiteneffekte und unvorhersagbares Verhalten zu schützen, läßt der Oracle Server die folgenden Aktionen in Ihren gespeicherten Funktionen nicht zu: Die gespeicherte Funktion darf keine Datenbanktabellen verändern. Sie kann keine INSERT-, DELETE- oder UPDATE-Anweisung ausführen. Eine gespeicherte Funktion, die entfernt oder parallelisiert aufgerufen wird, darf weder lesend noch schreibend auf Package-Variablen zugreifen. Der Oracle Server erlaubt keine Seiteneffekte, welche die Grenzen der aktuellen Benutzersitzung überschreiten. Eine gespeicherte Funktion kann die Werte von Package-Variablen nur dann ändern, wenn diese Funktion in einer SELECT-, VALUES- und SET-Klausel aufgerufen wird. Wenn diese Funktion in einer WHERE- oder GROUP BY-Klausel aufgerufen wird, kann sie keine Package-Variablen beschreiben. Vor Oracle 8 konnten Sie nur sehr wenige Programme in Built-in Packages in einer von SQL aus verwendeten Funktion aufrufen. Zu den verbotenen Programmen bzw. Packages gehörten beispielsweise DBMS_OUTPUT.PUT_LINE, DBMS_PIPE und 585

8 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen DBMS_SQL, um nur einige zu nennen. Das ist auch manchmal ganz gut so. Wenn Sie keine UPDATE-Anweisung ausführen dürfen, sollten Sie auch nicht über DBMS_SQL eine UPDATE-Operation»an der Zensur«vorbei einschleusen dürfen. Aber bei einigen anderen Packages sind diese Einschränkungen unnötig und nur vorhanden gewesen, weil Oracle diese Programme nicht aktiviert hatte. In Oracle8 wurden einige dieser Einschränkungen aufgehoben. Sie können jetzt DBMS_ OUTPUT.PUT_LINE aus einer von SQL aus aufgerufenen Funktion aufrufen und sogar Informationen durch Datenbank-Pipes schicken. 1 Vor Oracle8 konnten Sie RAE_APPLICATION_ERROR nicht aus einer gespeicherten Funktion aufrufen. In Oracle Server 7.3 können Sie keine PL/SQL-Tabellenmethoden (COUNT, FIRST, LAST, NEXT, PRIOR usw.) in einer gespeicherten Funktion verwenden, die von SQL aus verwendet wird (das ist ein»bekannter Bug«, der in Oracle8 behoben wurde). Beispielsweise kann eine Funktion, die den folgenden Code enthält, in SQL nicht verwendet werden: DECLARE TYPE emptabtype TABLE of emp%rowtype INDEX BY BINARY_INTEGER; emptab emptabtype; BEGIN IF emptab.count > 0 THEN -- Wird in SQL zurueckgewiesen Die gespeicherte Funktion darf kein anderes Modul (gespeicherte Prozedur oder Funktion) verwenden, das eine der obigen Regeln verletzt. Eine Funktion ist nur so rein wie alle Module, die sie selber aufruft. Die gespeicherte Funktion darf keine Sicht verwenden, die eine der obigen Regeln verletzt. Eine Sicht ist eine gespeicherte SELECT-Anweisung; die SELECT-Anweisung der Sicht kann gespeicherte Funktionen verwenden. Wenn Ihre Funktion gegen eine dieser Regeln verstößt oder eine Funktion aus einem Package ist, in dem das Pragma RESTRICT_REFERENCES fehlt, bekommen Sie den gefürchteten Fehler ORA-06571: ORA-06571: Function TOTAL_COMP does not guarantee not to update database Wie im Abschnitt»Die rauhe Wirklichkeit: PL/SQL-Funktionen in SQL aufrufen«erwähnt, kann es manchmal sehr schwierig (oder schlichtweg unmöglich) sein, diesen Fehler zu vermeiden. In anderen Situationen gibt es aber einfache Lösungen (schauen Sie aber auf jeden Fall durch die obige Liste der Beschränkungen). 1 Mein Buch Oracle Built-In Packages, 1998, O Reilly & Associates, enthält eine umfassende Besprechung der Funktionen aus Packages, die von SQL aus verwendet werden können. 586

9 Funktionen in Packages von SQL aus aufrufen Funktionen in Packages von SQL aus aufrufen Wie in Kapitel 16, Packages, beschrieben, sind die Spezifikation und der Rumpf eines Packages getrennt voneinander; eine Spezifikation kann (und muß) existieren, bevor der Rumpf definiert wird. Dieses Feature von Packages macht das Leben schwieriger, wenn es darum geht, Funktionen von SQL aus aufzurufen. Wenn eine SELECT-Anweisung eine Funktion aus einem Package aufruft, dann ist nur die Information aus der Spezifikation des Packages verfügbar. Andererseits ist es aber der Inhalt des Package- Rumpfes, der festlegt, ob eine Funktion von SQL aus ausgeführt werden darf. Als Konsequenz aus dieser Situation ergibt sich, daß Sie Code zu Ihrer Package-Spezifikation hinzufügen müssen, um eine Funktion aus einem Package von SQL aus aufrufbar zu machen. Man spricht davon, daß Sie den»reinheitsgrad«einer gespeicherten Funktion (der Grad, in dem die Funktion frei von Seiteneffekten ist) in der Package-Spezifikation»zusichern«müssen (assert the purity level). Der Oracle Server kann damit beim Kompilieren des Package-Rumpfes bestimmen, ob die Funktion diesen»reinheitsgrad«erfüllt oder nicht. Erfüllt sie ihn nicht, wird ein Fehler gemeldet, und Sie stehen der manchmal gewaltigen Aufgabe gegenüber, herauszufinden, wo und wie diese Verletzung vorkommt. Die Zusicherung des Reinheitsgrades einer Funktion geschieht mit dem Pragma RESTRICT_REFERENCES, das wir uns im nächsten Abschnitt ansehen werden. Das Pragma RESTRICT_REFERENCES Wie ich bereits erwähnt habe, ist ein Pragma eine Direktive für den PL/SQL-Compiler. Wenn Sie jemals eine programmiererdefinierte, benannte Ausnahme verwendet haben, dann sind Sie Ihrem ersten Pragma schon über den Weg gelaufen. Im Falle des Pragmas RESTRICT_REFERENCES teilen Sie dem Compiler den Reinheitsgrad mit, von dem Sie glauben, daß ihn Ihre Funktion mindestens erreicht. Jede Funktion im Package, die Sie in einer SQL-Anweisung verwenden wollen, benötigt ein eigenes Pragma, das nach der Funktionsdeklaration in der Package-Spezifikation stehen muß (im Package-Rumpf muß das Pragma dagegen nicht angegeben werden). Um den Reinheitsgrad mit dem Pragma zuzusichern, verwenden Sie die folgende Syntax: PRAGMA RESTRICT_REFERENCES (funktions_name, WNDS [, WNPS] [, RNDS] [, RNPS]) Hierbei ist funktions_name der Name der Funktion, deren Reinheitsgrad Sie zusichern wollen. Die vier verschiedenen Codes haben die folgenden Bedeutungen: WNDS Writes No Database State. Sichert zu, daß die Funktion keine Datenbanktabellen verändert. WNPS Writes No Package State. Sichert zu, daß die Funktion keine Package-Variablen verändert. 587

10 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen RNDS Reads No Database State. Sichert zu, daß die Funktion nicht aus Datenbanktabellen liest. RNPS Reads No Package State. Sichert zu, daß die Funktion nicht aus Package-Variablen liest. Nur WNDS muß im Pragma stehen. Das ist auch konsistent mit der Beschränkung, daß gespeicherte Funktionen in SQL keine UPDATE-, INSERT- oder DELETE-Anweisung ausführen dürfen. Alle anderen Zusicherungen sind optional. Sie können Sie in beliebiger Reihenfolge aufführen, aber WNDS muß immer dabei sein. Kein Argument folgt aus einem der anderen. Ich kann in die Datenbank schreiben, ohne aus ihr zu lesen, und aus einer Package-Variable lesen, ohne darauf zu schreiben. Hier ein Beispiel für zwei verschiedene Zusicherungen der Reinheit von Funktionen im Package company_financials: PACKAGE company_financials FUNCTION company_type (type_code_in IN VARCHAR2) RETURN VARCHAR2; FUNCTION company_name (company_id_in IN company.company_id%type) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES (company_type, WNDS, RNDS, WNPS, RNPS); PRAGMA RESTRICT_REFERENCES (company_name, WNDS, WNPS, RNPS); END company_financials; In diesem Package liest die Funktion company_name aus der Datenbank, um den Namen der angegebenen Firma zu ermitteln. Beachten Sie, daß ich beide Pragmas an das Ende der Package-Spezifikation gestellt habe, die Pragmas müssen den Funktionsspezifikationen nicht unmittelbar folgen. Ich habe mir außerdem die Mühe gemacht, die Argumente WNPS und RNPS bei beiden Funktionen anzugeben. Oracle Corporation empfiehlt, immer den höchstmöglichen Reinheitsgrad anzugeben, so daß der Compiler die Funktion nie unnötig zurückweist. HINWE Wenn eine Funktion, die Sie von SQL aus aufrufen wollen, eine Prozedur in einem Package aufruft, dann muß auch für diese Prozedur das Pragma RESTRICT_ REFERENCES angegeben werden. Sie können die Prozedur zwar nicht direkt von SQL aus aufrufen, aber wenn sie indirekt von SQL aufgerufen werden soll, dann muß sie sich ebenfalls an die Regeln halten. Fehler bei Pragmaverstößen Wenn Ihre Funktion gegen ihr Pragma verstößt, wird der Fehler PLS gemeldet. Wenn der Rumpf des Packages company_financials folgendermaßen aussieht 588

11 Funktionen in Packages von SQL aus aufrufen CREATE OR REPLACE PACKAGE BODY company_financials FUNCTION company_type (type_code_in IN VARCHAR2) RETURN VARCHAR2 v_sal NUMBER; BEGIN SELECT sal INTO v_sal FROM emp WHERE empno = 1; RETURN 'bigone'; END; FUNCTION company_name (company_id_in IN company.company_id%type) RETURN VARCHAR2 BEGIN UPDATE emp SET sal = 0; RETURN 'bigone'; END; END company_financials; / dann bekomme ich beim Kompilieren den folgenden Fehler: 3/4 PLS-00452: Subprogram 'COMPANY_TYPE' violates its associated pragma Der Grund dafür ist, daß die Funktion company_type aus der Datenbank liest, obwohl ich den Reinheitsgrad RNDS angegeben habe. Auch wenn ich diese dumme SELECT- Anweisung entferne, bekomme ich immer noch den folgenden Fehler 11/4 PLS-00452: Subprogram 'COMPANY_NAME' violates its associated pragma weil die Funktion company_name die Daten in der Datenbank aktualisiert, obwohl ich WNDS angegeben habe. Manchmal werden Sie auf Ihre Funktion starren und sagen,»he, diesmal verletzte ich den angegebenen Reinheitsgrad wirklich nicht. Hier ist ja gar kein UPDATE, DELETE oder INSERT«. Vielleicht haben Sie recht. Aber es ist nicht unwahrscheinlich, daß Sie ein Built-in Package aufgerufen oder auf andere Weise gegen die Regeln verstoßen haben. Zusichern des Reinheitsgrades im Initialisierungsabschnitt des Packages Wenn Ihr Package einen Initialisierungsabschnitt (ausführbare Anweisungen nach einer BEGIN-Anweisung im Package-Rumpf) enthält, dann müssen Sie auch den Reinheitsgrad dieses Abschnitts zusichern. Der Initialisierungsabschnitt wird automatisch ausgeführt, wenn das erste Mal auf ein Objekt aus dem Package zugegriffen wird. Wenn eine Funktion aus einem solchen Package also in einer SQL-Anweisung ausgeführt wird, kann sie die Ausführung dieses Codes bewirken. Wenn der Initialisierungsabschnitt Package-Variablen oder Daten in der Datenbank modifiziert, dann muß dies dem Compiler über das Pragma mitgeteilt werden. 589

12 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen Sie können den Reinheitsgrad des Initialisierungsabschnitts entweder explizit oder implizit zusichern. Für die explizite Zusicherung verwenden Sie die folgende Variation des Pragmas RESTRICT_REFERENCES: PRAGMA RESTRICT_REFERENCES (Package_name, WNDS, [, WNPS] [, RNDS] [, RNPS]) Anstelle des Namens der Funktion geben Sie hier den Namen des Packages selbst an, worauf wieder die Zustandsargumente folgen. Im folgenden Beispiel sichere ich nur WNDS und WNPS zu, weil der Initialisierungsabschnitt Daten aus der Konfigurationstabelle und aus einer globalen Variable eines anderen Packages (session_pkg. user_id) liest. PACKAGE configure PRAGMA RESTRICT_REFERENCES (configure, WNDS, WNPS); user_name VARCHAR2(100); END configure; PACKAGE BODY configure BEGIN SELECT lname ', ' fname INTO user_name FROM user_table WHERE user_id = session_pkg.user_id; END configure; Warum kann ich hier WNPS zusichern, obwohl ich die Package-Variable user_name beschreibe? Die Antwort ist, daß es sich um eine Variable aus dem gleichen Package handelt, weswegen diese Aktion nicht als Seiteneffekt zählt. Sie können den Reinheitsgrad des Initialisierungsabschnitts des Packages auch implizit zusichern, indem Sie den Compiler den Reinheitsgrad aus den Reinheitsgraden aller Pragmas der einzelnen Funktionen im Package ableiten lassen. In der folgenden Version des Packages company kann der Oracle Server aus den beiden Pragmas für die Funktionen einen Reinheitsgrad von RNDS und WNPS für den Initialisierungsabschnitt ableiten. Der Initialisierungsabschnitt kann also nicht aus der Datenbank lesen und keine Package-Variablen beschreiben. PACKAGE company FUNCTION get_company (company_id_in IN VARCHAR2) RETURN company%rowtype; FUNCTION deactivate_company (company_id_in IN company.company_id%type) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES (get_company, RNDS, WNPS); PRAGMA RESTRICT_REFERENCES (deactivate_name, WNPS); END company; 590

13 Die Präzedenz von Spalten- und Funktionsnamen Üblicherweise ist es besser, den Reinheitsgrad des Initialisierungsabschnitts explizit anzugeben. Das macht es denjenigen, die das Package später einmal warten müssen, leichter, Ihre Absichten und Ihr Verständnis des Packages zu durchschauen. Die Präzedenz von Spalten- und Funktionsnamen Wenn Ihre Funktion den gleichen Namen wie eine Tabellenspalte in einer SELECT- Anweisung und keine Parameter hat, dann hat die Spalte Vorrang vor der Funktion. Die Tabelle employee habe eine Spalte namens salary. Wenn Sie nun auch eine Funktion namens salary erzeugen CREATE TABLE employee (employee_id NUMBER,..., salary NUMBER,...); FUNCTION salary RETURN NUMBER; dann bezieht sich salary in einer SELECT-Anweisung immer auf die Spalte und nicht auf die Funktion: SELECT salary INTO calculated_salary FROM employee; Wenn Sie diese Präzedenz der Spalte umgehen wollen, müssen Sie den Namen der Funktion mit dem Namen des Schemas, dem diese Funktion gehört, qualifizieren: SELECT scott.salary INTO calculated_salary FROM employee; Damit wird die Funktion ausgeführt, anstatt den Spaltenwert zu holen. Die rauhe Wirklichkeit: PL/SQL-Funktionen in SQL aufrufen Die Möglichkeit, PL/SQL-Funktionen in SQL aufzurufen, gibt es schon seit der Version 2.1, aber trotzdem kann das in vielerlei Hinsicht (zumindest vor dem Erscheinen von Oracle8) als»brandneue«technologie betrachtet werden. Warum ist das so? Sie müssen in Ihrem Code die RESTRICT_REFERENCES-Pragmas von Hand eintragen, und Sie müssen selbst herausfinden, wo diese nötig sind. Wie man das macht, wird in einem späteren Abschnitt beschrieben. Die Funktionen werden außerhalb des Lesekonsistenzmodells der Oracle-Datenbank ausgeführt (!). Auch das wird in einem späteren Abschnitt näher erläutert. Es ist immer noch teuer, eine Funktion von SQL aus aufzurufen. Die genauen Kosten eines Funktionsaufrufs (verglichen beispielsweise mit Inline-SQL-Code) sind schwer zu bestimmen, sie unterscheiden sich von Computer zu Computer und sogar von Instanz zu Instanz oder von aufgerufener Funktion zu aufgerufener 591

14 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen Funktion. Ich habe von einer zusätzlichen halben Sekunde bis zu erstaunlichen zusätzlichen fünfzig Sekunden gehört (auch wenn ich im letzteren Falle vorschlagen würde, ein wenig mehr zu analysieren und zu debuggen). Aber egal wie schnell der Aufruf wirklich ist, die Verzögerung kann für den Anwender spürbar sein. Sie müssen sie also in Ihren Design- und Testplänen berücksichtigen. Tuning-Mechanismen wie EXPLAIN PLAN berücksichtigen den SQL-Code nicht, der in Funktionen aufgerufen werden könnte, die wiederum von Ihren SQL- Anweisungen aufgerufen werden. PL/SQL-Funktionen werden von EXPLAIN PLAN nicht berücksichtigt. Damit wird es schwierig, die Flaschenhälse zu erkennen, die man zur Performanzsteigerung beseitigen muß. Ein großer Teil der Oracle-Technologie, und dabei wiederum insbesondere jener Teil, der in Built-in Packages steckt, ist für Funktionen in SQL verboten. Denken Sie nur an DBMS_OUTPUT. Sie können dieses Package nicht in von SQL aus aufgerufenen Funktionen verwenden. Normalerweise möchten Sie aber die gleichen Funktionen in SQL und PL/SQL verwenden. Auch fügen Sie zum Debuggen möglicherweise am Anfang und am Ende Ihrer Funktionen und Prozeduren Aufrufe ein und verwenden sehr wahrscheinlich DBMS_OUTPUT (oder UTIL_FILE oder DBMS_PIPE, was Sie wollen, diese Funktionen sind alle zumindest vor Oracle8 verboten). Tja, tut mir leid. Diese Funktionen können Sie von SQL aus nicht verwenden. Also müssen Sie Code aus der Funktion herausnehmen. Am Ende haben Sie zwei Versionen Ihres Codes: eine für PL/SQL, eine für SQL, ein Alptraum für Software-Entwickler. Schauen wir uns jetzt zwei dieser Probleme genauer an. Manuelles Eintragen der Pragmas Sie müssen die RESTRICT_REFERENCES-Pragmas überall in Ihrem Code eintragen und auch herausfinden, wo diese hingehören. Dieser Vorgang ähnelt oft einer detektivischen Spurensuche, Sherlock Holmes läßt grüßen! Sie kompilieren ein Package und erhalten eine Meldung über einen Verstoß gegen ein Pragma. Der Grund dafür kann sein, daß Ihr Programm eine Regel verletzt (indem es beispielsweise Daten verändert), oder andere Programme aufruft, die eine Regel verletzen. In letzterem Fall stehen Sie womöglich vor fünf oder sechs anderen Funktionen oder Prozeduren, müssen also in all diesen ebenfalls die Pragmas eintragen. Damit sichern Sie aber Reinheitsgrade zu, wo das vorher nicht geschah, und handeln sich damit im besten Fall weitere Fehler ein, im schlechtesten Fall aber weitreichende Konsequenzen für die Architektur Ihrer Anwendung. Nehmen wir beispielsweise an, daß Sie auf einmal einer Prozedur im Package X ein Pragma anbeistellen müssen. Dieses Package hat aber einen Initialisierungsabschnitt, so daß Sie auch diesen mit Pragmas versehen müssen. In diesen Abschnitten werden oft PL/SQL-Tabellen für die Datenmanipulation im Speicher eingerichtet. Wenn Sie aber PL/SQL-Tabellenmethoden für die Initialisierung solcher Tabellen verwenden, wird das Pragma fehlschlagen. 592

15 Die rauhe Wirklichkeit: PL/SQL-Funktionen in SQL aufrufen Dieser Vorgang kann ziemlich frustrierend sein und manchmal dazu führen, daß Sie am Ende darauf verzichten, eine Funktion von SQL aus aufzurufen. Ich habe die Erfahrung gemacht, daß man so weit wie möglich im vornherein die Bereiche der Anwendung festlegen sollte, die von SQL aus aufgerufen werden sollen. Sie können dann diesen Code besonders»sauber«und beschränkt auf die eigentliche Aufgabe halten und die Verstrickungen mit anderen Packages sowie die Verwendung Built-in Packages so gering wie möglich halten. Das ist weder einfach noch besonders spaßig. Komplikationen mit dem Lesekonsistenzmodell Ja, es ist kaum zu glauben, aber wahr: Wenn Sie nicht besondere Vorsichtsmaßnahmen treffen, ist es gut möglich, daß Ihre SQL-Abfrage das Lesekonsistenzmodell des Oracle- RDBMS verletzt, ein seit Jahren geheiligtes Territorium in Oracle. Um dieses Problem zu verstehen, werfen Sie bitte einen Blick auf die folgende Abfrage und die von ihr aufgerufene Funktion: SELECT name, total_sales (account_id) FROM account WHERE status = 'ACTIVE'; FUNCTION total_sales (id_in IN account.account_id%type) RETURN NUMBER CURSOR tot_cur SELECT SUM (sales) total FROM orders WHERE account_id = id_in AND year = TO_NUMBER (TO_CHAR (SYSDATE, 'YYYY')); tot_rec tot_cur%rowtype; BEGIN OPEN tot_cur; FETCH tot_cur INTO tot_rec; RETURN tot_rec.total; END; Die Tabelle account hat fünf Millionen aktive Zeilen (offensichtlich ein sehr erfolgreiches Unternehmen!). Die Tabelle orders hat zwanzig Millionen Zeilen. Ich starte die Abfrage um 11 Uhr morgens und rechne damit, daß sie etwa eine Stunde dauert. Um viertel vor zwölf kommt jemand mit der entsprechenden Berechtigung, löscht alle Zeilen aus der Tabelle orders und gibt die Änderung frei. Nach dem Lesekonsistenzmodell von Oracle sollte die Sitzung, welche die Abfrage ausführt, all diese gelöschten Zeilen sehen, bis die Abfrage abgeschlossen ist. Aber wenn das nächste Mal die Funktion total_sales aus der Abfrage heraus aufgerufen wird, findet Sie keine Zeilen in orders mehr vor und gibt NULL zurück und das auch bei allen weiteren Aufrufen. Sie müssen sich also über solche Lesekonsistenzprobleme im klaren sein, wenn Sie in Funktionen, die von SQL aus aufgerufen werden, wiederum Abfragen durchführen. Wenn diese Funktionen von lange laufenden Abfragen oder Transaktionen aufgerufen 593

16 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen werden, sollten Sie vielleicht zwischen den SQL-Anweisungen der aktuellen Transaktion den folgenden Befehl eingeben, um die Lesekonsistenz zu erzwingen: SET TRANSACTION READ ONLY Mehr dazu finden Sie in Kapitel 6, Interaktion mit der Datenbank und Cursoren. Das Arbeiten mit Funktionen in SQL ist schwieriger und komplizierter, als Sie es sich vielleicht auf den ersten Blick vorstellen können. Das hätte man sich eigentlich auch denken können, denn man kann das über fast jeden Aspekt der Oracle-Technologie sagen, insbesondere über die kürzlich hinzugekommenen Neuerungen. Ich hoffe, daß uns Oracle mit der Zeit das Leben leichter machen wird (und in Oracle 8.0 gibt es einige deutliche Verbesserungen). Was wir letztendlich brauchen, ist ein Hilfsprogramm, mit dem ein Entwickler auf eine Funktion verweisen und verlangen kann, daß»diese Funktion für SQL nutzbar gemacht wird«. Dieses Hilfsprogramm trägt dann alle Pragmas ein oder erstellt zumindest einen Bericht über die notwendigen Schritte. Man darf ja schließlich träumen, oder? Beispiele eingebetteten PL/SQL-Codes Je mehr Sie über gespeicherte Funktionen in SQL nachdenken, um so mehr Möglichkeiten werden Ihnen einfallen, diese in jeder einzelnen Ihrer Anwendungen zu verwenden. Um Ihrer Kreativität eine kleine Starthilfe zu geben, zeige ich Ihnen hier einige Beispiele, wie gespeicherte Funktionen in SQL-Anweisungen Ihre Oracle-basierten Systeme verändern können. Eingekapselte Berechnungen In so ziemlich jeder Anwendung müssen Sie immer wieder die gleichen Berechnungen durchführen. Egal ob es sich dabei um die Berechnung des Bruttobetrags, des Standes der Hypothek, des Abstands zweier Punkte auf einer kartesischen Ebene oder einer statistischen Varianz handelt, mit nativem SQL müssen Sie diese Berechnungen in jeder SQL-Anweisung, in der sie benötigt werden, wieder neu schreiben. Für diese Redundanz zahlen Sie einen hohen Preis. Der Code, der Ihre Geschäftsregeln implementiert, ist über die gesamte Anwendung verstreut und wird immer wieder wiederholt. Sogar wenn sich diese Regeln selbst nicht ändern, wird sich wahrscheinlich die Implementierung dieser Regeln irgendwann ändern müssen. Wenn sich die Regel selbst ändert, ist die Lage natürlich noch übler, weil das oft zu ziemlich umfassenden Änderungen im Code führen kann. Um dieses Problem zu lösen, können Sie alle Formeln und Berechnungen in gespeicherten Funktionen verstecken. Diese Funktionen können dann sowohl aus SQL- Anweisungen als auch aus PL/SQL-Programmen heraus aufgerufen werden. Ein schönes Beispiel für die Nützlichkeit eingekapselter Berechnungen entstand, als eine Versicherung Analysen ihrer Konten auf Basis von Datumsangaben durchführen 594

17 Beispiele eingebetteten PL/SQL-Codes mußte. Der letzte Tag im Monat ist natürlich für die meisten Finanzinstitutionen ein sehr wichtiges Datum. Um die Datumsangaben zu manipulieren, sah die IT-Abteilung der Firma vor, die Built-in-Funktion LAST_DAY zu verwenden, um den letzten Tag eines Monats zu bekommen, und mit ADD_MONTHS von einem Monat zum nächsten zu springen. Bald fiel ihnen aber eine sehr interessante Nuance in der Funktion von ADD_ MONTHS auf: Wenn Sie einen Tag an ADD_MONTH übergeben, welcher der letzte Tag des jeweiligen Monats ist, dann gibt SQL immer den letzten Tag im daraus resultierenden Monat zurück, egal, wie viele Tage jeder der einzelnen Monate wirklich hat: Anders ausgedrückt: ADD_MONTHS ('28-FEB-1994', 2) ==> 30-APR-1993 Das ist vielleicht bei manchen Anwendungen und Abfragen auch sinnvoll. Bei der Versicherung war die Anforderung aber, daß man beim Springen von Monat zu Monat immer am gleichen Tag des Monats ankommen muß (oder am letzten Tag, wenn der Tag im Ausgangsmonat nach dem letzten Tag des Zielmonats lag). Ohne gespeicherte Funktionen hätte man folgende SQL-Anweisung verwenden müssen: SELECT DECODE (payment_date, LAST_DAY (payment_date), LEAST (ADD_MONTHS (payment_date, 1), TO_DATE (TO_CHAR (ADD_MONTHS (payment_date, 1), 'MMYYYY') TO_CHAR (payment, 'DD'), 'MMYYYYDD')), ADD_MONTHS (payment_date, 1)) FROM premium_payments; Auf deutsch heißt das:»wenn das Datum der letzten Zahlung auf den letzten Tag des Monats fällt, dann gib als Datum der nächsten Zahlung entweder das Ergebnis der Addition eines Monats zum Datum der letzten Zahlung (mit ADD_MONTHS) oder den gleichen Tag wie den der letzten Zahlung im neuen Monat zurück. Falls die letzte Zahlung nicht am letzten Tag des Monats getätigt wurde, dann verwende zur Bestimmung des nächsten Zahlungsdatums einfach ADD_MONTHS.«Das ist nicht nur schwierig zu verstehen, sondern benötigt auch drei Aufrufe der Builtin-Funktion ADD_MONTHS. Stellen Sie sich jetzt noch vor, daß diese komplexe SQL- Anweisung in jeder SELECT-Liste hätte wiederholt werden müssen, in der ADD_MONTHS verwendet wurde, um die Datumsangaben herauf- oder herunterzuzählen. Sie können sich da wahrscheinlich gut vorstellen, wie froh die Programmierer in dieser Firma waren, als sie die Version 7.1 von Oracle Server installierten und die folgende Funktion in ihren SQL-Anweisungen verwenden konnten (eine vollständige Erklärung der Logik dieser Funktion finden Sie in Kapitel 12, Datumsfunktionen): FUNCTION new_add_months (date_in IN DATE, months_shift IN NUMBER) RETURN DATE return_value DATE; 595

18 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen BEGIN return_value := ADD_MONTHS (date_in, months_shift); IF date_in = LAST_DAY (date_in) THEN return_value := LEAST (return_value, TO_DATE (TO_CHAR (return_value, 'MMYYYY') TO_CHAR (date_in, 'DD'), 'MMYYYYDD')); END IF; RETURN return_value; END new_add_months; Damit wird die SELECT-Anweisung zur Bestimmung des nächsten Zahlungsdatums sehr einfach: SELECT new_add_months (payment_date,1) FROM premium_payments; Je mehr Sie Ihre SQL-Anweisungen durchsehen, um so mehr Möglichkeiten für den Einsatz gespeicherter Funktionen werden Sie finden, mit denen Sie Berechnungen verstekken und damit auf lange Sicht die Stabilität Ihres Codes verbessern können. Es ist zwar wenig wahrscheinlich, daß Sie die Zeit und die Ressourcen haben, um das gesamte SQL-Rückgrat Ihrer Anwendung neu zu schreiben, aber Sie können zumindest entsprechende Funktionen entwickeln und diese in Neuentwicklungen einsetzen. Kombinieren skalarer und aggregierter Werte Die folgende einfache Frage ist in SQL schwer zu beantworten:»zeige mir den Namen und das Gehalt des Mitarbeiters jeder Abteilung, der in dieser Abteilung das höchste Gehalt hat, sowie das Gesamtgehalt aller Mitarbeiter der jeweiligen Abteilungen.«Wenn man diese Frage in zwei Teile aufteilt, ist das nicht schwer. Hier ist der erste Teil: SELECT department_id, last_name, salary FROM employee E1 WHERE salary = (SELECT MAX (salary) FROM employee E2 WHERE E.department_id = E2.department_id) GROUP BY department_id; Und hier der zweite: SELECT department_id, SUM (salary) FROM employee GROUP BY department_id; Es ist aber nicht so einfach, diese beiden zu kombinieren, weil man dabei sowohl skalare Werte (eine einzelne Zeile) als auch aggregierte (sich über mehrere Zeilen erstrekkende) Werte aus ein und derselben Tabelle abfragen müßte. Wie soll ich meine FROM-, WHERE- und GROUP BY-Klauseln schreiben, um sowohl das Gehalt eines einzelnen als auch das aller Abteilungsmitglieder zusammengenommen anzuzeigen? 596

19 Beispiele eingebetteten PL/SQL-Codes SELECT department_id, last_name, salary, SUM (salary) FROM...? WHERE...? GROUP BY...? Vor der Version 2.1 von PL/SQL war die naheliegendste Lösung, eine Sicht zu erzeugen, die das Gehalt jeder Abteilung schon einmal»im voraus«zusammenfaßte: CREATE VIEW dept_salary AS SELECT department_id, SUM (salary) total_salary FROM employee GROUP BY department_id; Mit dieser Sicht kann ich die Antwort mit einer einzigen SQL-Anweisung bekommen: SELECT E.department_id, last_name, salary, total_salary FROM employee E, dept_salary DS WHERE E.department_id = DS.department_id AND salary = (SELECT MAX (salary) FROM employee E2 WHERE E.department_id = E2.department_id); Diese Lösung sieht ja gar nicht so schlecht aus, aber Sie müssen jedesmal, wenn Sie eine solche Berechnung durchführen wollen, eine spezielle Sicht erzeugen. Abgesehen davon, ist dieser SQL-Code auch für viele Programmierer nicht so besonders offensichtlich. Eine bessere Lösung ist es, eine gespeicherte Funktion zu verwenden. Anstatt eine Sicht zu erzeugen, schreiben wir eine Funktion, die genau die gleiche Berechnung durchführt, aber dieses Mal nur für die angegebene Abteilung: FUNCTION total_salary (dept_id_in IN department.department_id%type) RETURN NUMBER CURSOR grp_cur SELECT SUM (salary) FROM employee WHERE department_id = dept_id_in; return_value NUMBER; BEGIN OPEN grp_cur; FETCH grp_cur INTO return_value; CLOSE grp_cur; RETURN return_value; END; Wenn eine Abteilung nicht existiert, gebe ich NULL zurück. Wenn eine Abteilung keine Mitarbeiter hat, gebe ich 0 zurück, ansonsten die Summe der Gehälter aller Mitarbeiter in dieser Abteilung. 597

20 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen Meine Abfrage muß jetzt keine Sicht verwenden, die ein GROUP BY enthält. Statt dessen ruft sie einfach die Funktion total_salary auf und übergibt die ID-Nummer der Abteilung des Mitarbeiters als Parameter: SELECT E.department_id, last_name, salary, total_salary (E.department_id) FROM employee E WHERE salary = (SELECT MAX (salary) FROM employee E2 WHERE E.department_id = E2.department_id); Die daraus resultierende SQL-Anweisung ist nicht nur leichter zu lesen, sondern ist auch schneller, insbesondere bei größeren Tabellen. Ich könnte die SQL-Anweisung noch weiter vereinfachen, indem ich eine Funktion schreibe, die das maximale Gehalt in einer bestimmten Abteilung zurückgibt. Die SELECT-Anweisung lautet dann einfach nur: SELECT department_id, last_name, salary, total_salary (department_id) FROM employee E WHERE salary = max_sal_in_dept (department_id); Ersetzung korrelierter Subabfragen Mit gespeicherten Funktionen in SQL-Anweisungen kann man auch korrelierte Subabfragen ersetzen. Das sind SELECT-Anweisungen innerhalb der WHERE-Klausel einer SQL-Anweisung (SELECT, INSERT oder DELETE), die sich auf eine oder mehrere Spalten der umgebenden SQL-Anweisung beziehen. Im letzten Abschnitt habe ich eine korrelierte Subabfrage verwendet, um den Mitarbeiter mit dem höchsten Gehalt in jeder Abteilung zu bestimmen: SELECT E.department_id, last_name, salary, total_salary (E.department_id) FROM employee E WHERE salary = (SELECT MAX (salary) FROM employee E2 WHERE E.department_id = E2.department_id); Die letzten drei Zeilen der Abfrage enthalten eine SELECT-Anweisung, in der die Abteilungsnummer des»inneren«mitarbeiters (E2) mit der Abteilungsnummer in der»äußeren«mitarbeitertabelle (E1) übereinstimmen soll. Die innere Abfrage wird für jede mit der äußeren Abfrage ermittelte Zeile einmal ausgeführt. Korrelierte Subabfragen sind ein sehr mächtiges Feature von SQL, weil sie den verschachtelten Schleifen prozeduraler Programmiersprachen wie in LOOP LOOP END LOOP; END LOOP; entsprechen. Sie haben aber zwei Nachteile: Die Logik kann ziemlich kompliziert werden. Die resultierende SQL-Anweisung kann schwierig zu verstehen und zu verfolgen sein. 598

21 Beispiele eingebetteten PL/SQL-Codes Sie können diese Nachteile vermeiden, indem Sie gespeicherte Funktionen anstelle der korrelierten Subabfragen verwenden. Im obigen Beispiel bräuchte ich eine Funktion, die das höchste Gehalt in einer bestimmten Abteilung berechnet: FUNCTION max_salary (dept_id_in IN department.department_id%type) RETURN NUMBER CURSOR grp_cur SELECT MAX (salary) FROM employee WHERE department_id = dept_id_in; return_value NUMBER; BEGIN OPEN grp_cur; FETCH grp_cur INTO return_value; CLOSE grp_cur; RETURN return_value; END; Jetzt kann ich sowohl total_salary als auch max_salary in meiner SELECT-Anweisung verwenden. Auf deutsch übersetzt würde diese etwa lauten:»zeige mir den Namen und das Gehalt des Mitarbeiters, der in der jeweiligen Abteilung das höchste Gehalt hat, sowie das Gesamtgehalt aller Mitarbeiter in der Abteilung dieses Mitarbeiters«: SELECT E.department_id, last_name, salary, total_salary (department_id) FROM employee WHERE salary = max_salary (department_id); Vergleichen Sie dieses einfache und selbstdokumentierende Stück SQL mit der Version, die eine Sicht und eine korrelierte Subabfrage benötigt: CREATE VIEW dept_salary AS SELECT department_id, SUM (salary) total_salary FROM employee GROUP BY department_id; SELECT E.department_id, last_name, salary, total_salary FROM employee E, dept_salary DS WHERE E.department_id = DS.department_id AND salary = (SELECT MAX (salary) FROM employee E2 WHERE E.department_id = E2.department_id); Ich bin sicher, Sie werden mir zustimmen, daß gespeicherte Funktionen in SQL Ihr Leben einfacher machen können. Ihnen ist vielleicht aufgefallen, daß die Funktion total_salary aus dem letzten Abschnitt der Funktion max_salary aus diesem Abschnitt sehr ähnlich sieht. Der einzige Unterschied zwischen den beiden ist der, daß der Cursor in total_salary die 599

22 Kapitel 17: PL/SQL-Funktionen von SQL aus aufrufen Gruppierungsfunktion SUM und der Cursor in max_salary die Gruppierungsfunktion MAX verwendet. Wenn Sie immer fanatisch darauf aus sind, möglichst viel Ihres Codes in einer möglichst kleinen Anzahl unterschiedlicher»beweglicher Teile«zusammenzufassen, dann könnten Sie auch eine einzige Funktion daraus machen, die abhängig von einem zweiten Parameter, verschiedene Statistiken auf Gruppenebene zurückliefert: FUNCTION salary_stat (dept_id_in IN department.department_id%type, stat_type_in IN VARCHAR2) RETURN NUMBER v_stat_type VARCHAR2(20) := UPPER (stat_type_in); CURSOR grp_cur SELECT SUM (salary) sumsal, MAX (salary) maxsal, MIN (salary) minsal, AVG (salary) avgsal, COUNT (DTINCT salary) countsal, FROM employee WHERE department_id = dept_id_in; grp_rec grp_cur%rowtype; retval NUMBER; BEGIN OPEN grp_cur; FETCH grp_cur INTO grp_rec; CLOSE grp_cur; IF v_stat_type = 'SUM' THEN retval := grp_rec.sumsal; ELSIF v_stat_type = 'MAX' THEN retval := grp_rec.maxsal; ELSIF v_stat_type = 'MIN' THEN retval := grp_rec.minsal; ELSIF v_stat_type = 'COUNT' THEN retval := grp_rec.countsal; ELSIF v_stat_type = 'AVG' THEN retval := grp_rec.avgsal; END IF; RETURN retval; END; 600

23 Beispiele eingebetteten PL/SQL-Codes Die zusätzlichen Kosten, die durch diese Ausdrücke in der SELECT-Liste entstehen und die Verarbeitung der IF-Anweisung sind vernachlässigbar. Mit diesem neuen, generischen Werkzeug sieht meine Gehaltsanalyse nun so aus: SELECT E.department_id, last_name, salary, salary_stat (department_id, 'sum') FROM employee WHERE salary = salary_stat (department_id, 'max'); Wenn ich jemals den SQL-Code, mit dem man die Statistiken über Abteilungen erhält, ändern muß, dann muß ich nur diese eine Funktion anfassen. Ersetzen von DECODE durch IF-Anweisungen Die DECODE-Funktion stellt IF-ähnliche Möglichkeiten in der nichtprozeduralen SQL- Umgebung des Oracle Server bereit. Sie können die DECODE-Syntax verwenden, um Matrixberichte mit einer festen Anzahl von Spalten zu erzeugen, aber auch, um in einer Abfrage komplexe IF-THEN-ELSE-Logik einzubauen. Betrachten Sie das folgende Beispiel für DECODE, in dem bestimmt wird, ob ein Datum innerhalb eines vorgeschriebenen Bereichs liegt und das, wenn ja, die Anzahl der Zeilen, die diese Bedingung erfüllen, inkrementiert: SELECT FC.year_number, SUM (DECODE (GREATEST (ship_date, FC.q1_sdate), ship_date, DECODE (LEAST (ship_date, FC.q1_edate), ship_date, 1, 0), 0)) Q1_results, SUM (DECODE (GREATEST (ship_date, FC.q2_sdate), ship_date, DECODE (LEAST (ship_date, FC.q2_edate), ship_date, 1, 0), 0)) Q2_results, SUM (DECODE (GREATEST (ship_date, FC.q3_sdate), ship_date, DECODE (LEAST (ship_date, FC.q3_edate), ship_date, 1, 0), 0)) Q3_results, SUM (DECODE (GREATEST (ship_date, FC.q4_sdate), ship_date, DECODE (LEAST (ship_date, FC.q4_edate), ship_date, 1, 0), 0)) Q4_results FROM orders O, fiscal_calendar FC GROUP BY year_number; Die Ergebnismenge der Abfrage könnte so aussehen: 601

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

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

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

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

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost Adobe Photoshop Lightroom 5 für Einsteiger Bilder verwalten und entwickeln Sam Jost Kapitel 2 Der erste Start 2.1 Mitmachen beim Lesen....................... 22 2.2 Für Apple-Anwender.........................

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

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

Datensicherung. Beschreibung der Datensicherung

Datensicherung. Beschreibung der Datensicherung Datensicherung Mit dem Datensicherungsprogramm können Sie Ihre persönlichen Daten problemlos Sichern. Es ist möglich eine komplette Datensicherung durchzuführen, aber auch nur die neuen und geänderten

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

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

Persönliche Zukunftsplanung mit Menschen, denen nicht zugetraut wird, dass sie für sich selbst sprechen können Von Susanne Göbel und Josef Ströbl

Persönliche Zukunftsplanung mit Menschen, denen nicht zugetraut wird, dass sie für sich selbst sprechen können Von Susanne Göbel und Josef Ströbl Persönliche Zukunftsplanung mit Menschen, denen nicht zugetraut Von Susanne Göbel und Josef Ströbl Die Ideen der Persönlichen Zukunftsplanung stammen aus Nordamerika. Dort werden Zukunftsplanungen schon

Mehr

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst.

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst. 40-Tage-Wunder- Kurs Umarme, was Du nicht ändern kannst. Das sagt Wikipedia: Als Wunder (griechisch thauma) gilt umgangssprachlich ein Ereignis, dessen Zustandekommen man sich nicht erklären kann, so dass

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

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

Was meinen die Leute eigentlich mit: Grexit?

Was meinen die Leute eigentlich mit: Grexit? Was meinen die Leute eigentlich mit: Grexit? Grexit sind eigentlich 2 Wörter. 1. Griechenland 2. Exit Exit ist ein englisches Wort. Es bedeutet: Ausgang. Aber was haben diese 2 Sachen mit-einander zu tun?

Mehr

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen.

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen. Datenbank-Verschlüsselung mit DbDefence und Webanwendungen. In diesem Artikel werden wir Ihnen zeigen, wie Sie eine Datenbank verschlüsseln können, um den Zugriff einzuschränken, aber trotzdem noch eine

Mehr

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 Referentin: Dr. Kelly Neudorfer Universität Hohenheim Was wir jetzt besprechen werden ist eine Frage, mit denen viele

Mehr

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7 Einrichtung des Cisco VPN Clients (IPSEC) in Windows7 Diese Verbindung muss einmalig eingerichtet werden und wird benötigt, um den Zugriff vom privaten Rechner oder der Workstation im Home Office über

Mehr

Updatehinweise für die Version forma 5.5.5

Updatehinweise für die Version forma 5.5.5 Updatehinweise für die Version forma 5.5.5 Seit der Version forma 5.5.0 aus 2012 gibt es nur noch eine Office-Version und keine StandAlone-Version mehr. Wenn Sie noch mit der alten Version forma 5.0.x

Mehr

Das große ElterngeldPlus 1x1. Alles über das ElterngeldPlus. Wer kann ElterngeldPlus beantragen? ElterngeldPlus verstehen ein paar einleitende Fakten

Das große ElterngeldPlus 1x1. Alles über das ElterngeldPlus. Wer kann ElterngeldPlus beantragen? ElterngeldPlus verstehen ein paar einleitende Fakten Das große x -4 Alles über das Wer kann beantragen? Generell kann jeder beantragen! Eltern (Mütter UND Väter), die schon während ihrer Elternzeit wieder in Teilzeit arbeiten möchten. Eltern, die während

Mehr

Zeichen bei Zahlen entschlüsseln

Zeichen bei Zahlen entschlüsseln Zeichen bei Zahlen entschlüsseln In diesem Kapitel... Verwendung des Zahlenstrahls Absolut richtige Bestimmung von absoluten Werten Operationen bei Zahlen mit Vorzeichen: Addieren, Subtrahieren, Multiplizieren

Mehr

Nach der Anmeldung im Backend Bereich landen Sie im Kontrollzentrum, welches so aussieht:

Nach der Anmeldung im Backend Bereich landen Sie im Kontrollzentrum, welches so aussieht: Beiträge erstellen in Joomla Nach der Anmeldung im Backend Bereich landen Sie im Kontrollzentrum, welches so aussieht: Abbildung 1 - Kontrollzentrum Von hier aus kann man zu verschiedene Einstellungen

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

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

Artikel Schnittstelle über CSV

Artikel Schnittstelle über CSV Artikel Schnittstelle über CSV Sie können Artikeldaten aus Ihrem EDV System in das NCFOX importieren, dies geschieht durch eine CSV Schnittstelle. Dies hat mehrere Vorteile: Zeitersparnis, die Karteikarte

Mehr

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage .htaccess HOWTO zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage Stand: 21.06.2015 Inhaltsverzeichnis 1. Vorwort...3 2. Verwendung...4 2.1 Allgemeines...4 2.1 Das Aussehen der.htaccess

Mehr

Professionelle Seminare im Bereich MS-Office

Professionelle Seminare im Bereich MS-Office Serienbrief aus Outlook heraus Schritt 1 Zuerst sollten Sie die Kontakte einblenden, damit Ihnen der Seriendruck zur Verfügung steht. Schritt 2 Danach wählen Sie bitte Gerhard Grünholz 1 Schritt 3 Es öffnet

Mehr

Das Leitbild vom Verein WIR

Das Leitbild vom Verein WIR Das Leitbild vom Verein WIR Dieses Zeichen ist ein Gütesiegel. Texte mit diesem Gütesiegel sind leicht verständlich. Leicht Lesen gibt es in drei Stufen. B1: leicht verständlich A2: noch leichter verständlich

Mehr

Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote

Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote Zweck dieser Anleitung ist es einen kleinen Überblick über die Funktion Last Minute auf Swisshotelportal zu erhalten. Für das erstellen

Mehr

Durchführung der Datenübernahme nach Reisekosten 2011

Durchführung der Datenübernahme nach Reisekosten 2011 Durchführung der Datenübernahme nach Reisekosten 2011 1. Starten Sie QuickSteuer Deluxe 2010. Rufen Sie anschließend über den Menüpunkt /Extras/Reisekosten Rechner den QuickSteuer Deluxe 2010 Reisekosten-Rechner,

Mehr

2. Einrichtung der ODBC-Schnittstelle aus orgamax (für 32-bit-Anwendungen)

2. Einrichtung der ODBC-Schnittstelle aus orgamax (für 32-bit-Anwendungen) 1. Einführung: Über den ODBC-Zugriff können Sie bestimmte Daten aus Ihren orgamax-mandanten in anderen Anwendungen (beispielsweise Microsoft Excel oder Microsoft Access) einlesen. Dies bietet sich beispielsweise

Mehr

Erklärung zu den Internet-Seiten von www.bmas.de

Erklärung zu den Internet-Seiten von www.bmas.de Erklärung zu den Internet-Seiten von www.bmas.de Herzlich willkommen! Sie sind auf der Internet-Seite vom Bundes-Ministerium für Arbeit und Soziales. Die Abkürzung ist: BMAS. Darum heißt die Seite auch

Mehr

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter 2 Inhaltsverzeichnis 1 Web-Kürzel 4 1.1 Einführung.......................................... 4 1.2 Web-Kürzel.........................................

Mehr

Anleitung zur Daten zur Datensicherung und Datenrücksicherung. Datensicherung

Anleitung zur Daten zur Datensicherung und Datenrücksicherung. Datensicherung Anleitung zur Daten zur Datensicherung und Datenrücksicherung Datensicherung Es gibt drei Möglichkeiten der Datensicherung. Zwei davon sind in Ges eingebaut, die dritte ist eine manuelle Möglichkeit. In

Mehr

Software Engineering Klassendiagramme Assoziationen

Software Engineering Klassendiagramme Assoziationen Software Engineering Klassendiagramme Assoziationen Prof. Adrian A. Müller, PMP, PSM 1, CSM Fachbereich Informatik und Mikrosystemtechnik 1 Lesen von Multiplizitäten (1) Multiplizitäten werden folgendermaßen

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

Summenbildung in Bauteiltabellen mit If Then Abfrage

Summenbildung in Bauteiltabellen mit If Then Abfrage Summenbildung in Bauteiltabellen mit If Then Abfrage Die in Bauteiltabellen ausgelesenen Werte lassen sich in jeder Spalte als Summe berechnen. So können selbstverständlich die Flächen der in der Tabelle

Mehr

Sie müssen sich für diesen Fall mit IHREM Rechner (also zeitgut jk o.ä.) verbinden, nicht mit dem Terminalserver.

Sie müssen sich für diesen Fall mit IHREM Rechner (also zeitgut jk o.ä.) verbinden, nicht mit dem Terminalserver. Sie müssen sich für diesen Fall mit IHREM Rechner (also zeitgut jk o.ä.) verbinden, nicht mit dem Terminalserver. Am 15.08.2015 um 21:03 schrieb Jürgen Kleindienst : bei einer Terminalsitzung steht mir

Mehr

Eva Douma: Die Vorteile und Nachteile der Ökonomisierung in der Sozialen Arbeit

Eva Douma: Die Vorteile und Nachteile der Ökonomisierung in der Sozialen Arbeit Eva Douma: Die Vorteile und Nachteile der Ökonomisierung in der Sozialen Arbeit Frau Dr. Eva Douma ist Organisations-Beraterin in Frankfurt am Main Das ist eine Zusammen-Fassung des Vortrages: Busines

Mehr

infach Geld FBV Ihr Weg zum finanzellen Erfolg Florian Mock

infach Geld FBV Ihr Weg zum finanzellen Erfolg Florian Mock infach Ihr Weg zum finanzellen Erfolg Geld Florian Mock FBV Die Grundlagen für finanziellen Erfolg Denn Sie müssten anschließend wieder vom Gehaltskonto Rückzahlungen in Höhe der Entnahmen vornehmen, um

Mehr

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0)

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0) Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0) Peter Koos 03. Dezember 2015 0 Inhaltsverzeichnis 1 Voraussetzung... 3 2 Hintergrundinformationen... 3 2.1 Installationsarten...

Mehr

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem Fachbericht zum Thema: Anforderungen an ein Datenbanksystem von André Franken 1 Inhaltsverzeichnis 1 Inhaltsverzeichnis 1 2 Einführung 2 2.1 Gründe für den Einsatz von DB-Systemen 2 2.2 Definition: Datenbank

Mehr

Einrichten einer mehrsprachigen Webseite mit Joomla (3.3.6)

Einrichten einer mehrsprachigen Webseite mit Joomla (3.3.6) Einrichten einer mehrsprachigen Webseite mit Joomla (3.3.6) 1. Loggen Sie sich im Administratorbereich ein und gehen Sie auf Extension > Extension Manager 2. Wählen Sie Install languages 3. Klicken Sie

Mehr

Die Beschreibung bezieht sich auf die Version Dreamweaver 4.0. In der Version MX ist die Sitedefinition leicht geändert worden.

Die Beschreibung bezieht sich auf die Version Dreamweaver 4.0. In der Version MX ist die Sitedefinition leicht geändert worden. In einer Website haben Seiten oft das gleiche Layout. Speziell beim Einsatz von Tabellen, in denen die Navigation auf der linken oder rechten Seite, oben oder unten eingesetzt wird. Diese Anteile der Website

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

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

4D Server v12 64-bit Version BETA VERSION

4D Server v12 64-bit Version BETA VERSION 4D Server v12 64-bit Version BETA VERSION 4D Server v12 unterstützt jetzt das Windows 64-bit Betriebssystem. Hauptvorteil der 64-bit Technologie ist die rundum verbesserte Performance der Anwendungen und

Mehr

OP-LOG www.op-log.de

OP-LOG www.op-log.de Verwendung von Microsoft SQL Server, Seite 1/18 OP-LOG www.op-log.de Anleitung: Verwendung von Microsoft SQL Server 2005 Stand Mai 2010 1 Ich-lese-keine-Anleitungen 'Verwendung von Microsoft SQL Server

Mehr

Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken.

Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken. Seite erstellen Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken. Es öffnet sich die Eingabe Seite um eine neue Seite zu erstellen. Seiten Titel festlegen Den neuen

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

Vorlesung Dokumentation und Datenbanken Klausur

Vorlesung Dokumentation und Datenbanken Klausur Dr. Stefan Brass 5. Februar 2002 Institut für Informatik Universität Giessen Vorlesung Dokumentation und Datenbanken Klausur Name: Geburtsdatum: Geburtsort: (Diese Daten werden zur Ausstellung des Leistungsnachweises

Mehr

Menü auf zwei Module verteilt (Joomla 3.4.0)

Menü auf zwei Module verteilt (Joomla 3.4.0) Menü auf zwei Module verteilt (Joomla 3.4.0) Oft wird bei Joomla das Menü in einem Modul dargestellt, wenn Sie aber z.b. ein horizontales Hauptmenü mit einem vertikalen Untermenü machen möchten, dann finden

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

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

Informationsblatt Induktionsbeweis

Informationsblatt Induktionsbeweis Sommer 015 Informationsblatt Induktionsbeweis 31. März 015 Motivation Die vollständige Induktion ist ein wichtiges Beweisverfahren in der Informatik. Sie wird häufig dazu gebraucht, um mathematische Formeln

Mehr

geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen

geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Vollständigkeit halber aufgeführt. Gehen wir einmal davon aus, dass die von uns angenommenen 70% im Beispiel exakt berechnet sind. Was würde

Mehr

SEMINAR Modifikation für die Nutzung des Community Builders

SEMINAR Modifikation für die Nutzung des Community Builders 20.04.2010 SEMINAR Modifikation für die Nutzung des Community Builders Step by Step Anleitung ecktion SEMINAR Modifikation für die Nutzung des Community Builders Step by Step Anleitung Bevor Sie loslegen

Mehr

Reporting Services und SharePoint 2010 Teil 1

Reporting Services und SharePoint 2010 Teil 1 Reporting Services und SharePoint 2010 Teil 1 Abstract Bei der Verwendung der Reporting Services in Zusammenhang mit SharePoint 2010 stellt sich immer wieder die Frage bei der Installation: Wo und Wie?

Mehr

Kompilieren und Linken

Kompilieren und Linken Kapitel 2 Kompilieren und Linken Bevor wir uns auf C++ selbst stürzen, brauchen wir einiges Vorgeplänkel, wie man komfortabel ein größeres C++- kompilieren kann. Mit Java stellt sich der Kompiliervorgang

Mehr

Inventur. Bemerkung. / Inventur

Inventur. Bemerkung. / Inventur Inventur Die beliebige Aufteilung des Artikelstamms nach Artikeln, Lieferanten, Warengruppen, Lagerorten, etc. ermöglicht es Ihnen, Ihre Inventur in mehreren Abschnitten durchzuführen. Bemerkung Zwischen

Mehr

Geld Verdienen im Internet leicht gemacht

Geld Verdienen im Internet leicht gemacht Geld Verdienen im Internet leicht gemacht Hallo, Sie haben sich dieses E-book wahrscheinlich herunter geladen, weil Sie gerne lernen würden wie sie im Internet Geld verdienen können, oder? Denn genau das

Mehr

Anleitung Captain Logfex 2013

Anleitung Captain Logfex 2013 Anleitung Captain Logfex 2013 Inhalt: 1. Installationshinweise 2. Erste Schritte 3. Client-Installation 4. Arbeiten mit Logfex 5. Gruppenrichtlinien-Einstellungen für die Windows-Firewall 1. Installationshinweis:

Mehr

Wichtige Forderungen für ein Bundes-Teilhabe-Gesetz

Wichtige Forderungen für ein Bundes-Teilhabe-Gesetz Wichtige Forderungen für ein Bundes-Teilhabe-Gesetz Die Parteien CDU, die SPD und die CSU haben versprochen: Es wird ein Bundes-Teilhabe-Gesetz geben. Bis jetzt gibt es das Gesetz noch nicht. Das dauert

Mehr

icloud nicht neu, aber doch irgendwie anders

icloud nicht neu, aber doch irgendwie anders Kapitel 6 In diesem Kapitel zeigen wir Ihnen, welche Dienste die icloud beim Abgleich von Dateien und Informationen anbietet. Sie lernen icloud Drive kennen, den Fotostream, den icloud-schlüsselbund und

Mehr

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein. Schritt 1: Installation des Javacompilers JDK. Der erste Start mit Eclipse Bevor Sie den Java-Compiler installieren sollten Sie sich vergewissern, ob er eventuell schon installiert ist. Gehen sie wie folgt

Mehr

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER Inhalt 1 Einleitung... 1 2 Einrichtung der Aufgabe für die automatische Sicherung... 2 2.1 Die Aufgabenplanung... 2 2.2 Der erste Testlauf... 9 3 Problembehebung...

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

Berechnungen in Access Teil I

Berechnungen in Access Teil I in Access Teil I Viele Daten müssen in eine Datenbank nicht eingetragen werden, weil sie sich aus anderen Daten berechnen lassen. Zum Beispiel lässt sich die Mehrwertsteuer oder der Bruttopreis in einer

Mehr

Alle gehören dazu. Vorwort

Alle gehören dazu. Vorwort Alle gehören dazu Alle sollen zusammen Sport machen können. In diesem Text steht: Wie wir dafür sorgen wollen. Wir sind: Der Deutsche Olympische Sport-Bund und die Deutsche Sport-Jugend. Zu uns gehören

Mehr

Programmieren für mobile Endgeräte SS 2013/2014. Dozenten: Patrick Förster, Michael Hasseler

Programmieren für mobile Endgeräte SS 2013/2014. Dozenten: Patrick Förster, Michael Hasseler Programmieren für mobile Endgeräte SS 2013/2014 Programmieren für mobile Endgeräte 2 Informationen aus der Datenbank lesen Klasse SQLiteDatabase enthält die Methode query(..) 1. Parameter: Tabellenname

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

Upgrade-Leitfaden. Apparo Fast Edit 1 / 7

Upgrade-Leitfaden. Apparo Fast Edit 1 / 7 Upgrade-Leitfaden Apparo Fast Edit 1 / 7 Inhaltsverzeichnis 1 Download der neuen Version... 4 2 Sicherung des Apparo Datenbank-Repository... 4 3 De-Installation der installierten Apparo Fast Edit Version...

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

Guide DynDNS und Portforwarding

Guide DynDNS und Portforwarding Guide DynDNS und Portforwarding Allgemein Um Geräte im lokalen Netzwerk von überall aus über das Internet erreichen zu können, kommt man um die Themen Dynamik DNS (kurz DynDNS) und Portweiterleitung(auch

Mehr

Der Klassenrat entscheidet

Der Klassenrat entscheidet Folie zum Einstieg: Die Klasse 8c (Goethe-Gymnasium Gymnasium in Köln) plant eine Klassenfahrt: A Sportcamp an der deutschen Nordseeküste B Ferienanlage in Süditalien Hintergrundinfos zur Klasse 8c: -

Mehr

Die bisher bereits bekannten Aggregatsfunktionen MIN, MAX, SUM, AVG, COUNT, VARIANCE und STDDEV wurden um FIRST und LAST erweitert.

Die bisher bereits bekannten Aggregatsfunktionen MIN, MAX, SUM, AVG, COUNT, VARIANCE und STDDEV wurden um FIRST und LAST erweitert. Betrifft Autor FIRST, LAST Markus Jägle (markus.jaegle@trivadis.com) Art der Info Technische Background Info (April 2002) Quelle Aus dem NF9i-Kurs, NF9i-Techno-Circle der Trivadis und Oracle9i Data Warehousing

Mehr

Einkaufen im Internet. Lektion 5 in Themen neu 3, nach Übung 10. Benutzen Sie die Homepage von: http://www.firstsurf.de/klietm9950_f.

Einkaufen im Internet. Lektion 5 in Themen neu 3, nach Übung 10. Benutzen Sie die Homepage von: http://www.firstsurf.de/klietm9950_f. Themen neu 3 Was lernen Sie hier? Sie formulieren Ihre Vermutungen und Meinungen. Was machen Sie? Sie erklären Wörter und Ausdrücke und beurteilen Aussagen. Einkaufen im Internet Lektion 5 in Themen neu

Mehr

CSS-Grundlagen. Etwas über Browser. Kapitel. Die Vorbereitung

CSS-Grundlagen. Etwas über Browser. Kapitel. Die Vorbereitung Kapitel 1 Die Vorbereitung Vorgängerversionen. Bald darauf folgte dann schon die Version 4, die mit einer kleinen Bearbeitung bis vor Kurzem 15 Jahre unverändert gültig war. All das, was du die letzten

Mehr

Nicht kopieren. Der neue Report von: Stefan Ploberger. 1. Ausgabe 2003

Nicht kopieren. Der neue Report von: Stefan Ploberger. 1. Ausgabe 2003 Nicht kopieren Der neue Report von: Stefan Ploberger 1. Ausgabe 2003 Herausgeber: Verlag Ploberger & Partner 2003 by: Stefan Ploberger Verlag Ploberger & Partner, Postfach 11 46, D-82065 Baierbrunn Tel.

Mehr

Kurzanleitung fu r Clubbeauftragte zur Pflege der Mitgliederdaten im Mitgliederbereich

Kurzanleitung fu r Clubbeauftragte zur Pflege der Mitgliederdaten im Mitgliederbereich Kurzanleitung fu r Clubbeauftragte zur Pflege der Mitgliederdaten im Mitgliederbereich Mitgliederbereich (Version 1.0) Bitte loggen Sie sich in den Mitgliederbereich mit den Ihnen bekannten Zugangsdaten

Mehr

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress.

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress. Anmeldung http://www.ihredomain.de/wp-admin Dashboard Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress. Das Dashboard gibt Ihnen eine kurze Übersicht, z.b. Anzahl der Beiträge,

Mehr

Kapitel 4 Die Datenbank Kuchenbestellung Seite 1

Kapitel 4 Die Datenbank Kuchenbestellung Seite 1 Kapitel 4 Die Datenbank Kuchenbestellung Seite 1 4 Die Datenbank Kuchenbestellung In diesem Kapitel werde ich die Theorie aus Kapitel 2 Die Datenbank Buchausleihe an Hand einer weiteren Datenbank Kuchenbestellung

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

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom 21.10.2013b

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom 21.10.2013b AGROPLUS Buchhaltung Daten-Server und Sicherheitskopie Version vom 21.10.2013b 3a) Der Daten-Server Modus und der Tresor Der Daten-Server ist eine Betriebsart welche dem Nutzer eine grosse Flexibilität

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

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

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

Konzepte der Informatik

Konzepte der Informatik Konzepte der Informatik Vorkurs Informatik zum WS 2011/2012 26.09. - 30.09.2011 17.10. - 21.10.2011 Dr. Werner Struckmann / Christoph Peltz Stark angelehnt an Kapitel 1 aus "Abenteuer Informatik" von Jens

Mehr

PHPNuke Quick & Dirty

PHPNuke Quick & Dirty PHPNuke Quick & Dirty Dieses Tutorial richtet sich an all die, die zum erstenmal an PHPNuke System aufsetzen und wirklich keine Ahnung haben wie es geht. Hier wird sehr flott, ohne grosse Umschweife dargestellt

Mehr

Access [basics] Gruppierungen in Abfragen. Beispieldatenbank. Abfragen gruppieren. Artikel pro Kategorie zählen

Access [basics] Gruppierungen in Abfragen. Beispieldatenbank. Abfragen gruppieren. Artikel pro Kategorie zählen Abfragen lassen sich längst nicht nur dazu benutzen, die gewünschten Felder oder Datensätze einer oder mehrerer Tabellen darzustellen. Sie können Daten auch nach bestimmten Kriterien zu Gruppen zusammenfassen

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

1. Bearbeite Host Netzgruppen

1. Bearbeite Host Netzgruppen 1. Bearbeite Host Netzgruppen Eine "Host Netzgruppe" (von jetzt an Netzgruppe) kann mit einer Gästeliste, wenn Sie jemand zu einer Party einladen, verglichen werden. Sie haben eine Gästeliste erstellt

Mehr

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken Dateiname: ecdl5_01_00_documentation_standard.doc Speicherdatum: 14.02.2005 ECDL 2003 Basic Modul 5 Datenbank - Grundlagen

Mehr

Arbeiten mit UMLed und Delphi

Arbeiten mit UMLed und Delphi Arbeiten mit UMLed und Delphi Diese Anleitung soll zeigen, wie man Klassen mit dem UML ( Unified Modeling Language ) Editor UMLed erstellt, in Delphi exportiert und dort so einbindet, dass diese (bis auf

Mehr

Was ist Sozial-Raum-Orientierung?

Was ist Sozial-Raum-Orientierung? Was ist Sozial-Raum-Orientierung? Dr. Wolfgang Hinte Universität Duisburg-Essen Institut für Stadt-Entwicklung und Sozial-Raum-Orientierte Arbeit Das ist eine Zusammen-Fassung des Vortrages: Sozialräume

Mehr

Das Persönliche Budget in verständlicher Sprache

Das Persönliche Budget in verständlicher Sprache Das Persönliche Budget in verständlicher Sprache Das Persönliche Budget mehr Selbstbestimmung, mehr Selbstständigkeit, mehr Selbstbewusstsein! Dieser Text soll den behinderten Menschen in Westfalen-Lippe,

Mehr

! " # $ " % & Nicki Wruck worldwidewruck 08.02.2006

!  # $  % & Nicki Wruck worldwidewruck 08.02.2006 !"# $ " %& Nicki Wruck worldwidewruck 08.02.2006 Wer kennt die Problematik nicht? Die.pst Datei von Outlook wird unübersichtlich groß, das Starten und Beenden dauert immer länger. Hat man dann noch die.pst

Mehr

Enigmail Konfiguration

Enigmail Konfiguration Enigmail Konfiguration 11.06.2006 Steffen.Teubner@Arcor.de Enigmail ist in der Grundkonfiguration so eingestellt, dass alles funktioniert ohne weitere Einstellungen vornehmen zu müssen. Für alle, die es

Mehr