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