SQL Syntax <--- ---> SQLJ, roles, privileges

PL/SQL (ORACLE)

(Konsistenz und transaktionen in relationalen DBMS)
ACID    Atomicity, Consistency, Isolation, Durability

Bedingung für einzelne Attributwerte

ALTER TABLE Angestellter
ADD CONSTRAINT Zeitanteilconstraint
CHECK (Zeitanteil BETWEEN 10 AND 90)                     (wie bei select anweisung)

Referentielle Integrität

ON DELETE CASCADE                        T                    Fortpflanzung, Referenzen mit löschen
ON DELETE RESTRICT            ->|                   Falls Referenzen bestehen, abbrechen
ON DELETE SET NULL             ->0                   Referenzen auf Null setzen
ON DELETE SET DEFAULT                  ->wert               Referenzen auf default setzten

Beispiel:
ALTER TABLE AbtLeitung
ADD CONSTRAINT fk_AbtLAbt
            FOREIGN KEY (AbtNr) REFERENCES Abteilung (AbtNr)
            ON DELETE CASCADE;

ALTER TABLE AbtLeitung
DROP CONSTRAINT fk_AbtLang

PL/SQL

DECLARE
            Emp_name                   VARCHAR2(10);
            Emp_number                INTEGER;
            Empno_out_of_range     EXCEPTION;
BEGIN
            Emp_number := 10001;
            IF Emp_number > 9999 OR Emp_number < 1000 THEN
                        RAISE Empno_out_of_range;
            ELSE
                        SELECT Name INTO Emp_name FROM Angestellter
                                   WHERE PersNr = Emp_number;
                        DBMS_OUTPUT.PUT_LINE('Employee name is ' || Emp_name);
            END IF;
            EXCEPTION
                        WHEN Empno_out_of_range THEN
                                   DBMS_OUTPUT.PUT_LINE('Employee number ' || Emp_number ||
                                               ' is out of range.');
END;
/

Beispiel PROCEDURE

CREATE OR REPLACE
PROCEDURE projektZuteilen (
                ProjName Projekt.Bezeichnung%TYPE,
                AngName Angestellter.Name%TYPE,
                ProzAnt DECIMAL,
                ErrCode OUT DECIMAL)
IS
                PNr Projekt.ProjNr%TYPE;      /* lokale Variable PNr */
                AngNr Angestellter.PersNr%TYPE;       /* lokale Variable AngNr */
BEGIN      /* Body der Prozedur */
                ErrCode := 10; /* unbekannter Fehler */
                BEGIN      /* lokaler, anonymer Block */
                               SELECT Angestellter.PersNr INTO AngNr
                               FROM Angestellter
                               WHERE Angestellter.Name=AngName;
                EXCEPTION /*Exception-Handler des lokalen Blocks */
                WHEN NO_DATA_FOUND THEN
                               /* System Exception: SELECT INTO liefert keinen Wert */
                  ErrCode := -1;       /*Angestllter AngNAme existiert nicht */
                  RAISE;   /* Fehler weiterwerfen */
                WHEN TOO_MANY ROWS THEN
                               /* SELECT INTO liefert mehr als einen Wert */
                  ErrCode := 2; /* AngName ist kein eindeutiges Kriterium */
                  RAISE;
                END;
BEGIN      /* lokaler, anonymer Block */
                               SELECT Projekt.ProjNr INTO PNr
                               FROM Projekt
                               WHERE Projekt.Bezeichnung=ProjNAme;
                EXCEPTION /*Exception-Handler des lokalen Blocks */
                WHEN NO_DATA_FOUND THEN
                               /* System Exception: SELECT INTO liefert keinen Wert */
                  ErrCode := -1;       /*Projekt ProjName existiert nicht */
                  RAISE;   /* Fehler weiterwerfen */
                WHEN TOO_MANY ROWS THEN
                               /* SELECT INTO liefert mehr als einen Wert */
                  ErrCode := 2; /* ProjName ist kein eindeutiges Kriterium */
                  RAISE;
                END;
                BEGIN
                               INSERT INTO ProjektZuteilung
                                               VALUES (AngNr, PNr, ProjektAnt, NULL, NULL);
                               ErrCode := 1; /* ok */
                EXCEPTION
                WHEN DUP_VAL_ON_INDEX THEN
                               ErrCode := -5;         /*Projektzutielung existiert bereits */
                END;
EXCEPTION             /* Procedure */
WHEN OTHERS THEN /* alle Exceptions abfangen */
                ROLLBACK;
END ProjektZuteilung;

Aufruf einer Prozedur aus PL/SQL

DECLARE
  Errcode decimal;
BEGIN
  Projektzuteilen('Mars','Rey', 'Herbert', 80, errCode);
  Dbms_output.put_line(errcode);
END;
(SQL> SET serveroutput on)

Beispiel einer FUNKTION

CREATE OR REPLACE FUNCTION AbteilungsSalaer (AbtName CHAR) RETURN NUMBER
(argument1 [IN | OUT | INOUT] datatyp1, )       RETURN datatyp
IS
 AbtSalaer NUMBER (10,2) := 77890.00; //lokale Variablen
BEGIN
 RETURN AbtSalaer;                             //oder select count(*) Abtielung a where abtSalaer>1000;
END AbteilunsSalaer;

Aufruf einer Funktion aus PL/SQL

BEGIN
 :tot := AbteilungsSalaer ('Entwicklung');
END;

Aufruf einer Funktion aus SQLPlus-Skript

 VARIABLE tot NUMBER;
 EXECUTE :tot := AbteilungsSalaer('Entwicklung');
 Print tot

Statement-Trigger: Prüfung von Vorbedingungen

CREATE OR REPLACE TRIGGER CheckInsertAng
 BEFORE INSERT OR UPDATE OR DELETE ON Angestellter
BEGIN IF (TO_CHAR(sysdate, 'DY') IN ('SAT', 'SUN') ) OR
     (TO_CHAR(sysdate,'HH24') NOT BETWEEN '08' AND '18')
 THEN
                RAISES_APPLICATION_ERROR
                 (-20500, 'Aenderung nur während Arbeitszeit erlaubt !');
  END IF;
END;

Row-Trigger: Sicherstellung der referentiellen Integrität

CREATE OR REPLACE TRIGGER cascade_updates
                AFTER UPDATE OD AbtNr ON Abteilung
                FOR EACH ROW
                BEGIN
                               IF :old.AbtNr != :new.AbtNr THEN
                                               UPDATE Angesteller A
                                               SET A.AbtNr = :new.AbtNr
                                               WHERE A.AbtNr = :old,Abtr;
                                               UPDATE AbtLeitung AL
                                               SET AL.AbtNr = :new.AbtNr
                                               WHERE AL.AbtNr = :old.AbtNr;
                               END IF;
                END;

Row-Trigger: Prüfung von Vorbedingungen

CREATE OR REPLACE TRIGGER check_SalaerAenderung
 BEFORE UPDATE OF Salaer ON Angestellter
 FOR EACH ROW
 WHEN ( ( :new.Salaer < :old.Salaer * 0.9) OR
                  ( :new.Salaer > :old.Salaer * 1.1)
 BEGIN
  RAISES_APPLICATION_ERROR(-20508, 'Salaer nicht mehr als 10% aendern!');
END;

SQL Syntax <--- ---> SQLJ, roles, privileges