Ubungsblatt 8- Lösungsvorschlag - DBIS

Transcription

Ubungsblatt 8- Lösungsvorschlag - DBIS
Universität Innsbruck - Institut für Informatik
Prof. Günther Specht, R.Binna, N.Krismer, M. Tschuggnall
30. November 2012
Proseminar Datenbanksysteme
Übungsblatt 8- Lösungsvorschlag
Aufgabe 1 (Trigger)
Da MySQL Check Constraints nicht interpretiert, bilden Sie bitte die folgenden Constraints für das klinische Informationssystem aus Übung 6 nach und erstellen Sie einen
Test der das korrekte Verhalten des jeweiligen Triggers sicherstellt.
Das Schema kann mittels der Datei ’klinisches-infosystem.sql’ erstellt werden. Beachten Sie beim Erstellen des Triggers, dass Sie den Delmiter zwischen den einzelnen
SQL-Statements mittels DELIMITER ’delimiter’ ändern können. Dies ist wichtig da innerhalb des Triggers der Standarddelimiter ; gültig ist. Verwenden Sie SQLState ’45000’,
welcher für benutzerdefinierte Ausnahmen reserviert ist, um mögliche Fehler zu signalisieren.
a) Stellen Sie mittels eines insert Triggers sicher, dass das Rechnungsdatum einer
neuen Behandlung immer neuer als das Rechnungsdatum aller vorangegangen Behandlungen ist.
Lösung:
DELIMITER ; ;
DROP TRIGGER
IF EXISTS c h e c k b e f o r e b e h a n d l u n g ; ;
CREATE TRIGGER c h e c k b e f o r e b e h a n d l u n g
BEFORE INSERT ON Behandlung
FOR EACH ROW
Proseminar Datenbanksysteme – Übungsblatt 8
BEGIN
DECLARE l a t e s t d a t e DATE;
DECLARE t r i g g e r e r r o r m s g VARCHAR( 2 5 5 ) ;
SET l a t e s t d a t e =
(SELECT MAX( rechnungsDatum ) FROM Behandlung ) ;
IF NEW. rechnungsDatum < l a t e s t d a t e THEN
SET t r i g g e r e r r o r m s g = CONCAT(
’A Behandlung with a rechnungsDatum ’ ,
’ newer than th e p r o v i d e d a l r e a d y e x i s t s . ’
);
SIGNAL SQLSTATE ’ 45000 ’
SET m e s s a g e t e x t = t r i g g e r e r r o r m s g ;
END IF ;
END; ;
DELIMITER ;
DELETE FROM Behandlung ;
DELETE FROM P a t i e n t ;
DELETE FROM Person ;
INSERT INTO Person ( a d r e s s e , gebDatum , g e s c h l e c h t ,
nachname , vorname )
VALUES( ’ t e c h n i k e r s t r a s s e 21 a ’ , ’ 01−01−2012 ’ , ’m ’ ,
’ test ’ , ’ patient ’ ) ;
INSERT INTO P a t i e n t ( svnr , p a t i e n t I D , eCardID )
VALUES ( LAST INSERT ID ( ) , 815 , 1 2 3 ) ;
INSERT INTO Behandlung ( behandlungsNr , svnr , rechnungsNr ,
rechnungsDatum , abrechnungsNr )
VALUES( 8 1 5 , LAST INSERT ID ( ) , 1 , ’ 1999−09−20 ’ , 3 ) ;
INSERT INTO Behandlung ( behandlungsNr , svnr , rechnungsNr ,
rechnungsDatum , abrechnungsNr )
VALUES( 8 1 6 , LAST INSERT ID ( ) , 2 , ’ 1999−09−19 ’ , 4 ) ;
b) Erstellen Sie einen insert und einen update Trigger, welcher sicherstellt dass die
Emailadresse des Arztes das korrekte Format besitzt. Lagern Sie dafür Code, welcher von beiden Triggern verwendet wird, in eine eigene Procedure aus.
Lösung:
2
Proseminar Datenbanksysteme – Übungsblatt 8
DROP TRIGGER
IF EXISTS c h e c k e m a i l a r z t t r i g g e r i n s e r t e m a i l ;
DROP TRIGGER
IF EXISTS c h e c k e m a i l a r z t t r i g g e r u p d a t e e m a i l ;
DROP PROCEDURE
IF EXISTS c h e c k e m a i l a r z t p r o c e d u r e ;
DELIMITER ; ;
CREATE PROCEDURE c h e c k e m a i l a r z t p r o c e d u r e (
IN e m a i l VARCHAR( 5 0 )
)
BEGIN
IF NOT e m a i l REGEXP ’ [ a−zA−Z0 −9]∗@[ a−zA−Z0 −9]∗ ’
THEN
SIGNAL SQLSTATE ’ 45000 ’
SET m e s s a g e t e x t =
’ Email d oes not comply to e m a i l f or m at . ’ ;
END IF ;
END; ;
CREATE TRIGGER c h e c k e m a i l a r z t t r i g g e r i n s e r t e m a i l
BEFORE INSERT ON Ar zt E m ail
FOR EACH ROW
BEGIN
c a l l c h e c k e m a i l a r z t p r o c e d u r e ( new . e m a i l ) ;
END; ;
CREATE TRIGGER c h e c k e m a i l a r z t t r i g g e r u p d a t e e m a i l
BEFORE UPDATE ON Ar zt E m ail
FOR EACH ROW
BEGIN
c a l l c h e c k e m a i l a r z t p r o c e d u r e ( new . e m a i l ) ;
END; ;
DELIMITER ;
DELETE FROM
DELETE FROM
DELETE FROM
INSERT INTO
nachname ,
Ar zt E m ail ;
Arzt ;
Person ;
Person ( a d r e s s e , gebDatum , g e s c h l e c h t ,
vorname )
3
Proseminar Datenbanksysteme – Übungsblatt 8
VALUES( ’ t e c h n i k e r s t r a s s e 21 a ’ , ’ 01−01−2012 ’ , ’m ’ ,
’ test ’ , ’ arzt ’ ) ;
INSERT INTO Arzt ( s v n r )
VALUES ( LAST INSERT ID ( ) ) ;
INSERT INTO Ar zt E m ail ( svnr , e m a i l )
VALUES( LAST INSERT ID ( ) , ’ dr . no@mail . jm ’ ) ;
INSERT INTO Ar zt E m ail ( svnr , e m a i l )
VALUES( LAST INSERT ID ( ) , ’ dr . house ’ ) ;
UPDATE Ar zt E m ail
SET e m a i l = ’ dr . house ’
WHERE s v n r = LAST INSERT ID ( ) ;
c) Um sicherzustellen, dass die Emailaddressen von Ärzten trotz Löschvorgang auf der
Tabelle Arzt nicht verloren gehen. Erstellen Sie eine Tabelle Email Archive(email)
welche die Emails von gelöschten Ärzten beinhaltet. Um dies automatisiert durchführen
zu können erstellen Sie einen Trigger welcher gelöschte Emails automatisch in die
Tabelle Email Archive kopiert.
Lösung:
DROP TABLE IF EXISTS E m a i l A r c h i v e ;
CREATE TABLE E m a i l A r c h i v e (
e m a i l VARCHAR( 5 0 ) PRIMARY KEY
);
DELIMITER ; ;
CREATE TRIGGER c o p p y e m a i l a r z t t r i g g e r d e l e t e e m a i l
BEFORE DELETE ON Ar zt E m ail
FOR EACH ROW
BEGIN
INSERT INTO E m a i l A r c h i v e ( e m a i l ) VALUES( o l d . e m a i l ) ;
END; ;
DELIMITER ;
DELETE FROM
DELETE FROM
DELETE FROM
INSERT INTO
Ar zt E m ail ;
Arzt ;
Person ;
Person (
4
Proseminar Datenbanksysteme – Übungsblatt 8
a d r e s s e , gebDatum ,
g e s c h l e c h t , nachname ,
vorname
)
VALUES(
’ t e c h n i k e r s t r a s s e 21 a ’ ,
’ 01−01−2012 ’ , ’m ’ ,
’ test ’ , ’ arzt ’
);
INSERT INTO Arzt ( s v n r )
VALUES ( LAST INSERT ID ( ) ) ;
INSERT INTO Ar zt E m ail ( svnr , e m a i l )
VALUES( LAST INSERT ID ( ) , ’ dr . no@mail . jm ’ ) ;
DELETE FROM Ar zt E m ail ;
SELECT ∗ from E m a i l A r c h i v e ;
Aufgabe 2 (Procedures)
Die folgenden Aufgaben operieren erneut auf dem filesystem-Schema von Blatt Nr. 6.
Importieren Sie dieses unter Zuhilfenahme der Datei ’filesystem.sql’.
Da MySQL keine Rekursion nach dem SQL-Standard unterstützt erstellen Sie eine
Stored Procedure, welche die Anfrage nach allen Pfaden analog zur Aufgabe 1.a) von
Übungsblatt Nr. 7 lösen kann. Führen sie das DDL Statement zur Erstellung der Rekursionstabelle nicht innerhalb der Stored Procedure aus. Stattdessen verwenden Sie
INSERT bzw. DELETE statements um den Inahlt der Rekursionstabelle innerhalb der Stored Procedure zu manipulieren. Dies ist wichtig, wenn die rekursive Stored Procedure
von einer Stored Function aus aufgerufen werden soll.
Hinweis: Setzen Sie die Variable max sp recursion depth, da ansonsten keine Rekursion in MySQL möglich ist.
Lösung:
DROP TABLE IF EXISTS t b l p a t h ;
CREATE TABLE t b l p a t h (
i n o d e INTEGER PRIMARY KEY,
5
Proseminar Datenbanksysteme – Übungsblatt 8
path TEXT,
depth INT
);
DELIMITER ; ;
DROP PROCEDURE IF EXISTS p a t h p r o c ; ;
CREATE PROCEDURE p a t h p r o c (
IN p h o p a k t u e l l INT, IN p h op s INT
)
BEGIN
IF ( p h o p a k t u e l l = 0) THEN
DELETE FROM t b l p a t h ;
INSERT INTO t b l p a t h ( in od e , path , depth )
SELECT DISTINCT in od e , ’ ’ , 0 FROM f i l e
WHERE p a r e n t I S null ;
CALL p a t h p r o c ( p h o p a k t u e l l + 1 , p h op s ) ;
ELSEIF ( p h o p a k t u e l l <= p h op s ) THEN
INSERT INTO t b l p a t h ( in od e , path , depth )
SELECT f i l e . in od e ,
CONCAT( t b l p a t h . path , ’ / ’ , f i l e . name ) ,
p hop aktuell
FROM f i l e , t b l p a t h
WHERE t b l p a t h . i n o d e = f i l e . p a r e n t
AND t b l p a t h . depth = p h o p a k t u e l l − 1 ;
CALL p a t h p r o c ( p h o p a k t u e l l + 1 , p h op s ) ;
END IF ;
END; ;
DELIMITER ;
SET GLOBAL m a x s p r e c u r s i o n d e p t h = 2 0 ;
SET m a x s p r e c u r s i o n d e p t h = 2 0 ;
CALL p a t h p r o c ( 0 , 1 0 ) ;
SELECT in od e , path FROM t b l p a t h ;
Aufgabe 3 (Stored Function mittels Stored Procedure)
Erstellen Sie eine Stored Function welche unter Angabe einer inode den entsprechenden Pfad zurückliefert. Beispielsweise soll die folgende Anfrage die Pfade aller Dateien
zurückliefern.
SELECT path ( f i l e . i n o d e ) FROM f i l e
6
Proseminar Datenbanksysteme – Übungsblatt 8
Verwenden Sie zur Lösung dieser Aufgabe die Stored Procedure aus der vorherigen Aufgabe.
Lösung:
DELIMITER ; ;
DROP FUNCTION IF EXISTS path ; ;
CREATE FUNCTION path ( i n o d e INT) RETURNS TEXT
BEGIN
DECLARE p ath v TEXT;
CALL p a t h p r o c ( 0 , 1 0 ) ;
SELECT path INTO p ath v FROM t b l p a t h
WHERE t b l p a t h . i n o d e = i n o d e ;
RETURN p ath v ;
END; ;
DELIMITER ;
SELECT path ( f i l e . i n o d e ) FROM f i l e ;
Aufgabe 4 (Stored Function mit Loop)
Erstellen Sie die gleiche Stored Function wie in der vorherigen Aufgabe. Verwenden Sie
dabei keine vorher erstellte Stored Procedure sondern eine WHILE-Loop.
Lösung:
DELIMITER ; ;
DROP FUNCTION IF EXISTS path ; ;
CREATE FUNCTION path ( i n o d e INT) RETURNS TEXT
BEGIN
DECLARE p ath v TEXT;
SET p ath v = ’ ’ ;
WHILE NOT i n o d e I S NULL DO
IF p ath v != ’ ’ THEN
SET p ath v = CONCAT( ’ / ’ , p ath v ) ;
7
Proseminar Datenbanksysteme – Übungsblatt 8
END IF ;
SELECT CONCAT( name , p ath v ) , p a r e n t
INTO path v , i n o d e
FROM f i l e
WHERE f i l e . i n o d e = i n o d e ;
END WHILE ;
r e t u r n p ath v ;
END; ;
DELIMITER ;
SELECT path ( f i l e . i n o d e ) FROM f i l e ;
Laden Sie Ihre Lösungen bis spätestens Montag, den 03.12.2012 9:00 im U2L unter
http://u2l-informatik.uibk.ac.at/ hoch.
8

Documents pareils