Dipl.-Math. Michael Bock Inhaltsverzeichnis )* ! + , - # . ! ! / ! " # " " 1 0 $ %& &' & & &( & Bit, Character, Date, Decimal, Double Precision, Float, Integer, Interval, Numeric, Real, Smallint, Time, Timestamp, Varbit, Varchar ! " # Avg, Bit_Length, Character_length, Convert, Count, Extract, Lower, Max, Min, Octet_length, Position, Substring, Sum, Table_name, Table_schema, Translate, Trim, Upper $ # % #% ( ), *, +, -, / , <, <=, > >= , <>, ||, And, Between, Case, Cast, Exists, In, Like, Not, Null, Or & ' ! ( Begin Declare Section, Close, Commit, Connect, Dedare Cursor, Disconnect, End Declare Section, Rollback, Select, Set Connection ) % * Current_date, Current_time, Current_timestamp, Current_user, Session_user, System_user ! " # " $ %& &' & & &( & # 2 , 3 ! + ! ! 45 Binary, Byte, Counter, Currency, Datetirne, Decimal, Double Precision, Float, Guid, Integer, Long, Longbinary, Memo, Real, Short, Single, Text, Varbinary ! " # Abs , Array , Asc , Atn , Avg (DAO), CBool , CByte , CCur , CDate , CDbl , CDec , Choose , Chr , CInt , CLng , CodeDb, Command, Date , DateAdd , DateDiff , DatePart , DateSerial , DateValue , DAvg, Day , DCount, DDB , DDE, DDEInitiate, DDERequest, DDESend, DFirst, Dir , DLast, DLookup, DMax, DMin, DoEvents , DStDev, DStDevP, DSum, IIf , IMEStatus , Input , InputBox , InStr , Int , IPmt , IRR , IsArray , IsDate , IsEmpty , IsError , IsMissing , IsNull , IsNumeric , IsObject , Last (DAO), LBound , LCase , Left , Len , LoadPicture, Loc , LOF , Second , Seek , Sgn , Shell , Sin , SLN , Space , Spc , Sqr , StDev (DAO), StDevP (DAO), Str , StrComp , StrConv , String , StringFromGUID, Sum (DAO), Switch , Cos , Count (DAO), CreateControl, CreateForm, CreateGroupLevel, CreateObject , CreateReport, CreateReportControl, CSng , CStr , CurDir , CurrentDb, CurrentUser, CVar , CVDate , CVErr , DVar, DVarP, Environ , EOF , Error , Eval, Exp , FileAttr , FileDateTime , FileLen , First (DAO), Fix , Format , FreeFile , FV , GetAllSetting , GetAttr , GetObject , GetSetting , GUIDFromString, Hex , Hour , HyperlinkPart, Log , LTrim , Max (DAO), Mid , Min (DAO), Minute , MIRR , Month , MsgBox , Now , NPer , NPV , Nz, Oct , Partition , Pmt , PPmt , PV , QBColor , Rate , RGB , Right , Rnd , RTrim , SYD , SysCmd, Tab , Tan , Time , Timer , TimeSerial , TimeValue , Trim , TypeName , UBound , UCase , Val , Var (DAO), VarP (DAO), VarType , Weekday , Year $ # % #% ( ), *, +, -, / , <, <=, > >= , <>, All, And, Any, Between, Exists, In, Like, Not, Null, Or, Some & ' ! ( Create Index, Update ! " # " Delete, Drop Index, $ %& &' & & &( Drop Table, & Insert, Select, 6 2 , $ 3 7 8+9 2 ! : $ Bfile, Blob, Character, Clob, Date, Double Precision, Float, Integer, Long, Mlslabel, Nchar, Nclob, Number, Nvarchar, Real, Smallint, Varchar $ ! " # Abs, Acos, Ascii, Asin, Atan, Atan2, Avg, Ceiling, Chr, Cos, Cosh, Cot, Count, Exp, Floor, Hextoraw, Length, Log, Lower, Ltrim, Max, Min, Nod, Power, Round, Rtrim, Sin, Sinh, Sqrt, Substr, Sum, Tan, Tanh, To_binary_integer, To_char, To_date, To_multi_byte, To_number, To_single_byte, Upper $ $ # % #% ( ), *, +, -, / , <, <=, > >= , <>, All, And, Any, Between, Exists, In, Like, Not, Null, Or, Some $ & ' ! ( Alter Cluster, Alter Database, Alter Function, Alter Index, Alter Procedure, Alter Table, Alter Tablespare, Alter Trigger, Alter View, Close, Comment On, Commit, Connect, Create Alias, Create Cluster, Create Controlfile, Create Database, Create Funchon, Create Index, Create Procedure, Create Schema, Create Synonym, Create Tablespace, Create View, Dedare Cursor, Delete, Describe, Disconnect, Drop Cluster, Drop Database, Drop Funchon, Drop lndex, Drop Package, Drop Procedure, Drop Schema, Drop Synonym, Drop Table, Drop Tablespare, Drop Trigger, Drop View, Execute, Fetch, Grant, Insert, Lock Table, Open, Prepare, Recover, Revoke, Rollback, Select, Update, Whenever, $ ) % * %found, %isopen, %rowcount , %rowtype, %type ! " # " $ %& &' & & &( & " + , - In SQL – Befehlen wird grundsätzlich nicht zwischen Groß- und Kleinschreibung unterschieden, es sei denn, es handelt sich um Zeichenliterale oder Bezeichner in Anführungszeichen. Zeichenliterale werden in Hochkommata eingeschlossen. An jeder Stelle eines SQL-Befehls, an der ein Leerzeichen stehen kann, können auch ein oder mehrere Tabulatoren, Zeilenende, Leerzeichen oder Kommentare stehen1. * . / + 0 1 2# 3 4 3 0 5 Namen dürfen 1 bis 30 Zeichen enthalten, mit der Ausnahme: Namen von Datenbanken dürfen höchstens 8 Zeichen enthalten, Namen von DatenbankVerknüpfungen können bis zu 128 Zeichen enthalten. Namen dürfen keine Hochkommata enthalten. Namen werden nicht nach Groß- und Kleinschreibung unterschieden. Ein Name muß mit einem Buchstaben beginnen, es sei denn, er ist von Anführungszeichen umgeben. Steht ein Name in Anführungszeichen, dann wird zwischen Groß- und Kleinschreibung unterschieden. Namen können nur Buchstaben, Ziffern und die Sonderzeichen _ , $, und # enthalten. Benutzen Sie möglichst $ und # nicht. („You are strongly discouraged from using $ and #. “) Ein Name darf kein reserviertes Wort sein. In der Regel können Sie keine deutschen Umlaute in Namen verwenden. $ " 3 Mit dem Doppelminus „- - “ wird der Rest einer Zeile (also alle Zeichen zwischen „ - - “ und dem Zeilenende-Zeichen zum Kommentar erklärt: Alle Zeichen, die zwischen /* und */ eingeschlossen sind, werden ignoriert. Die Anweisung SELECT DUMMY -- Dieser Text wird ignoriert /* Dieser ganze Textblock wird ignoriert */ FROM DUAL; entspricht in der Wirkung der folgenden Anweisung SELECT DUMMY FROM DUAL; 1 Allerdings reagiert Oracle trotz gegenteiliger Behauptungen seiner Online-Hilfe allergisch auf Leerzeilen! ! " # " $ %& &' & & &( & 1 $ 3 3 6 3 +/3+ 2 5 Zur Datendefinition gehört • das Anlegen von Tabellen und Indizes, • die Erklärung von Integritätsregeln. $ 3 78 Um Tabellen erstellen zu können, benötigen wir für jedes Attribut die Angabe seines Wertebereiches. Diese Wertebereiche werden realisiert erstens durch vorgegebene Datentypen und zweitens durch zusätzliche Angabe von Gültigkeitsregeln. Die Datentypen sind grob in vier Kategorien einzuteilen: <Datentyp> ::= <numerischer Datentyp> | <alphanumerischer Datentyp> | <Datum Datentyp> | <Bytestring Datentyp> <numerischer Datentyp> ::= NUMBER [({<precision> | *}[,<scale>])]| <alphanumerischer Datentyp> ::= CHAR[ACTER] [(<length>)] VARCHAR (<length>) | VARCHAR2 ( <length> ) | LONG [VARCHAR] | <Datum Datentyp> ::= DATE <Bytestring Datentyp> ::= RAW (<length>) | LONG RAW <length> ::= <natürliche Zahl> <precision> ::= <natürliche Zahl> <scale> ::= [-]<natürliche Zahl> ORACLE-Datentypen Datentyp Bereich NUMBER Gleitkomma-Zahlen zwischen 1,0 x 10-130 und 9.9...9 x 10125 NUMBER(p,s) Festkomma-Zahlen: p ist die Gesamtanzahl der Stellen, s ist die Anzahl der Nachkommastellen CHAR(n) Zeichenketten mit fester Länge von n Byte, n <= 255 VARCHAR(n) Entspricht noch VARCHAR2 VARCHAR2(n) Variabel lange Zeichenketten mit maximal n Zeichen, n <= 2000 LONG Zeichen mit variabler Länge bis zu 2 Gigabytes (ORACLE 7) DATE Zulässige Datumsangaben reichen vom 1.Januar 4712 v.Chr. bis zu 4712 n.Chr. RAW(n) Binäre Daten bis zu n Bytes Größe, n <= 255 LONG RAW Binäre Daten bis zu 2 GigaBytes Größe ! " # " $ %& &' & & &( & 5 ANSI - Datentypen Datentyp BIT(anzahl) CHARACTER(n), CHAR(n) DATE DECIMAL(precision,scale) DOUBLE PRECISION, DOUBLE FLOAT(precision) Bereich Eine Anzahl Bits Zeichenketten mit fester Länge von n Byte Zeichenketten mit fester Länge von n Byte Datum eines Tages Gepackte Dezimalzahl Gleitkommazahl Gleitkommazahl, die angegebene Stellen der Genauigkeit werden eingehalten INTEGER, INT Ganzzahl, Größe ist implementationsabhängig NUMERIC(precision,scale) Wie Decimal REAL Wie Float SMALLINT Ganzzahl, Größe ist implementationsabhängig, aber i.d.R halb so lang wie Integer TIME Uhrzeit TIMESTAMP Datum + Uhrzeit VARBIT Variabel langer Bit-Array VARCHAR Variabel langer Text, Größe ist implementationsabhängig ! " # " $ %& &' & & &( & Oracle 9 9 9 9 9 9 9 : $ / 3 Eine Tabelle ist ein Datenbankobjekt und wird vom DBMS als solches verwaltet. Eine Übersicht über die von Ihnen erstellten Tabellen erhalten Sie mit der Anweisung SELECT table_name FROM user_tables; unter Oracle. Der CREATE-Befehl zum Erstellen neuer Tabellen lautet in der Backus-Naur-Form: <Erzeuge Tabelle Anweisung> ::= CREATE TABLE <Tabellenname> <Tabellenschema> <Tabellenschema> ::= ( <Tabellenelement> [{,<Tabellenelement>}...] ) <Tabellenelement> ::= < Attributdefinition > | <Tabellen Integritäts-Regel> <Attributdefinition> ::= <Attributname> <Datentyp> [<Default Ausdruck>] [<Attribut Integritäts-Regel> ...] [<Default Ausdruck>] ::= DEFAULT <Ausdruck> Beispiel: CREATE TABLE Kunden ( knr NUMBER(10) PRIMARY KEY, kname VARCHAR(20) NOT NULL, kvorname VARCHAR(10) , ort VARCHAR(20) DEFAULT ‘Paderborn‘); $ * : ;, Der Befehl zum Löschen einer Tabelle: <Tabellen-Lösch-Befehl> ::= DROP TABLE <Tabellenname> Dieser Befehl löscht die Tabelle mitsamt allen Datensätzen. Existieren in der Tabelle Primärschlüssel, auf die aus anderen Tabellen mittels Fremdschlüsseln verwiesen wird, so kann sie nicht mit diesem Befehl allein gelöscht werden. Beispiel: DROP TABLE Kunden; Um Tabellen zu löschen, die mit anderen Tabellen zusammenhängen, schreiben Sie: Beispiel: DROP TABLE Kunden CASCADE CONSTRAINTS; ! " # " $ %& &' & & &( & 4 $ ! * ! #% , "# * % In SQL können Tabellen auch aus anderen vorliegenden Tabellen kopiert werden. <Kopiere Tabelle Anweisung> ::= CREATE TABLE <Tabellenname> [(<Copy Tabellen Schema> [{,<Copy Tabellen Schema>}...] AS <Select Anweisung> <Copy Tabellen schema> ::= (<Tabellenelement2> [{,<Tabellenelement2> }... ]) <Tabellenelement2> ::= <Attributbeschreibung> | < Tabellen Integritäts-Regel> <Attributbeschreibung> ::= <Attributname> [<Default Ausdruck>] [<Attribut Integritäts-Regel> ...] Beispiel: CREATE TABLE KundenKopie ( k2nr , k2name , k2vorname ) AS SELECT knr, kname,kvorname FROM Kunden; Bis auf die Angabe des Attribut-Datentyps, entspricht die obige Syntax derjenigen beim Neuerstellen einer Tabelle! Beim Versuch, den Datentyp eines bereits vorhandenen Attributs zu ändern, erhält man die folgende Fehlermeldung: ERROR at line 1: ORA-01773: may not specify column datatypes in this CREATE TABLE ! " # " $ %& &' & & &( & $ $ * < Ein Benutzer darf keinen zwei Tabellen den gleichen Namen geben. Es ist aber möglich, daß mehrere Benutzer in der gleichen Datenbank Tabellen mit gleichen Namen anlegen. Um generell auf Tabellen eines anderen Benutzers zuzugreifen – vorausgesetzt man hat das Recht dazu – benutzt man die Tabellenbeschreibung: <Tabellenbeschreibung> ::= [<Eigentümername> .] <Tabellenname> Benutzen Sie für Tabellen kurze aber aussagekräftige Namen. Es ist hilfreich bei Tabellennamen einen Plural zu verwenden: z.B.: Projekte statt Projekt. $ & # < Für jede Tabelle kann ein Benutzer ein Synonym anlegen. Beispiel: CREATE SYNONYM Kaeufer FOR KundenKopie; Synonyme können auch gelöscht werden: Beispiel: DROP SYNONYM Kaeufer; ! " # " $ %& &' & & &( & $ $ 3 $ $ ? = > %! ( < Um nachträglich den Tabellennamen zu ändern, benutzen Sie den Rename-Befehl <Rename Anweisung> ::= RENAME <Tabelle specification> TO <Tabellenname> RENAME Kunden TO MeineKunden; $ $ ? %! ( % % !" !% Mit dem Befehl ALTER TABLE lassen sich ... • • eine oder mehrere Attribute in eine vorhandene Tabelle einfügen, bereits existierende Attribute modifizieren. Die Syntax für den Befehl ALTER TABLE lautet: <Tabellenänderung> ::= ALTER TABLE <Tabellenname> {<Tabellenelemente hinzufügen> | <Tabellenelemente ändern> }... <Füge Tabellenelement hinzu> ::= ADD <Tabellenschema> <Tabellenelemente ändern> ::= MODIFY (<Attributänderung> [{,<Attributänderung>}...]) | <Attributänderung> ::= <Attributname> [<Datentyp>] [[NOT] NULL] Beispiel: ALTER TABLE Kunden DROP CONSTRAINT Kunden_pk ADD UNIQUE (kname) MODIFY kname CHAR(30) ; oder Beispiel: ALTER TABLE Kunden DROP CONSTRAINT Kunden_pk ADD ( UNIQUE (kname), Strasse VARCHAR(45) MODIFY (kname CHAR(30), ort VARCHAR(23)) ; ) Bei dem Versuch, den Datentyp eines Attributs zu ändern in einen Datentyp, der zur Speicherung bereits vorhandener Daten nicht mehr ausreicht, erhalten wir folgende (ORACLE 7) Fehlermeldung: ERROR at line 3: ORA-01441: column to be modified must be empty to decrease column length ! " # " $ %& &' & & &( & $ & + = + ; 3 Constraints (engl.: Bedingung, Zwang) sollen die Integrität der Daten und die Integrität der Beziehungen gewährleisten und absichern. Dabei gibt es einerseits naheliegende datenbanktechnische Bedingungen wie z.B. die Verbindung zwischen einem Primärschlüssel und einem Fremdschlüssel, und andererseits auch benutzerspezifische Zwänge wie bestimmte Geschäftsregeln eines Unternehmens. Diese Zwänge können über die Benutzerschnittstelle (z.B. ein PHP Script programmiert werden) oder manchmal auch schon in der Datenbank durch Constraints formuliert werden (diese Lösung ist in der Regel sicherer und bequemer.) ORACLE stellt folgende Constraint-Möglichkeiten zur Verfügung, die so oder ähnlich in anderen RDBMS zu finden sind: • • • • • PRIMARY KEY FOREIGN KEY NOT NULL UNIQUE CHECK (Primärschlüssel) (Fremdschlüssel) (Pflichtfeld) (eindeutige Attributkombination) (Regel) Diese Constraints können angelegt, angesehen, gelöscht und ausser Kraft gesetzt werden. Ausserdem besteht die Möglichkeit, ihnen Namen zu geben, damit sie bei einer eventuellen Verletzung leichter identifiziert werden können. 3.4.1 % ! ( % Constraints können häufig auf zwei Arten dargestellt, bzw. vereinbart werden. Erstens als Spaltenconstraint (direkt hinter dem Datentyp des Attributs), oder als Tabellenconstraint (in einer eigenen Stelle der Auflistung). 3.4.1.1 * @ ;# % % ! ( CREATE TABLE personen ( pnr INTEGER PRIMARY KEY, name VARCHAR(20) ); 3.4.1.2 * @ * ;# % % ! ( CREATE TABLE personen ( pnr INTEGER, PRIMARY KEY (pnr), name VARCHAR(20) ); Die Syntax der Darstellungsarten weicht je nach Constraint voneinander ab. In den meisten Fällen können Sie sich die Darstellungsart aussuchen. In manchen Fällen kann man einen Constraint nur als Tabellenconstraint darstellen. REGEL Es gilt die Regel: Jeder Spaltenconstraint kann als Tabellenconstraint dargestellt werden, aber nicht umgekehrt. ! " # " $ %& &' & & &( & # 3.5 ; 3 3 #% ; Für die eigene Bequemlichkeit dürfen Tabellenbesitzer ihren Constraints Namen geben. Diese Namen werden dann bei Verletzung des Constraints von Oracle angezeigt. Damit ist die Fehlerquelle schneller lokalisierbar. Wird kein Name für die Constraints gewählt, so vergibt Oracle einen eigenen Namen (z.B.: SYS_C00233697 ). Jeder Constraintname darf nur ein einziges mal in einem Benutzerschema auftauchen. Es ist sinnvoll, ein Bezeichnungsschema durchzuhalten, z.B.: pk_personen $ , fk_projekte_personen ' 3 . nn_nachname_personen $ chk_gebdat_personen 9 un_name_personen 2 ; ; < * < * ; ! = < * ! / 9 0> , ! ? * ! @ 0 ! > , ! / < * , ! ! ! < * < * CREATE TABLE personen ( pnr INTEGER CONSTRAINT pk_personen PRIMARY KEY, name VARCHAR(20), abt INTEGER CONSTRAINT chk_abt CHECK(abt > 10), CONSTRAINT fk_personen_abteilungen FOREIGN KEY (abt) REFERENCES abteilungen(abtnr) ); ! " # " $ %& ! &' & & &( & ! ! 6 3.6 % < % " A; 3 @ = B Pro Tabelle darf höchstens ein Primärschlüssel erklärt werden. Der Primärschlüssel darf aus einem oder mehreren Attributen bestehen. Diese Attribute dürfen keine Nullwerte aufweisen, und die Kombination muss eindeutig sein. 3.6.1.1 * @ ;# % % ! ( CREATE TABLE personen ( pnr INTEGER PRIMARY KEY, name VARCHAR(20) ); 3.6.1.2 * @ * ;# % % ! ( CREATE TABLE personen ( pnr INTEGER, name VARCHAR(20), PRIMARY KEY (pnr) ); Sind mehrere Attribute am Schlüssel beteiligt, ist nur die Tabellenconstraint-Darstellung möglich. 3.6.1.3 * @ * ;# % % ! ( CREATE TABLE mitarbeit ( personid INTEGER, projektid INTEGER, PRIMARY KEY (personid, projektid) ); ! " # " $ %& &' & & &( & " 3.7 #% ( " A; 3 @ > B Fremdschlüssel sichern ebenfalls die Integrität der Datenbank: die referentielle Integrität. Zwischen zwei Tabellen besteht häufig eine referentielle Abhängigkeit: der Primärschlüssel der einen (Mastertable) wird zum Fremdschlüssel der anderen (Detailtable). 3.7.1.1 @ * ;# % % ! ( CREATE TABLE projekte ( projektnr INTEGER, start DATE, pnr INTEGER REFERENCES personen ); Die Tabelle projekte bezieht sich mit ihrem Fremdschlüssel pnr auf den Primärschlüssel der Tabelle personen (s.o.), der dort genauso heisst. 3.7.1.2 * @ * ;# % % ! ( CREATE TABLE projekte ( projektnr INTEGER, start DATE, pnr INTEGER, FOREIGN KEY (pnr) REFERENCES personen ); $ 4 ! % ;, ;, * C ;, % Primärschlüssel und Fremdschlüssel müssen nicht die gleiche Bezeichnung tragen: 3.7.2.1 * @ ;# % % ! ( CREATE TABLE projekte ( projektnr INTEGER, start DATE, leiter INTEGER REFERENCES personen (pnr) ); Die Tabelle projekte bezieht sich mit Ihrem Fremdschlüssel leiter auf den Primärschlüssel pnr der Tabelle personen. 3.7.2.2 * @ * ;# % % ! ( CREATE TABLE projekte ( projektnr INTEGER, start DATE, leiter INTEGER, FOREIGN KEY (leiter) REFERENCES personen (pnr) ); ! " # " $ %& &' & & &( & 1 $ D # ! A; 3 @ 6 6 > Ein Nullwert ist nicht die Zahl 0, sondern ein fehlender oder leerer Eintrag für ein Attribut. Beispiel: Eine Telefonnummer in einer Datenbank kann aus zwei Gründen fehlen: Entweder hat die Person keine Telefonnummer oder sie ist nicht bekannt. In keiner der beiden Fälle kann man sagen, dass die Telefonnummer ein Leerstring ’’ ist. Auch sind zwei Nullwerte niemals gleich.. In ORACLE wird ein Nullwert explizit durch das Schlüsselwort NULL ausgedrückt. Für Attribute, deren Werte immer eingetragen werden müssen (sogenannte Pflichtfelder), wird die Integritätsregel NOT NULL erklärt. Bei jeder Änderung des Tabelleninhalts (Einfügen und Ändern) überprüft das RDBMS, ob für die Pflichtfelder Daten vorhanden sind. Falls nicht, wird die Änderung nicht durchgeführt und ein Fehler ausgelöst. Anmerkungen: • Oracle erkennt auch Leerstrings, also ’’ und ’ ’ als Nullwerte. • Bei Oracle Tabellen beinhaltet der Primary Key –Constraint bereits den NOT NULL Constraint! Beispiel: Für die Tabelle1 ist folgende Belegung möglich CREATE TABLE Tabelle1 ( PID NUMBER(2) NOT NULL, Name VARCHAR(10) ); Tabelle1 PID 341 190 992 3.8.1.1 NAME Braun Schur * @ ;# % % ! ( CREATE TABLE personen ( pnr INTEGER PRIMARY KEY, name VARCHAR(20) NOT NULL ); 3.8.1.2 * @ * ;# % % ! ( Gibt es nicht ! ! " # " $ %& &' & & &( & 5 $ ! ! A; 3 @ > / + ' > Muss ein Attribut oder eine Attributkombination in einer Tabelle eindeutig sein, kann hierfür die Integritätsregel UNIQUE erklärt werden. Diese Gültigkeitsregel kann wieder in beiden Varianten erklärt werden. 3.9.1.1 @ * ;# % % ! ( CREATE TABLE Tabelle1 ( PID NUMBER(2) UNIQUE, Name VARCHAR(10) ); oder 3.9.1.2 * @ * ;# % % ! ( CREATE TABLE Tabelle1 ( PID NUMBER(2), Name VARCHAR(10), UNIQUE (PID) ); Soll die Kombination aus PID und Name eindeutig sein, kann nur die Tabellenconstraintdarstellung verwendet werden. 3.9.1.3 * @ * ;# % % ! ( CREATE TABLE Tabelle1 ( PID NUMBER(2), Name VARCHAR(10), UNIQUE (PID,Name) ); NULL-Werte sind nur dann erlaubt, wenn UNIQUE für nur ein Attribut erklärt wird. ! " # " $ %& &' & & &( & : $ E ; , ; "A; 3 9 + * B . C, 9 9 ! B = D (, %! 9 ! ! + @* / . > 6 ! ! A ! + ! , !! !! 9 ! @ ;# B , ! + . 3.10.1.1 * ! ! * ! . ! % + , ! , , ? ! 7 E* ! * ' . % % ! ( CREATE TABLE autos ( anr INTEGER, firma VARCHAR(10) CHECK(firma = UPPER(firma)) ); 3.10.1.2 * @ * ;# % % ! ( CREATE TABLE autos ( anr INTEGER, firma VARCHAR(10), CHECK(firma = UPPER(firma)) ); A , + 3.10.1.3 * - @ ' ;# !! % A % , ! 3 ! ( CREATE TABLE personen ( pnr INTEGER, anrede CHAR(4) CHECK(anrede IN (’Herr’,’Frau’)), name VARCHAR(20) ); 3.10.1.4 * @ * ;# % % ! ( CREATE TABLE personen ( pnr INTEGER, anrede CHAR(4), name VARCHAR(20), CHECK(anrede IN (’Herr’,’Frau’)) ); ! " # " $ %& &' & & &( & , % * .