Anzeige

Laz Infos Svn0082

5. May 2009
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Anzeige
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Laz Infos Svn0082
Nächste SlideShare
HandbuchHandbuch
Wird geladen in ... 3
1 von 122
Anzeige

Más contenido relacionado

Anzeige

Laz Infos Svn0082

  1. LazInfos Das Lazarus Beispielbuch Andreas Frieß Die Community von www.lazarusforum.de 20. Mai 2008
  2. Version SVN $LastChangedRevision: 76 $ Copyright (C) 2007 Andreas Frieß. Es wird die Erlaubnis gewährt, dieses Doku- ment zu kopieren, zu verteilen und/oder zu modifizieren, unter den Bestimmungen der GNU Free Documentation License, Version 1.2 oder jede spätere Version, veröf- fentlicht von der Free Software Foundation; mit keinen unveränderlichen Abschnit- ten, keinen vorderen Umschlagtexten und keinen hinteren Umschlagtexten. Eine Kopie der Lizenz ist aufgenommen in den Abschnitt mit dem Titel quot;GNU Free Do- cumentation Licensequot;. Copyright c 2007 Andreas Friess Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”. 2
  3. Inhaltsverzeichnis 1 Lazarus Pascal 10 1.1 Anweisungen, Verzweigungen, Schleifen . . . . . . . . . . . . . . . . . . . . 10 1.1.1 Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.1.2 Verzweigungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.1.3 Prozeduren und Funktionen . . . . . . . . . . . . . . . . . . . . . . . 13 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Prozeduren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Parameterliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Parameterübergabe bei Wert . . . . . . . . . . . . . . . . . . . . . . . 15 Parameterübergabe bei Referenz . . . . . . . . . . . . . . . . . . . . . 16 Parameterübergabe von Objekten und Klassen . . . . . . . . . . . . . . 17 Überladen von Funktionen . . . . . . . . . . . . . . . . . . . . . . . . 17 1.2 Variablen, Konstanten, Datentypen . . . . . . . . . . . . . . . . . . . . . . . . 19 1.2.1 Konstanten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Normale Konstanten . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Typisierte Konstanten . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Resourcen Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.2.2 Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Begriff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Deklaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 1.2.3 Initialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 1.2.4 Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.3 Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 1.3.1 Was ist ein Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 1.3.2 Zur Laufzeit erzeugen und zerstören . . . . . . . . . . . . . . . . . . . 24 1.3.3 Was sollte man unterlassen . . . . . . . . . . . . . . . . . . . . . . . . 25 Erzeugung von Speicherleichen (Memoryleaks) . . . . . . . . . . . . . 25 2 Grundlagen Datenbank 27 2.1 Datenbanken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.1.1 Einführung in die Datenbanktheorie . . . . . . . . . . . . . . . . . . . 27 Begriffe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Was ist eine Datenbank . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Desktop und Client-Server Datenbankarten . . . . . . . . . . . . . . . 28 Relationale Datenbanken . . . . . . . . . . . . . . . . . . . . . . . . . 29 Grunddaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3
  4. Inhaltsverzeichnis 2.1.2 DDL Datendefinitionssprache . . . . . . . . . . . . . . . . . . . . . . 33 2.1.3 DML Datenveränderungssprache . . . . . . . . . . . . . . . . . . . . . 33 SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Beispiele zu SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . 34 INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Beispiele zu INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 UPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Beispiele zu UPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . 38 DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Beispiele zu DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.1.4 DCL Datenkontrollsprache . . . . . . . . . . . . . . . . . . . . . . . . 40 3 Installation 42 3.1 Linux openSUSE Erweiterte Lazarusinstallation . . . . . . . . . . . . . . . . . 42 3.1.1 Installation von Freepascal 2.2.0 . . . . . . . . . . . . . . . . . . . . . 42 3.1.2 Systemvorbereitung für Lazarus . . . . . . . . . . . . . . . . . . . . . 43 Subversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Abhängigkeiten von Lazarus . . . . . . . . . . . . . . . . . . . . . . . 44 FPC-Quellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.1.3 Installation von Lazarus aus dem SVN . . . . . . . . . . . . . . . . . . 45 3.1.4 Erstellen der Crosscompiling-Umgebung . . . . . . . . . . . . . . . . 46 Anpassung der fpc.cfg . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.1.5 Wine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Programme in WINE ausführen . . . . . . . . . . . . . . . . . . . . . 50 3.1.6 Eyecandy - GTK2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.2 Linux Debian Etch Snapshotinstallation . . . . . . . . . . . . . . . . . . . . . 54 3.2.1 Vorbereitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.2.2 Download . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.2.3 Umwandeln RPM -> DEB . . . . . . . . . . . . . . . . . . . . . . . . 55 3.2.4 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.2.5 Ausführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4 Lazarus IDE 57 4.1 Entwicklungsumgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.1.1 Tastenkombinationen . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.1.2 Fehlersuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 DebugLn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Heap Trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 4.1.3 Projektschablonen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Beschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5 Codebeispiele & FAQ 64 5.1 FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4
  5. Inhaltsverzeichnis 5.1.1 Oberfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Schrift auf einen Label ändert sich nicht . . . . . . . . . . . . . . . . . 64 6 Bibliotheken 65 6.1 SQLdb - Serverdatenbank Komponenten . . . . . . . . . . . . . . . . . . . . . 65 6.1.1 Beschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Debbuging von SQLdb . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Active, Open oder ExecSQL . . . . . . . . . . . . . . . . . . . . . . . 65 Wie kommen die geänderten Daten in die Datenbank . . . . . . . . . . 66 Filtern, aber wo ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Anzahl der Datensätze abfragen . . . . . . . . . . . . . . . . . . . . . 67 Navigieren durch eine Datenmenge . . . . . . . . . . . . . . . . . . . 67 Was ist BOF und EOF . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Zugriff auf Felder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Zugriff auf Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Schlüsselfelder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 6.1.2 TxxxConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Close . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 EndTransaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 ExecuteDirect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 GetFieldNames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 GetProcedureNames . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 GetTableNames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 StartTransaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 CharSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Connected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 DatabaseName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 HostName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 KeepConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 LoginPrompt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Password . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 StreamedConnected . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 UserName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 6.1.3 TMySQL50Connection . . . . . . . . . . . . . . . . . . . . . . . . . 72 6.1.4 TMySQL41Connection . . . . . . . . . . . . . . . . . . . . . . . . . 72 6.1.5 TMySQL40Connection . . . . . . . . . . . . . . . . . . . . . . . . . 72 6.1.6 TOracleConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 6.1.7 TPQConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 6.1.8 TODBCConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 5
  6. Inhaltsverzeichnis 6.1.9 TSQLTransaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Commit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 CommitRetaining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 EndTransaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Rollback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 RollbackRetaining . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 StartTransaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 6.1.10 TSQLQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Methoden von TSQLQuery . . . . . . . . . . . . . . . . . . . . . . . 75 ApplyUpdates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 CancelUpdates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Close . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 ExecSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 IsEmpty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Locate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Prepare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 SetSchemaInfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Unprepare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 UpdateStatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Eigenschaften von TSQLQuery . . . . . . . . . . . . . . . . . . . . . 77 Active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 DataSource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Filtered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 FilterOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 ParseSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Prepared . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 ReadOnly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 RecordCount . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 ServerFilter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 ServerFiltered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 SQL, UpdateSQL, InsertSQL, DeleteSQL . . . . . . . . . . . . . . . . 81 Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 StatementType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 UpdateMode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 UsePrimaryKeyAsKey . . . . . . . . . . . . . . . . . . . . . . . . . . 82 6.2 Data Access - Clientdatenbank Komponenten . . . . . . . . . . . . . . . . . . 83 6
  7. Inhaltsverzeichnis 6.2.1 Beschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.2 TDatasource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.3 SDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.4 FIXED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.5 TDBF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.6 MEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.7 SQLite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 ExecSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 ApplyUpdates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 ExecSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 SaveOnClose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 SaveOnRefetch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 6.3 utils.pas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 6.3.1 Beschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 6.3.2 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 ClearDir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 DateTimeToHourString . . . . . . . . . . . . . . . . . . . . . . . . . . 86 DateTimeToIndustrialTime . . . . . . . . . . . . . . . . . . . . . . . . 86 DrawText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 ExecProcessEx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 IsNumeric . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 InstallExt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 HTTPEncode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 ValidateFileName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 ValidateFileDir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 ValidateDate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 GetTempPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 GetConfigDir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 GetGlobalConfigDir . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 SizeToText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 GetMainIconHandle . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 CanWriteToProgramDir . . . . . . . . . . . . . . . . . . . . . . . . . 90 OpenBrowser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 HexToBin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 LoadLanguage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 RoundTo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 TimeTotext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 ExecProcess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 ExecVisualProcess . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 GetProcessforExtension . . . . . . . . . . . . . . . . . . . . . . . . . 92 GetMimeTypeforExtension . . . . . . . . . . . . . . . . . . . . . . . . 92 7
  8. Inhaltsverzeichnis GetSystemLang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 RPos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 StripHTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 StrTimeToValue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 SystemUserName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 6.4 uFileMisc.pas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.4.1 Beschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.4.2 Typendefinitionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.4.3 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 SearchFile Variante 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 SearchFile Variante 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.4.4 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 7 Beispiele 97 7.1 Datenbanken MySQL 5.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 7.1.1 Demodatenbank MySQL . . . . . . . . . . . . . . . . . . . . . . . . . 97 Installieren von MySQL 5.x . . . . . . . . . . . . . . . . . . . . . . . 97 Erstellung der DEMO Datenbank . . . . . . . . . . . . . . . . . . . . 98 Windows FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7.1.2 Projekt MySQLSimple . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7.1.3 Projekt MySQLTestData . . . . . . . . . . . . . . . . . . . . . . . . . 104 7.2 Datenbanken SQLite 3.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 7.3 Datenbanken DBase, FoxPro . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 8 Programme 109 8.1 Nützliche Werkzeuge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 8.1.1 Versionskontrolle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 svn Kommandozeile . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 8.1.2 Tool Versionenselektierer . . . . . . . . . . . . . . . . . . . . . . . . . 111 Was macht das Tool eigentlich? . . . . . . . . . . . . . . . . . . . . . 111 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 9 Anhang 113 9.1 Tabellenverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 9.2 GNU Free Documentation License . . . . . . . . . . . . . . . . . . . . . . . . 116 GNU Free Documentation License 116 1. APPLICABILITY AND DEFINITIONS . . . . . . . . . . . . . . . . . . . . . . 116 2. VERBATIM COPYING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 3. COPYING IN QUANTITY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 4. MODIFICATIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 5. COMBINING DOCUMENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 6. COLLECTIONS OF DOCUMENTS . . . . . . . . . . . . . . . . . . . . . . . . 120 7. AGGREGATION WITH INDEPENDENT WORKS . . . . . . . . . . . . . . . . 121 8
  9. Inhaltsverzeichnis 8. TRANSLATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 9. TERMINATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 10. FUTURE REVISIONS OF THIS LICENSE . . . . . . . . . . . . . . . . . . . . 121 ADDENDUM: How to use this License for your documents . . . . . . . . . . . . . 122 9
  10. 1 Lazarus Pascal 1.1 Anweisungen, Verzweigungen, Schleifen Vorbereitung Bei den hier verwendeten Beispielen handelt es sich um ein neu erstelltes gra- fisches Projekt mit einem Formular mit dem Namen „TestForm“ und einem darauf plazierten Button mit dem klingenden Namen „Button1“. Die Ereignisroutine „Button1Click“ wird durch ein doppelclicken auf den Button automatisch von Lazarus erzeugt. 1.1.1 Anweisungen Einleitung Ein Programm besteht aus einer Reihe von Anweisungen1 . Diese werden zur Lauf- 1 zeit nacheinander ausgefü 4 hrt. Und zwar werden Anweisungen immer von links nach rechts und von oben nach unten durchgeführt. Um diesen Ablauf zu durchbrechen gibt es zusätzlich auch noch Verzeigungen und Schleifen. Anweisungen werden immer mit einem Beistrich2 abgeschlossen. Ausnahmen sind, unmittel- bar vor einem Blockende und am Ende einer Unit - dort wird ein Punkt gesetzt. Block Bildung Anweisungen werden immer in Blöcken zusammengefasst. Dieser Block wir mit begin eingeleitet und mit end abgeschlossen. Zusätzlich bildet die Schleife repeat ... until und die Verzweigung case ... end auch automatisch einen Block. begin ..... Anweisungen ... end; Die Anweisungen zwischen begin und end werden wie eine einzelne Anweisung betrachtet. Das wird dann bei Schleifen und Verzweigungen verwendet. Blöcke können verschaltelt werden, die Blockgrenzen dürfen sich aber nicht schneiden. Daher ein end schliesst immer das letzte begin. Das folgende Beispiel demonstriert wie es richtig ist, denn der zweite Block befindet sich komplett innerhalb des ersten Blockes. begin Anweisung1; ... Anweisungen Block 1.Stufe... Anweisung2; begin AnweisungA; 1 Englisch: Statement 2 Semikolon „;“ 10
  11. 1 Lazarus Pascal ... Anweisungen Block 2.Stufe... AnweisungB; AnweisungC <- keine Strichpunkt notwendig end; Anweisung3; ... Anweisungen Block 1.Stufe... Anweisung4; Anweisung5 <- keine Strichpunkt notwendig end; 1.1.2 Verzweigungen Einleitung Verzweigungen dienen zum Unterbrechen des geradlinigen Ablaufes und zum treffen von Entscheidungen. Bedingte Verzweigungen Bei den bedingten Verzweigungen wird eine Bedingung als Ent- scheidung genommen, wohin sich der Programmablauf verzweigt. if then else Bei if Bedingung then Anweisung; wird abgeprüft ob eine Bedingung, die boolsch3 sein muß, den Wert true angenommen hat. Wenn nicht so wird die Anweisung nicht durchgeführt. Im folgenden Beispiel kann die Bedingung nie Wahr4 werden und somit wird die Hinweisbox5 nie am Bildschirm angezeigt, da die ANweisung einfach übersprungen wird. procedure TTestForm.Button1Click(Sender: TObject); var i : integer; begin i := 0; if i=1 then showmessage(’Geht nicht’); end; Wenn man sowohl den Fall behandeln will, das die Bedingung wahr ist, als auch den Fall, das es nicht so ist, kann man die if Bedingung then Anweisung1 else Anweisung Verzweigung nehmen. procedure TTestForm.Button1Click(Sender: TObject); var i : integer; begin i := 0; if i=1 then showmessage(’Geht nicht’) else showmessage(’Geht doch’) end; 3 bei boolscher Logik gibt es nur True und False 4 den Wert True annehmen 5 Die Anweisung showmessage() erzeugt eine Hinweisbox am Bildschirm 11
  12. 1 Lazarus Pascal Hier wird dann im else Zweig der Bedingung die Hinweisbox mit dem Text „Geht doch“ ange- zeigt. Bis jetzt konnte das Beispiel nur unterscheiden ob die Variable „i“ gleich 1 ist oder nicht. Will man mehere Werte von„i“ abprüfen so muß man die Verzweigungen entsprechend verschachteln. Im folgend Beispiel prüfen wir die Zahlen von null bis zwei ab, alles andere wird als unbekannt bewertet. procedure TTestForm.Button1Click(Sender: TObject); var i : integer; begin i := 2; if i=0 then showmessage(’i=0’) else if i=1 then showmessage(’i=1’) else if i=2 then showmessage(’i=2’) else showmessage(’Wert unbekannt’); end; Es gibt im folgenden eine einfachere Art solche Verzweigungen zu behandeln, wenn aber die case Verzweigung nicht verwendet werden kann, so ist es mit Hilfe des obigen Beispiels möglich das case nachzubauen. case Bei case wird ein so gennanter Selektor eingesetzt, anhand dessen entschieden wird, welcher Zweig genommen wird. Der Selektor darf aber nur ein ordinaler Typ6 sein. procedure TTestForm.Button1Click(Sender: TObject); var i : integer; begin i := 2; case i of 0 : showmessage(’i=0’); 1 : showmessage(’i=1’); 2 : showmessage(’i=2’); else showmessage(’Wert unbekannt’) end; end; Unbedingte Verzweigungen goto und label Der Befehl goto ... mit nachgestellter Sprungmarke, bewirkt das die Abarbei- tung der Befehle an der Stelle weitergeführt wird, wo sich die Sprungmarke befindet. Der Befehl kann nur lokal springen. Das heisst die Sprünge müssen sich innerhalb derselben Prozedur oder 6 Byte, Word, Integer, Char siehe auch Kapitel Datentypen 12
  13. 1 Lazarus Pascal Funktion bewegen. In einigen Fällen kann er die Lesbarkeit und Funktion von Programmenteilen erhöhen. Im Normalfall wird der Befehl nicht benötigt. Es muß ein Label deklariert werden, bevor es innerhalb der Prozedure oder Funktion verwen- det werden kann, dieses Label dient als Sprungmarke. procedure TTestForm.Button1Click(Sender: TObject); var i : integer; label hier; begin i := 2; goto hier; .... .... hier: i := 3; end; Exit Exit7 bewirkt das die aktuelle Funktion oder Prozedure beendet wird, ohne das nachfol- gende Befehle abgearbeitet werden. Es ist vergleichbar mit einem Goto, wobei die Sprungmarke unmittelbar vor dem letzen end sich befindet. In dem Beispiel wird die case Anweisung nicht bearbeitet, solange „i“ den Wert drei hat. procedure TTestForm.Button1Click(Sender: TObject); var i : integer; begin i := 3; if i=3 then exit; case i of 0 : showmessage(’i=0’); 1 : showmessage(’i=1’); 2 : showmessage(’i=2’); else showmessage(’Wert unbekannt’) end; end; 1.1.3 Prozeduren und Funktionen Einleitung Durch das Schreiben von Routinen, das sind Prozeduren und Funktionen, kann man sich den Funktionsumfang den Lazarus hat, selbst erweitern. Das Wesen von Routinen ist, Anweisungen die immer wieder in fast gleicher Weise verwendet werden, zusammenzufassen und an einer Stelle zu warten. Es ist wird so der Quelltest auch leichter lesbar und vor allen wird der Code auch leichter zu warten. Eine Verbesserung muss nicht an etlichen Stellen im Code durchgeführt werden. So kann man auch keine Stellen zu ändern vergessen. Der Code liegt an einer Stelle. 7 Wird bei Schleifen auch verwendet, wirkt dort nur auf den lokalen Block 13
  14. 1 Lazarus Pascal Funktionen Funktionen sind eine geblockte, gekapselte Ansammlung von Anweisungen. Zusätzlich gibt die Funktion einen (aber nur einen !) Wert zurück. Sie kann somit im Programm wie eine Variable verwendet werden. Im folgenden Beispiel schreiben wir eine Funktion mit dem Namen „MyFunction“ die zwei Zahlen addieren soll. Dazu definieren wir den Funktionskopf. Die Variablenliste mit den Para- metern „a“ und „b“ definieren wir von Typ Integer und zusätzlich das die Funktion ein Ergebnis auch vom Typ Integer zurückgibt. In den die Funktion begrenzenden begin ... end Block, kön- nen wir jetzt unsere Anweisungen hineinschreiben. Der automatisch Variablen result übergeben wir den Wert der Berechnung. Beim Aufruf der Funktion übergeben wir die Parameter „i1“,„i2“ und das Ergebnis speichern wir in der Variablen „erg“ ab. In der nächsten Zeile wird der Wert der Variablen „erg“ in eine Zeichkette umgewandelt und in einer Hinweisbox ausgegeben. function MyFunction(a,b : integer):integer; begin result := a + b end; procedure TTestForm.Button1Click(Sender: TObject); var i1,i2,erg : integer; begin i1 := 2; i2 := 3; erg := MyFunction(i1,i2); showmessage(’Ergebnis=’ + IntToStr(erg)) end; Prozeduren Prozeduren sind eine Sonderform der Funktion. Sie sind komplett gleich, bis auf die Tatsache, das eine Prozedure kein Ergebnis zurückliefert. Das Beispiel ist gleich zum obigen, mit dem Unterschied, das die Ausgabe in die Hinweisbox jetzt über eine Prozedure abläuft. function MyFunction(a,b : integer):integer; begin result := a + b end; procedure MyHinweisBox(a:integer); begin showmessage(’Ergebnis=’ + IntToStr(a)) end; 14
  15. 1 Lazarus Pascal procedure TTestForm.Button1Click(Sender: TObject); var i1,i2,erg : integer; begin i1 := 2; i2 := 3; erg := MyFunction(i1,i2); MyHinweisBox(erg) end; Parameterliste Die Parameter dienen dazu, um Daten in die Funktion bzw. Prozedure zu übertragen und auch in der anderen Richtung von diesen zu erhalten. In den bisherigen Beispielen zu Funktionen und Parameter ist nur die Richtung in die Funktion oder PArameter betrachtet worden. Bei der Defi- nition werden gleichartige Parameter durch einen Beistrich, ansonsten durch einen Strichpunkt getrennt. Beim Aufruf werden die Parameter einfach durch Beistriche getrennt angegeben. Die Reihenfolge der Parameter ist bindend. procedure MyProc(param1,param2 : integer; param3 : single); begin // ... einige sinnvolle Anweisungen end; procedure TTestForm.Button1Click(Sender: TObject); begin MyProc(11,30,12.5); end; Parameterübergabe bei Wert Wenn der Parameter als Wert übergeben wird, so wird der Inhalt des übergebenen Wertes kopiert und diese Kopie der Funktion oder Prozedur zur Verfügung gestellt. Änderungen am Wert inner- halb der Funktion werden deshalb nur auf der Kopie gemacht und haben keine Auswirkung auf den Originalwert ausserhalb der Funktion oder Prozedure. procedure MyProc(param1: integer); begin // ... einige sinnvolle Anweisungen param1 := param1 + 5; showmessage(’Wert in MyProc ist ’ + IntToStr(param1)); //<-- Anzeige ist 6 end; procedure TTestForm.Button1Click(Sender: TObject); var iWert : integer; begin 15
  16. 1 Lazarus Pascal iWert := 1; showmessage(’Wert vorher ist ’ + IntToStr(iWert)); //<-- Anzeige ist 1 MyProc(iWert); showmessage(’Wert nachher ist ’ + IntToStr(iWert)); //<-- Anzeige ist 1 end; Anhand diese Beispieles sieht man, das der Wert innerhalb meiner Prozedure zwar geändert wird, es aber keinerlei Auswirkung auf den Wert in der aufrufenden Prozedur hat. Parameterübergabe bei Referenz Bei der Parameterübergabe als Referenz, wird nicht der Wert selbst sondern eine Referenz8 übergeben. Dadurch das keine Kopie erstellt wird, sondern auf eine Variable refernziert wird, betreffen Änderungen sehr wohl die ursprüngliche Variable. procedure MyProc(var param1: integer); begin // ... einige sinnvolle Anweisungen param1 := param1 + 5; showmessage(’Wert in MyProc ist ’ + IntToStr(param1)); //<-- Anzeige ist 6 end; procedure TTestForm.Button1Click(Sender: TObject); var iWert : integer; begin iWert := 1; showmessage(’Wert vorher ist ’ + IntToStr(iWert)); //<-- Anzeige ist 1 MyProc(iWert); showmessage(’Wert nachher ist ’ + IntToStr(iWert)); //<-- Anzeige ist 6 end; Bei dieser Art der Parameterübergabe ist aber eine Variable notwendig und es kann kein fester Wert verwendet werden. Das folgende Beispiel ist deshalb nicht erlaubt. procedure MyProc(var param1: integer); begin // ... einige sinnvolle Anweisungen param1 := param1 + 5; showmessage(’Wert in MyProc ist ’ + IntToStr(param1)); end; procedure TTestForm.Button1Click(Sender: TObject); begin MyProc(5); end; 8 auch oder Zeiger, Pointer genannt 16
  17. 1 Lazarus Pascal Es wird mit folgender Meldung richtigerweise zurückgewiesen, da aus einem festen Wert der Kompiler keine Referenz bilden kann. umain.pas(39,11) Error: Variable identifier expected umain.pas(30,11) Hint: Found declaration: MyProc(var LongInt) umain.pas(47) Fatal: There were 1 errors compiling module, stopping Parameterübergabe von Objekten und Klassen Objekte und Klassen werden immer als Referenz übergeben, das heisst Änderungen werden immer auf der Klasse oder Objekt durchgeführt und keine Kopien davon angelegt. Überladen von Funktionen Funktionen und Prozeduren können auch überladen werden, das heisst es gibt mehrer Versionen einer gleichnamigen Funktion oder Prozedure aber mit unterschiedlichen Parameterliste. In dem Beispiel wird die Funktion ’ToString’ mit verschiedenen Parametertypen überladen. Zuerst mit boolschen Paramater, dann mit einem Integer Parameter und zum Schluß mit einem Double Parameter. Die funktionköpfe sehen fast gleich aus, aber durch die verschiedene Parama- tertypen kann der Compiler das sehr wohl auseinander halten und richtig zuweisen. function ToString(value:boolean):string; begin if value then result := ’true’ else result := ’false’; end; function ToString(value:integer):string; begin result := IntToStr(value); end; function ToString(value:double):string; begin result := FloatToStr(value); end; Hier sieht man dann sehr gut, das der Compiler immer die richtige Version der Funktion an- hand des Types auswählen kann. Beim drücken des Button 1 wird im Editfeld der Text ’true’ eingetragen. Bei den anderen Buttend er entsprechnde Wert im Editfeld angezeigt. procedure TForm1.Button1Click(Sender: TObject); begin edit1.Text:= ToString(true); end; 17
  18. 1 Lazarus Pascal procedure TForm1.Button2Click(Sender: TObject); begin edit1.text := ToString(10); end; procedure TForm1.Button3Click(Sender: TObject); begin edit1.text := ToString(11.01); end; 9 Version: $LastChangedRevision: $ 9 Autor: Andreas Frieß Lizenz: GFDL 18
  19. 1 Lazarus Pascal 1.2 Variablen, Konstanten, Datentypen Ein großer Teil der hier verwendeten Definitionen und Texte stammen aus dem ’Language Re- ference Guide[FPCLangRef]’. Es handelt sich hier nicht um eine exakte Übersetzung, sondern um eine für dieses Buch angepasste Form. 1.2.1 Konstanten Bei Konstanten muß der Kompiler zur Kompilierzeit fähig sein, den Term aufzulösen. Das heisst das sehr viele Funktionen die nur zur Laufzeit zur Verfügung stehen nicht verwendet werden können. Die folgenden Operatoren können immer verwendet werden „- +, -, *, /, not, and, or, div, mod, ord, chr, sizeof, pi, int, trunc, round, frac, odd“. Normale Konstanten Die Deklaration von Konstanten ist nur für Ordinale-, Reale-, Char- und Stringtypen erlaubt. const co_real = 3.14; { Reale Typen Konstante } co_int = 25; { Integer Typen Konstante } co_char = ’A’; { Character Typen Konstante } co_str = ’Irgend ein String’; {String Typen Konstante} co_ls = SizeOf(Longint); co_ls_real = SizeOf(co_real); Eine Zuweisung10 an die Konstante ist nicht möglich. co_str := ’Ein anderer String’; Das ist bei normalen Konstanten nicht erlaubt und wird mit der Fehlermeldung xxx.pas(47,11) Error: Variable identifier expected quittiert. Die Fehlermeldung resultiert daher, das zwar eine Konstante mit dem Namen existiert, aber keine Variable. Typisierte Konstanten Typisierte Konstanten sind ein Weg um das Programm mit initialisierten Variablen zu versorgen. Im Gegensatz zu normalen Variablen, wo der Programmiere sich um die Initialisierung selbst kümmern muß, wird ihr Wert initialisiert wenn das Programm startet. Anders als bei normalen Konstanten kann ihnen zur Laufzeit neue Werte zugewiesen werden. const co_char : char = ’A’;{Character Typen Konstante} co_str : string = ’Irgendein String’;{String Typen Konstante} Somit ist das gültiger Code. 10 Nur mit typisierten Konstanten möglich 19
  20. 1 Lazarus Pascal co_str := ’Ein anderer String’; Typisierte Konstanten werden oft benutzt um Arrays und Records zu initialisieren. const co_tt : array [1..3] of string[20] = (’Mike’, ’Ros’, ’Heh’); co_ti : array [1..3] of Longint = (1,2,3); Bei Arrays müssen die initialen Werte in runden Klammern angegeben werden, mit Kommas getrennt und die Anzahl der Elemente muß genau gleich sein, als die Anzahl der Elemente in der Deklaration. type Point = record X,Y : Real end; const aOrigin : Point = (X:0.0; Y:0.0); In typisierten Recordkonstanten, muß jedes Element des Records spezifiziert sein und zwar in der Form: Feldname, Doppelpunkt, Werte getrennt durch Strichpunkt und das ganze von runden Klammern umschlossen. Die Felder müssen in der Reihenfolge in der Deklaration verwendet werden, ansonsten gibt es eine Kompiler Fehlermeldung xxx.pas(47,11) Error: Some fields co- ming before quot;Yquot;weren’t initialized Resourcen Strings Sie verhalten sich Grundlegend wie normale Konstanten, es aber nur der Typ Strings zugelassen. Zusätzlich sind sie nur im Modus objfpc und Delphi erlaubt. Resourcen Strings sind in erster Linie dazu da, um die Internationalisierung einfacher zu gestalten und einen einheitliche Weg für das behandeln von konstanten Strings zu haben. Die Strings werden dazu in eigene Dateien abgelegt, auf die dann über ein Programmierin- terface zur Laufzeit zugegriffen werden kann. Dadurch können Strings für die Übersetzung be- nutzt werden. Ausserdem kommen mit dem Free Pascal Kompiler Werkzeuge um die Resourcen Strings zu bearbeiten und in andere Formate (Linux, Windows, ...) zu konvertieren. Resourcestring FileMenu = ’&File...’; EditMenu = ’&Edit...’; 1.2.2 Variablen Begriff Eine Variable ist eine genau bekannter Speicherbereich mit einem bestimmten Typ. Wenn Werte einer Variablen zugewiesen werden, so erzeugt der Free Pascal Compiler Maschinenkode um 20
  21. 1 Lazarus Pascal den Wert zu dem reservierten Speicherbereich zu transportieren. Wo sich die Variable befindet, ist vom Ort der Deklarierung abhängig. Globale Variablen Sind Variablen die innerhalb einer Unit oder Programmes definiert sind, aber NICHT innerhalb von Prozeduren oder Funktionen. Diese werden auf fixen Speicher- bereichen gelegt und sind während der ganzen Programmbearbeitung verfügbar. Lokale Variablen Sind innerhalb von Prozeduren oder Funktionen definiert. Sie werden auf den Stack, daher nicht auf einen fixen Speicherbereichen gelegt. Beim FPC und somit auch innerhalb von Lazarus ist das bereitstellen der Speicherbereiche komplett transparent11 . Das Hantieren (Schreiben, Lesen) mit den Werten erfolgt ebenfalls trans- parent, kann aber explizit durch den Programmierer vorgegeben werden, durch das verwenden von Eigenschaften(Properties). Variablen müssen extra deklariert werden, wenn sie gebraucht werden. Es wird solange kein Speicherbereich zur Verfügung gestellt, bis die Variable deklariert ist. Wird eine Variable ver- wendet die nicht zuerst deklariert ist, so wird vom Compiler eine Fehlermeldung erzeugt. Deklaration Hier ist Platz für Informationen zum Thema. Ich bin leider noch nicht soweit. 1.2.3 Initialisierung Variablen, wie auch andere Indentifizierer gehorchen den generellen Regeln der Gültigkeit. Zu- sätzlich werden die zu inititialisierten Variabeln zur folgenden Zeit initialisiert. Globale initialisierte Variablen Werden einmalig initialisiert wenn des Programm startet. Lokale initialisierte Variablen Werden jedes mal initialisiert wenn die Funktion oder Prozedur ausgeführt wird. Man beachte das das Verhalten von lokal initialisierten Variablen ein anderes ist, als von lokal definierten Konstanten. Eine lokal definierte Konstante verhält sich wie eine global initialisierte Variable. Welche Variablen werden überhaupt, wie initialisiert ? AnsiString teilweise Der Platz für den Pointer wird erstellt und mit nil vorbelegt. Gültig nur für globale und lokale AnsiStrings, die ein Teil einer Struktur sind (Statische Arrays, Records und Objekte). Typisierte Konstanten Verhält sich wie eine Globale initialisierte Konstante, wird einmalig initialisiert wenn des Programm startet, auch wenn sie sich Lokal in einer Prozedur oder Funktion befindet. 11 Für den Programmierer nicht sichtbar, im Hintergrund 21
  22. 1 Lazarus Pascal Es werden die meisten Variablen aus Geschwindigkeitsgründen nicht initialisiert. Folgendes soll als Beispiel dienen. var anArray : array[1..100000] of string; Bei dieser Deklaration wird, wenn die Variable initialisiert wird, hunderttausend Mal der Wert nil in das Array geschrieben. Das braucht seine Zeit, auch wenn die noch so kurz ist. Befindet sich der Code in einer Prozedur oder Funktion, die in einer Schleife aufgerufen wird, so kann der Zeitaufwand dafür erheblich werden. 1.2.4 Datentypen ToDo: Hier ist Platz für Informationen zum Thema. Ich bin leider noch nicht soweit. Version: $LastChangedRevision: $ 12 12 Originalautor: Michaël Van Canneyt, Lizenz: free Übersetzung und Bearbeitung: Andreas Frieß 22
  23. 1 Lazarus Pascal 1.3 Objekte 1.3.1 Was ist ein Objekt Was ist ein Objekt, eine gute Frage. Nähern wir uns einmal dem Begriff indem wir ein Objekt be- schreiben. Ein Objekt hat Eigenschaften und kann Aktionen durchführen, weiters beinhaltet es Daten zum Verwalten seiner Zustände. Außerdem muß das Objekt auch einen Namen besitzen. Wie definieren wir ein Objekt? Unter (Lazarus) Pascal verwenden wir dazu die Klassendefinition class. TMyObject = class end; Mit diesen Zeilen kann mal ein grundlegendes Objekt definieren. Es hat einen Namen, aber kann weder Aktionen durchführen, noch hat es Eigenschaften, aber es ist das minimalste Beispiel. In unseren Fall hat das Objekt den Namen „TMyObject“. Sehen wir uns jetzt eine volle Definition an. { TMyGreatObject } TMyGreatObject = class(TParentObject) private FIsValid: Boolean; procedure SetIsValid(const AValue: Boolean); protected function GetWert: integer; procedure SetWert(const AValue: integer); public constructor Create; override; destructor Destroy; override; published property IsValid : Boolean read FIsValid write SetIsValid; property Wert : integer read GetWert write SetWert; end; var aMyGreatObject : TMyGreatObject; Mittels der Klassendefinition class(TParentObject)definieren wir ein Objekt mit dem Namen TMyGreatObject, das alle Eigenschaften, Aktionen etc. vom Elternobjekt erbt. Das heißt alles was das Elternobjekt kann oder hat, hat unser Objekt auch. Durch die Deklarationen private, protected, public und published wird die Sichtbarkeit der Eigenschaften und Aktionen definiert. private Nur hier in dieser Deklaration kann auf diese Eigenschaften und Aktionen zugegriffen werden protected Wie private, zusätzlich kann auch bei Kindobjekten auf die Eigenschaften und Ak- tionen zugegriffen werden 23
  24. 1 Lazarus Pascal public Auf die Eigenschaften und Aktionen kann immer zugegriffen werden published Wie public zusätzlich sind die Eigenschaften auch im Objektinspektor verfügbar Im private Teil ist eine Boolsche-Variable und eine Prozedur zum Ändern der Variablen definiert. Generell ändert man den Wert einer Variablen nicht direkt, sondern verwendet eine Prozedur dazu, in der auch eventuell die nötigen Prüfungen oder Bearbeitungsschritte durchgeführt wer- den. Als Namen für die Prozeduren13 und Funktionen14 die interne Variablen ändern haben sich GetXXXX 15 und SetXXXX durchgesetzt. Das setzt sich auch im protected Abschnitt fort. Im public Bereich sind die Konstruktoren (immer Create16 ), Destruktoren (immer Destroy) und die von ausserhalb sichtbaren Variablen17 , Eigenschaften, Prozeduren und Funktionen. 1.3.2 Zur Laufzeit erzeugen und zerstören Gerade am Anfang erweist sich das richtige Erzeugen und Löschen von Objekten als Problem. Denn die Zuweisung mittels var aListe : TStringList; reicht nicht aus. Damit wird nur der Platz für den Verweis auf das Objekt erzeugt, nicht aber das Objekt selbst! Zu diesem Zeitpunkt ist das Objekt, in diesem Fall eine Stringliste nicht in einem gebrauchsfähigen Zustand, der Verweis ist undefiniert (und zeigt ins Nirgendwo). Deshalb wird auch eine Anweisung wie aListe.Create nicht funktionieren und eine Exception auslösen. Wie geht es also richtig. Alle Objekte haben einen Konstruktor, entweder direkt in der Klasse oder in einem Vorfahren, der aufgerufen werden kann und der das Objekt richtig erstellt und uns den richtigen Verweis zurück liefert, den wir dann in unserer Variablen ablegen können. procedure TForm1.buObjektClick(Sender: TObject); var aListe : TStringList; begin aListe := TStringList.Create; try aListe.Add(’Eine Zeile’); aListe.Add(’Eine zweite Zeile’); aListe.Add(’Eine dritte Zeile’); Memo1.Lines.Assign(aListe); finally aListe.Free; end; end; Sehen wir uns den Beispielcode18 einmal von oben nach unten an. 13 Zum Setzen 14 Zum Abfragen 15 Auch Getter und Setter genannt 16 manchmal kommen Namensabwandlungen vor 17 Variablen macht man normalerweise über Eigenschaften zugänglich 18 Aus dem Projekt: BspObjErzeug 24
  25. 1 Lazarus Pascal var aListe : TStringList; Definieren einer Variable für den Verweis auf ein Objekt von Typ TStringlist aListe := TStringList.Create; Erzeugen des Objektes und initialisieren der Variablen mit dem Verweis aListe.Add(’Eine Zeile’); Einfügen eines Strings in die Stringliste Memo1.Lines.Assign(aListe); Füllen des Memos mit den Strings aus der Stringliste aListe aListe.Free; Freigeben des Objektes Stringliste durch aufruf von Free. Nach dem Aufruf von Free ist der Inhalt der Variablen aListe nicht mehr definiert! Free ruft den Destruktor des Objektes auf. Der Inhalt zeigt jetzt auf kein gültiges Objekt mehr und enthält einen beliebigen Inhalt, er ist nicht Null oder nil. Zusätzlich ist mit der Exceptionbehandlung try..finally..end sichergestellt, daß das Objekt si- cher zerstört wird, auch wenn innerhalb des try..finally Blocks ein Fehler aufgetreten ist. Das zwischen dem finally..end eingegrenzte Anweisung wird in jedem Falle ausgeführt. 1.3.3 Was sollte man unterlassen Es gibt bei Klassen immer wieder Kode, den man besser nicht schreiben sollte. Ich werde hier versuchen Beispiele zu bringen, meistens werden sie aus dem Forum stammen. Erzeugung von Speicherleichen (Memoryleaks) 19 Eine einfacher Weg um Speicherleichen zu erzeugen ist das ’wilde’ zuweisen von Klassen. Meistens wird der Gedanke aus einer vermeintlichen Abkürzung im Kode geboren. Bei der Deklaration ist ja noch alles in Ordnung. Obj1 : TObject; Obj2 : TObject; Ôbj1,2 sind nur Zeiger die im Moment auf irgendwas zeigen wenn man drauf zugreifen will gibt es eine Zugriffsverletzung (’Access violation’), weil das Objekt ja noch nicht erstellt wurde. Obj1 := TObject.Create; Obj2 := TObject.Create; jetzt zeigen unsere Zeiger auf die Objekte die erstellt wurden und die Objekte sind jetzt auch benutzbar. Wenn man jetzt aus welchen Grund auch immer die folgende Zuweisung macht, hat man eine Leiche erschaffen. Obj1 := Obj2; 19 Basierend auf Informationen von christian[11] im deutschen Lazarusforum 25
  26. 1 Lazarus Pascal Mit dieser Zuweisung zeigen beide Zeiger auf Obj2. Obj1 kann nie wieder benutzt werden, da jegliche Referenzierung darauf verschwunden ist. Somit kann Obj1 auch nicht mehr gelöscht und der Speicherplatz frei gegebnen werden, wie im folgenden Kode. Obj1.Free; Obj2.Free; Das erste Obj1.Free wird anstandslos ausgeführt, da ja in Wirklichkeit das Obj2 freigegeben wird und nicht das ursprüngliche Obj1 - das ist ja in Vergessenheit geraten. Das nachfolgende Obj2.Free erzeugt jetzt eine Zugriffsverletzung, da das Objekt ja bereits freigegeben wurde und das ursprüngliche Obj1 ist eine Leiche (im Speicher-Keller). 20 Version: $LastChangedRevision: 59 $ 20 Autor: Andreas Frieß Lizenz: GFDL 26
  27. 2 Grundlagen Datenbank 2.1 Datenbanken 2.1.1 Einführung in die Datenbanktheorie Das Folgende Kapitel wendet sich speziell an den Personenkreis der in die Theorie von Daten- banken noch nicht so eingedrungen ist, beziehungsweise dient als Nachschlagwerk für die ver- schiedenen Begriffe. Man kann also bei entsprechenden Vorwissen die folgenden erklärenden Kapitel überspringen und bei Bedarf nachschlagen. Begriffe Um Missverständnisse auszuschließen und zu einer gemeinsamen Sprachregelung zu kommen, sollte man die verwendeten Begriffe möglichst genau definieren: • Eine Datenmenge ist eine Menge von einzelnen Datensätzen. Jeder Datensatz besteht aus mindesten einem Feld. Die Herkunft dieser Datenmenge ist nicht festgelegt. • Eine Tabelle ist als Datenbankbestandteil eine spezielle Ausführung einer Datenmenge. Die Tabelle speichert als physisches vorhandenes Element die Daten. • Eine Abfrage ist eine virtuelle Datenmenge, die den Inhalt von tatsächlich vorhandenen Tabellen in einer frei wählbaren Anordnung abbildet, manchmal auch Projektion genannt. • Eine Datenbank ist eine Zusammenstellung von logisch zusammengehörigen Tabellen. • Ein Datenbankserver verwaltet verschiedene Datenbanken und stellt auch das Manage- ment, die Sicherung und andere Verwaltungsdienste zur Verfügung. Wichtige Informationen bei der Entwicklung einer Datenbankanwendung sind das Verhalten der Datenbank bzw. des Datenbankservers selbst. Was ist eine Datenbank Eine Datenbank ist eine geordnete Sammlung von Daten, die auf irgendeine Weise miteinander in Beziehung stehen. Die ersten Generationen von Datenbanken waren sogenannte File-Systeme. Zuerst auf Band, dann auch auf Festplatten. In diesem Datei-Systemen wurden die Daten nacheinander abgespei- chert. Um auf einen bestimmten Datensatz zu zugreifen, muss man an den Anfang der Datei (oder Bandes) gehen und anschließend alle Datensätze durchlaufen, bis man den richtigen ge- funden hat. Somit ist auch klar, das ein einfaches sortieren oder einfügen von Daten in eine 27
  28. 2 Grundlagen Datenbank sortierte Datenmenge enormen Aufwand und Kapazität erfordert hat. Um diesen Beschränkun- gen zu entfliehen, (und durch neue, schnellere und größere Festplatten ermöglicht) haben sich aus diesen System die heutigen relationalen oder objektorientierten Datenbanken entwickelt. Die derzeit am meisten verwendeten Datenbanken sind die relationalen und im weiteren werde ich nur noch diese behandeln. Desktop und Client-Server Datenbankarten Gerade der Begriff Netzwerkdatenbank ist sehr verwirrend. Wird damit eine Access-Datenbank, die mehrere Benutzer über das Netzwerk verwenden so bezeichnet ? Oder eine Serverbasierende Datenbank? Die folgenden Erklärungen sollten die Begriffe klarer werden lassen. Stand-Alone Datenbank Eine Stand-Alone Datenbank ist eine Desktop-Datenbank, es be- finden sich daher die Daten auf dem Arbeitsplatzrechner. Auf die Daten kann immer nur ein Anwender, mit immer nur einem Programm zugreifen. Es ist zwar prinzipiell möglich über ein Netzwerk auf die Datenbankdatei zuzugreifen, aber es kann der eine nur in der Datenbank ar- beiten, wenn der andere sein Programm geschlossen hat. Probleme die durch den gleichzeitigen Zugriff entstehen können daher gar nicht auftreten. Bei jeder etwas umfangreicheren Datenbank wird dieses Verhalten zu einem Engpass. Man stelle sich nur vor, der eine Benutzer öffnet die Datenbankdatei und vergisst auf das schließen des Programms. Kein anderer Benutzer kann die Daten in der Zwischenzeit benutzen! File-Share Datenbank Moderne Netzwerke bieten die Möglichkeit, dass mehrer Anwender auf ein und dieselbe Datei zugreifen. Auf diese Weise ist es auch möglich das mehrer Program- me auf ein und dieselbe Datenbankdatei zugreifen. Diese Version der Desktop-Datenbank nennt man File-Share Datenbank und damit ist bereits ein echter Mehrbenutzer Betrieb möglich. Das ganze hat jedoch (unter anderem) einen entscheidenden Nachteil: Die Datenverarbeitung erfolgt auf den Arbeitsplatzrechnern. Für Abfragen muss der jeweilige ganze Datenbestand zu den Ar- beitsplatzrechnern gebracht werden, dementsprechend hoch ist die Belastung für das Netzwerk. Weiter können auch Störungen am Netzwerk leicht zu Datenverlust bzw. zu inkonsistenz der Datenbeständen führen. Client-Server Datenbank Bei Client-Server Datenbanken hat nur der Datenbankserver selbst direkten Zugriff auf die Dateien des Datenbestandes. Anfragen werden somit direkt an den Datenbankserver gestellt, von diesem bearbeitet und die Ergebnisse an den Arbeitsplatzrechner zurückgeliefert. Die Verwaltung beim gleichzeitigen Zugriff durch mehrer Arbeitsplatzrechner obliegt dem Datenbankserver. Falls eine Verbindung durch eine Störung abbricht, so wird dieses erkannt und die noch nicht kompletten Anfragen verworfen und somit die Konsistenz der Daten erhalten. Gerade zur File-Share Datenbank können Netzbelastungen drastisch gesenkt werden. Man stelle sich nur vor, das man den größten Wert aus einer unsortierten Tabelle mit 1 Mil- lionen Datensätze habe will. Bei der File-Share Datenbank müssen alle Datensätze geholt und bearbeitet werden, bei der Client Server Datenbank nur das Ergebnis. Weitere Bereiche sind die Möglichkeit Backups zu erstellen während die Datenbank weiter in Verwendung ist. 28
  29. 2 Grundlagen Datenbank Relationale Datenbanken Der Begriff relationale Datenbank geht auf einen Artikel von E. F. Codd zurück, der 1970 ver- öffentlich wurde. Codd bezeichnet Datenbanken als quot;minimal relationalquot;, wenn sie folgende Bedingungen erfüllen. [list] [*]Die Informationen werden einheitlich in Form von Tabellen re- präsentiert. [*]Der Anwender sieht keine Verweisstrukturen zwischen den Tabellen. [*]Es gibt mindestens die Operation der Selektion, der Projektion und des JOIN definiert. [/list] 1985 ver- öffentlichte Codd zwölf Regeln, die relationalen Datenbanken im strengeren Sinn definieren, Ende 1990 veröffentlichte er ein Buch über relationale Datenbanken, in dem er die einstigen zwölf Regeln des relationalen Modells auf 333 Regeln differenziert. Dadurch wird die Relatio- nalität einer Datenbank bis ins letzte Detail festgeschrieben Soweit die Theorie, normalerweise sprechen Hersteller von relationalen Datenbanken, wenn die Mehrheit der 12 Regeln eingehalten werden. Begriffe in relationalen Datenbanken Man kann nicht über relationale Datenbanken spre- chen, ohne zuvor einige Begriffe zu klären. Relationen Eine Relation ist gleich einer Tabelle. Die Daten werden daher in Relationen gespeichert. Attribut und Tuples Die Attribute sind die Spalten einer Relation (Tabelle), die Tuples sind die Datensätze. Degree und Kardinalität Die Zahl der Attribute einer Relation nennt man Degree, das ist der Ausdehnungsgrad. Die Zahl der Tuples ist die Kardinalität. Eine Relation mit Degree Null macht keinen Sinn, eine Kardinalität von NULL Tuples hingegen ist eine leere Relation. Domain Eine Domain ist ein Wertebereich. Man kann z.B. eine Domain Nachnamen vom Ty- pe „Zeichen mit Länge 20“ erstellen. Diese wird immer dann verwendet wenn man Datenspalten mit dem Type „Nachname“ erstellen muss. Warum dieser Umweg? Wenn man später Tabellen miteinander verknüpft (in Relation bringt), so müssen die Spalten (Attribute) der gleichen Do- main unterliegen. Habe ich vorher eine Domain definiert, so gibt es keine Probleme. Weiter ist es kein Problem wenn man draufkommt das die „Nachnamen“ länger sind, so kann die Defini- tion der Domain geändert werden und alle Spalten haben die richtige Länge. Würde ich beim händischen Editieren eine Spalte vergessen so würde die Datenbank nicht mehr korrekt arbeiten. NULL Ein „Nichtwert“ der anfangs immer für Verwirrung sorgt ist NULL. NULL ist nicht gleich Null! Ein besserer Ausdruck wäre UNBEKANNT. NULL macht übrigens aus einer zwei- wertigen Logik (Ja/Nein) eine dreiwertige (Ja/Nein/Unbekannt). Vorstellen kann man es sich am besten mit einem Beispiel. Jedem Konferenzraum kann ein Beamer mit seiner Nummer zugeteilt werden. Die Räume welche keinen Beamer besitzen (zuwenige Beamer vorhanden) bekommen als Wert NULL zugeteilt, da ja ein nicht vorhandener Beamer auch keine Nummer besitzt, folg- lich also unbekannt ist. 29
  30. 2 Grundlagen Datenbank Schlüssel Im Zuge der Normalisierung (welche später erklärt wird) werden die Daten auf viele Tabellen vereilt. Um dieses Tabellen wieder richtig in Relation zu bringen werden ver- schiedene Schlüssel, auch Keys genannt, verwendet. Primärschlüssel (Primary Key) Jede Relation (Tabelle) besitzt einen Primärschlüssel um einen Datensatz eindeutig zu identifizieren. Ausnahmen von dieser Regel gibt es nur bei „M:N Verknüpfungen“ für die Zwischentabellen verwendet werden (die meisten Datenbanksysteme können diese Verknüpfungen nicht direkt abbilden). Ein Primärschlüssel ist immer eindeutig und ohne Duplikate. Meistens wird dafür eine fortlaufende Nummer verwendet, ist aber nicht zwingend. Vorsicht bei bestimmten Fällen, denn selbst Sozialversicherungsnummern müssen nicht eindeutig sein ! Sekundärschlüssel (Secundary Keys) Werden dafür verwendet um bei bestimmten Da- tenbankoperationen die Effizienz zu steigern, da die Datensätze intern nicht ungeordnet sondern in sortierter Reihenfolge verwaltet werden. Beim verwenden sollte aber immer auf die zugrunde liegende Datenbank Rücksicht genommen werden, da die Vor- und Nachteile stark datenbankab- hängig sind. Fremdschlüssel (Foreign Key) Ist der Verweis in der Tabelle auf einen Primärschlüssel in einer anderen Tabelle. Gerade in relationalen Datenbanken gibt es sehr viele Verknüpfungen die auf Primär- und Fremdschlüsselpaaren aufbauen. Wichtig ist, das Primär- und Fremdschlüssel der gleichen Domain unterliegen. Referentielle Integrität Die referentielle Integrität stellt sicher das die Daten zueinander (über Primär- und Fremdschlüssel) glaubhaft bleiben. Ein einfügen, ändern oder löschen ist zu verweigern wenn dadurch die Datenintegrität verletzt würde. Man kann zum Beispiel keine Da- tensätze aus der Personentabelle löschen, solange in der Tabelle der Bestelllungen auf diese Personen verwiesen wird. Normalisierung Unter der Normalisierung einer Datenbank, wird die Technik des logischen Datenbankdesigns bezeichnet. Es erfolgt meistens durch das Schrittweise optimieren der Daten- bank zur Designzeit. Theoretiker haben insgesamt 5 Stufen der Normalisierung herausgearbeitet, wobei in der Praxis meist nur die ersten 3 Stufen verwendet werden. Warum wird meistens nur bis zur 3. Normalform normalisiert? Bei der Anwendungsentwick- lung besteht meistens nicht das Ziel, möglichst den exakten theoretische Grundlagen zu ent- sprechen, sondern eine möglichst effiziente Komplettlösung für das Problem zu erhalten. Dazu gehört natürlich auch, die Rücksicht auf das verwendete Datenbanksystem und die damit zu er- zielenden Performance. Es leuchtet jedem ein, das die Aufteilung der Informationen auf viele Tabellen bei einer Auswertung zu schlechteren Ergebnissen führt. Somit kann es sein, das in Teil- bereichen sogar eine Denormalisierung aus Performancegründen nötig ist, oder der gewonnene Platz bzw. das Geschäftsmodell keine Normalisierung sinnvoll erscheinen lassen. 30
  31. 2 Grundlagen Datenbank Ausgangslage Alle Informationen in einer Tabelle 1. Normalform Jede Spalte einer Tabelle enthält unteilbare Informationen. Die Da- tensätze verwenden keine sich wiederholenden Informationen, die nicht auch zu einer separaten Gruppe zusammengefasst werden könnten 2 Normalform Es wird die 1. Normalform eingehalten und alle Informationen in nicht Schlüsselfeldern hängen nur vom kompletten Primärschlüssel ab 3 Normalform Es wird die 2 Normalform eingehalten und alle Informationen in den nicht Schlüsselfeldern sind untereinander nicht abhängig. 4 Normalform Es wird die 3. Normalform eingehalten und in gleichen Tabellen sind keine unabhängigen Objekte vorhanden, zwischen denen eine m:n Beziehung bestehen könnte 5 Normalform Die normalisierte Datenbank kann nicht weiter in Tabellen mit we- niger Attributen konvertiert werden. Es muss sich jederzeit der un- normalisierte Ursprungszustand ohne Informationsverlust herstel- len lassen Tabelle 2.1: Datenbank Normalisierungstufen Übersicht Grunddaten Mit Grunddaten werden die Informationen bezeichnet, die Voraussetzung für die tägliche Arbeit sind und während des täglichen Betriebs anfallen. Sie stellen die Basis des Datenbanksystems dar. Die Grunddaten werden in zwei Kategorien, Stammdaten und Bewegungsdaten, eingeteilt. Stammdaten Stammdaten sind diejenigen Grunddaten, die über einen längeren Zeitraum be- nötigt werden. Sie bilden den Grundbestand an Daten für das Datenbanksystem und werden auch als Bestandsdaten bezeichnet. Stammdaten weisen eine geringe Änderungshäufigkeit auf. Üblicherweise ist bei der Neuanlage von Stammdaten noch nicht bekannt, wann Änderungen zu erwarten und wie lange die Daten insgesamt gültig sind. Da auf Stammdaten häufig zugegriffen wird, ist ihre aktuelle Pflege notwendig, so dass Änderungen unmittelbar im Datenbestand nach- gezogen werden sollten. Somit ist auch die normale Zugriffsart festgelegt, auf Stammdaten wir meistens in Verbindung mit Abfragen lesend zugegriffen, nur die Wartung erfolgt schreibend. Bewegungsdaten Im Gegensatz zu Stammdaten haben Bewegungsdaten eine begrenzte Le- bensdauer, die durch einen vorgegebenen Lebenszyklus beschrieben ist. Bewegungsdaten haben einen konkreten Zeitbezug, der für die Bedeutung und Interpretation der Information wichtig ist. Des weiteren beziehen sich Bewegungsdaten auf Stammdaten, weshalb sie auch als abgeleitete Daten bezeichnet werden. Da Bewegungsdaten gegenüber Stammdaten in der Menge mächtiger sind, ist gerade hier auf ein gutes Design zu achten. Betrachten wir es am Beispiel eines Zäh- lers einer Station: Die Zähler werden im 10 Minutenrhythmus in die Bewegungsdaten eingefügt, das sind 144 Datensätze pro Tag, währenddessen der Stammdatenteil gleich bleibt, nämlich 1 31
  32. 2 Grundlagen Datenbank Datensatz. 1 Version: $LastChangedRevision: 55 $ 1 Autor: Andreas Frieß Lizenz: GFDL 32
  33. 2 Grundlagen Datenbank 2.1.2 DDL Datendefinitionssprache Die Datendefinitionssprache (Data Definition Language = DDL2 ) umfasst die Sprachteile von Datenbanksprache, mit deren Hilfe man Datenstrukturen wie Tabellen und andere ähnliche Ele- mente erzeugt. Es sind das die Befehle die mit CREATE beginnen, zum Beispiel CREATE TA- BLE und CREATE INDEX. 2.1.3 DML Datenveränderungssprache Die Datenveränderungssprache (Data Manipulation Language = DML3 ) umfasst die Sprachteile von Datenbanksprache, die sich mit dem Lesen, Ändern und Löschen von Daten beschäftigen. Es sind das die Befehle SELECT, INSERT, UPDATE und DELETE. Im folgend sehen wir uns die wichtigsten Befehle an, wobei ein Befehl besonders mächtig ist—SELECT—. SELECT SELECT ist einer der Vielseitigsten und am meisten eingesetzten Befehle überhaupt. Er dient zum Abfragen von Datenmengen aus der Datenbank. Er ermöglicht die Abfrage von Daten aus den Tabellen (die Projektion) Einfachste Darstellung Bei der einfachsten Abfrage haben wir es mit wenigen Schlüssel- wörter zu tun. SELECT [DISTINCT] ’Auswahlliste’ FROM ’Quelle’ WHERE ’Where-Klausel’ [GROUP BY (’Group-by-Attribut’)+ [HAVING ’Having-Klausel’]] [ORDER BY (’’Sortierungsattribut’’ [ASC|DESC])+]; Mit SELECT wird die Abfrage eingeleitet, anschliessend kommt die Auswahlliste der gewünsch- ten Tabellenspalten. Dann das FROM , das angibt welche Tabellen die Daten bereitstellen und das WHERE, das angibt nach welchen Kriterien die Daten vorselektiert werden. SELECT ’Auswahlliste’ Hier gibt man die einzelnen Tabellenspalten an, die sich später in der rückgelieferten Datenmenge finden. Sind die Name nicht eindeutig genug, besonders wenn mehrere Tabellen betroffen sind, so muß man den Tabellennamen und eventuell auch die Da- tenbank angeben, sprich die Eindeutigkeit qualifizieren. Somit kann ein SELECT so aussehen: SELECT MyDB.STPerson.Vorname, meistens wird die verkürzte Schreibweise verwendet wie SELECT Vorname. In komplexeren Abfragen kann auch statt dem Tabellnamen alleine, eine Funktion stehen. Damit kann man in Datenmengen mathematische und statistische Funktionen verwenden. Auch 2 siehe auch http://de.wikipedia.org/wiki/Data_Definition_Language 3 siehe auch http://de.wikipedia.org/wiki/Data_Manipulation_Language 33
  34. 2 Grundlagen Datenbank Verzweigungen und Berechnungen sind möglich. Zu diesen Punkten kommen dann an späterer Stelle die entsprechden Erklärungen. DISTINCT erzwingt die Vermeidung von doppelten Datensätzen. Es überspringt in der Aus- gabe die mehrfach vorkommenden Datensätze. Die Folge ist ein höherer Aufwand am Server, da das urspüngliche Ergebnis (ohne DISTINCT) meist noch entsprechend nachbearbeitet wer- den muß. Bevor man DISTINCT zur Korrektur unerklärlicher doppelter Datensätze verwendet (Verschleiern von Problemen), sollte man sich zuerst seine JOINS und WHERE Klauseln ganz genau ansehen, denn dort liegt meistens das Problem. Eine gerne verwendete Abkürzung stellt das beliebte SELECT * dar. Hier darf dann das Programm zur Laufzeit erraten, welche Spalten es gibt und von welchen Typ sie sind. Es einfach zu verwenden, birgt aber in fertigen Programmen einiges an versteckten Fehlerquellen. Wird die dem SELECT zugrunde liegende Tabelle geändert oder auch nur Spalten getauscht, so kann es sein, daß Fehler nicht beim ausführen des Statements auffallen (Spalte xx nicht gefunden) und erst andere Programmteile dann unklare Fehlermeldung produzieren. Ich empfehle deshalb, die Spaltennamen wirklich anzugeben. Es gibt Programme die gerade diese Eigenschaft ausnutzen, dort wird es aber bewusst gemacht und entsprechend abgesichert. FROM ’Quelle’ FROM gibt die Quelle der Daten an. Es ist einfach der Tabellenname, eine Verbindung von Tabellen (JOIN) oder auch eine untergelagerte SELECT Anweisung. WHERE ’Where-Klausel’ Die WHERE - Klausel schränkt die Ergebnisdatenmenge ein. Bei einfachen Beispielen wird sie gerne, oft zu Unrecht, weggelassen. Wir müssen aber immer Da- tenmengen betrachten, das Ergebnis kann eine Zeile oder eine million Zeilen sein. Wenn wir in einer Adressdatenbank eine Personen suchen, so wird es trotzdem sinnvoll sein, von Haus aus die Suche einzuschränken. Denn alles was nicht an Daten sinnlos übertragen werden muß, spart Bandbreite, Speicher und erhöht die Geschwindigkeit. GROUP BY (’Group-by-Attribut’ Die Daten werden nach dem Group-by-Attributen zu- sammengefasst (gruppiert). Dazu müssen auch in der Auswahlliste, für alle nicht durch GROUP BY erfassten Spalten, entsprechende Operationen verwendet werden (SUM, AVG, MIN, ...). HAVING ’Having-Klausel’ Ist als ein WHERE zu betrachten, das allerdings erst nach dem Gruppieren wirksam ist und deshalb nur auf die Gruppierungsfunktionen wirksam ist. ORDER BY (”Sortierungsattribut” [ASC|DESC]) Die ausgegeben Daten werden ent- sprechend sortiert. Das Sortierungsattribut sind die entsprechden Spaltennamen in der reihenfol- ge wie sortiert werden soll. Beispiele zu SELECT SELECT * FROM st_person; Ohne Einschränkung oder Sortierung. 34
  35. 2 Grundlagen Datenbank quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 378,quot;Hopequot;,quot;Giordanoquot;,quot;HoGiquot;,quot;Hope0Giordanoquot; 379,quot;Rosequot;,quot;Brunoquot;,quot;RoBrquot;,quot;Rose4Brunoquot; 380,quot;Laurenquot;,quot;Morganquot;,quot;LaMoquot;,quot;Lauren4Morganquot; 381,quot;Meganquot;,quot;Colemanquot;,quot;MeCoquot;,quot;Megan9Colemanquot; SELECT * FROM st_person where STPerson = 875; Die Person deren ID 875 ist. quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 875,quot;Hannahquot;,quot;Collinsquot;,quot;HaCoquot;,quot;Hannah3Collinsquot; SELECT * FROM st_person where cVName like ’H%’; Alle Personen deren Vorname mit „H“ beginnt. Das Prozentzeichen „%“ ist eine Wildcard. So wie bei manchen Betriebssystemen der Stern „*“. quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 875,quot;Hannahquot;,quot;Collinsquot;,quot;HaCoquot;,quot;Hannah3Collinsquot; 406,quot;Hannahquot;,quot;Cookquot;,quot;HaCoquot;,quot;Hannah9Cookquot; 845,quot;Hannahquot;,quot;Doylequot;,quot;HaDoquot;,quot;Hannah9Doylequot; 1363,quot;Hannahquot;,quot;Fosterquot;,quot;HaFoquot;,quot;Hannah6Fosterquot; SELECT * FROM st_person order by cFName; Alle Personen, aber nach Familienname aufsteigend sortiert. quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1258,quot;Caitlinquot;,quot;Adamsquot;,quot;CaAdquot;,quot;Caitlin4Adamsquot; 687,quot;Taylorquot;,quot;Alexanderquot;,quot;TaAlquot;,quot;Taylor5Alexanderquot; 644,quot;Reneequot;,quot;Alexanderquot;,quot;ReAlquot;,quot;Renee8Alexanderquot; 885,quot;Taylorquot;,quot;Alexanderquot;,quot;TaAlquot;,quot;Taylor3Alexanderquot; 1131,quot;Sarahquot;,quot;Alexanderquot;,quot;SaAlquot;,quot;Sarah5Alexanderquot; 603,quot;Meganquot;,quot;Allenquot;,quot;MeAlquot;,quot;Megan0Allenquot; 1172,quot;Isabellaquot;,quot;Allenquot;,quot;IsAlquot;,quot;Isabella0Allenquot; 472,quot;Isabellequot;,quot;Allenquot;,quot;IsAlquot;,quot;Isabelle6Allenquot; SELECT * FROM st_person order by cFName desc; Alle Personen, aber nach Familienname absteigend sortiert. quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 842,quot;Isabellaquot;,quot;Youngquot;,quot;IsYoquot;,quot;Isabella6Youngquot; 1232,quot;Taylorquot;,quot;Youngquot;,quot;TaYoquot;,quot;Taylor3Youngquot; 427,quot;Ashleyquot;,quot;Youngquot;,quot;AsYoquot;,quot;Ashley3Youngquot; 420,quot;Kylaquot;,quot;Youngquot;,quot;KyYoquot;,quot;Kyla2Youngquot; 668,quot;Alexandraquot;,quot;Wrightquot;,quot;AlWrquot;,quot;Alexandra6Wrightquot; 1070,quot;Madisonquot;,quot;Wrightquot;,quot;MaWrquot;,quot;Madison5Wrightquot; SELECT * FROM st_person where cVName like ’H%’ order by cFName; Alle Personen deren Vorname mit „H“ beginnt und nach Familienname aufsteigend sortiert. 35
  36. 2 Grundlagen Datenbank quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 932,quot;Hopequot;,quot;Bellquot;,quot;HoBequot;,quot;Hope3Bellquot; 1194,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 515,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 1279,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; 875,quot;Hannahquot;,quot;Collinsquot;,quot;HaCoquot;,quot;Hannah3Collinsquot; 406,quot;Hannahquot;,quot;Cookquot;,quot;HaCoquot;,quot;Hannah9Cookquot; 1296,quot;Harmonyquot;,quot;Diazquot;,quot;HaDiquot;,quot;Harmony1Diazquot; SELECT cVName, cFName FROM st_person where cVName like ’H%’ order by cFName; Anzeige nur der Spalten „cVName“ und „cFName“ und alle Personen deren Vorname mit „H“ beginnt und nach Familienname aufsteigend sortiert. quot;cVNamequot;,quot;cFNamequot; quot;Hopequot;,quot;Bellquot; quot;Harmonyquot;,quot;Campbellquot; quot;Harmonyquot;,quot;Clarkquot; quot;Hollyquot;,quot;Collinsquot; quot;Hannahquot;,quot;Collinsquot; quot;Hannahquot;,quot;Cookquot; quot;Harmonyquot;,quot;Diazquot; SELECT cVName, cFName FROM st_person where (cVName like ’H%’) or (cVName like ’A%’) order by cFName; Anzeige nur der Spalten „cVName“ und „cFName“ und alle Personen deren Vorname mit „H“ oder „A“ beginnt und nach Familienname aufsteigend sortiert. quot;Alyssaquot;,quot;Butlerquot; quot;Abbyquot;,quot;Butlerquot; quot;Ashleyquot;,quot;Butlerquot; quot;Ashleyquot;,quot;Byrnequot; quot;Harmonyquot;,quot;Campbellquot; quot;Harmonyquot;,quot;Clarkquot; quot;Annaquot;,quot;Clarkquot; quot;Abbyquot;,quot;Colemanquot; quot;Hannahquot;,quot;Collinsquot; quot;Ameliaquot;,quot;Collinsquot; quot;Annaquot;,quot;Collinsquot; SELECT count(cVName), cVName FROM st_person group by cVName order by count(cVName) desc; Anzahl der Vorkommen der Vornamen absteigend sortiert. quot;count(cVName)quot;,quot;cVNamequot; 19,quot;Ameliaquot; 19,quot;Angelquot; 17,quot;Lauraquot; 36
  37. 2 Grundlagen Datenbank 16,quot;Elizabethquot; 16,quot;Parisquot; 16,quot;Rubyquot; 15,quot;Caitlinquot; 14,quot;Sophiequot; 14,quot;Abbyquot; 14,quot;Mikaylaquot; SELECT count(cVName) as Anzahl, cVName as Vorname FROM st_person group by cVName order by count(cVName) desc; Anzahl der Vorkommen der Vornamen absteigend sortiert. Dazu noch die Spaltennamen geändert. quot;Anzahlquot;,quot;Vornamequot; 19,quot;Ameliaquot; 19,quot;Angelquot; 17,quot;Lauraquot; 16,quot;Elizabethquot; 16,quot;Parisquot; 16,quot;Rubyquot; 15,quot;Caitlinquot; 14,quot;Sophiequot; 14,quot;Abbyquot; 14,quot;Mikaylaquot; SELECT count(cVName) as Anzahl, cVName as Vorname FROM st_person group by cVName desc having Anzahl = 16; Anzahl der Vorkommen der Vornamen, Dazu noch die Spaltennamen geändert und die Anzahl muß sechzehn sein quot;Anzahlquot;,quot;Vornamequot; 16,quot;Elizabethquot; 16,quot;Parisquot; 16,quot;Rubyquot; INSERT INSERT wird für das Einfügen von Datensätzen in eine Tabelle verwendet. Einfache Darstellung Beim einfachen Einfügen haben wir es mit wenigen Schlüsselwörter zu tun. INSERT ’Ziel’ (’Spaltenliste’) VALUES (’Werteliste’) Bei dem Ziel handelt es sich um die Tabelle in die die Daten eingefügt werden sollen. Die Spal- tenliste kann auch weggelassen werden, wenn die Werteliste in der exakt gleichen Reihenfolge ist, wie die Definition in der Tabelle. 37
  38. 2 Grundlagen Datenbank Wenn die Spaltenliste vorhanden ist, so müssen die Werte in der Werteliste in der gleichen Reihenfolge stehen. Es muß dann aber nicht die Reihenfolge und Anzahl der Spalten mit der Tabellen Definition übereinstimmen. Das wird normalerweise verwendet, da an Spalten mit au- tomatischen Zählern (meist Primärschlüssel) keine Werte übergeben werden dürfen! Beispiele zu INSERT INSERT st_person (cVName,cFName,cMName, cRName) VALUES (quot;Hopequot;,quot;Giordanoquot;,quot;HoGiquot;, quot;Hope0Giordanoquot;); Bei INSERT und anderen Befehlen zur Erstellung von Daten, gibt es kein Ergebnismenge. SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1,quot;Hopequot;,quot;Giordanoquot;,quot;HoGiquot;,quot;Hope0Giordanoquot; 2,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; Die Spalte STPerson, ist zwar beim INSERT nicht angegeben, wird vom System automatisch vergeben. Ein weiteres Beispiel befindet unter Projekt MySQLTestData UPDATE Mit UPDATE können die Daten in den Tabellen geändert werden. Einfache Darstellung Beim einfachen Ändern haben wir es mit wenigen Schlüsselwörter zu tun. UPDATE ’Ziel’ SET ’Spalte1’ = ’Wert1’ , ’Spalte2’ = ’Wert2’ WHERE ’Where-Klausel’ Bei dem Ziel handelt es sich um die Tabelle in der die Daten geändert werden sollen. Nach dem Schlüsselwort SET erfolgt die Auflistung der Spalten mit den neuen Wert. Wichtig ist hier die WHERE-Klausel! Fehlt sie so werden alle Datensätze der Tabelle geän- dert! Soll nur ein einziges Datensatz von der Änderung geändert werden, so muß die Einschrän- kung richtig definiert sein. Normalerweise wird hier der Primärschlüssel (auch zusammenge- setzt) verwendet, denn so ist die Eindeutigkeit sichergestellt. Bezüglich der Möglichkeiten der WHERE-Klausel bitte beim Befehl SELECT nachzulesen. Beispiele zu UPDATE UPDATE st_person set cRName = quot;HoGiquot;WHERE STPerson = 1; Bei UPDATE und anderen Befehlen zur Erstellung von Daten, gibt es kein Ergebnismenge. 38
  39. 2 Grundlagen Datenbank SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1,quot;Hopequot;,quot;Giordanoquot;,quot;HoGiquot;,quot;HoGiquot; 2,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; UPDATE st_person set cVName = quot;Hopperquot;, cRName = quot;HoGi1quot;WHERE STPerson = 1; Hier werden zwei Spalten gleichzeitig geändert SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1,quot;Hopperquot;,quot;Giordanoquot;,quot;HoGiquot;,quot;HoGi1quot; 2,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; UPDATE st_person set cVName = quot;HaHaquot;WHERE cVName like „Ha“; Hier werden mehrere Datensätze gleichzeitig geändert SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1,quot;Hopperquot;,quot;Giordanoquot;,quot;HoGiquot;,quot;HoGi1quot; 2,quot;HaHaquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;HaHaquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; DELETE Mittels dem Befehl DELETEwerden Datensätze in der Datenbank gelöscht. Einfache Darstellung Beim einfachsten DELETE haben wir es mit wenigen Schlüsselwör- ter zu tun. DELETE ’Ziel’ WHERE ’Where-Klausel’ Aber Vorsicht, ohne entsprechende WHERE-Klausel werden alle betroffenen Datensätze ge- löscht. Daher gilt, fehlt die WHERE-Klausel, so werden alle Datensätze unwiderruflich ge- löscht! 39
  40. 2 Grundlagen Datenbank Beispiele zu DELETE DELETE FROM st_person WHERE STPerson = 1; Bei DELETE und anderen Befehlen zur Erstellung von Daten, gibt es kein Ergebnismenge. Hier wird der Datensatz mit dem Wert 1 in der Spalte STPerson gelöscht. SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1,quot;Hopequot;,quot;Giordanoquot;,quot;HoGiquot;,quot;HoGiquot; 2,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; DELETE FROM st_person WHERE STPerson = 1; SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 2,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; DELETE st_person WHERE STPerson = 1; Bei DELETE und anderen Befehlen zur Erstel- lung von Daten, gibt es kein Ergebnismenge. Hier werden alle Datensätze in der Tabelle st_person gelöscht! SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 1,quot;Hopequot;,quot;Giordanoquot;,quot;HoGiquot;,quot;HoGiquot; 2,quot;Harmonyquot;,quot;Campbellquot;,quot;HaCaquot;,quot;Harmony7Campbellquot; 3,quot;Harmonyquot;,quot;Clarkquot;,quot;HaClquot;,quot;Harmony4Clarkquot; 4,quot;Hollyquot;,quot;Collinsquot;,quot;HoCoquot;,quot;Holly7Collinsquot; DELETE FROM st_person; SELECT * FROM st_person; quot;STPersonquot;,quot;cVNamequot;,quot;cFNamequot;,quot;cMNamequot;,quot;cRNamequot; 2.1.4 DCL Datenkontrollsprache Die Datenkontrollsprache (Data Control Language = DCL4 ) umfasst die Sprachteile von Daten- banksprache, mit deren Hilfe man die Rechte vergibt, Wartungen durchführt. Es sind das Befehle wie GRANT und REVOKE. 4 siehe auch http://de.wikipedia.org/wiki/Data_Control_Language 40
  41. 2 Grundlagen Datenbank 5 Version: $LastChangedRevision: 52 $ 5 Autor: Andreas Frieß Lizenz: GFDL 41
Anzeige