ÖVNING 13 Betrakta följande relationsdatabasschema: HÄST(Namn, Mankhöjd, Favoritmat, Art PERSON(Personnummer, Namn, Adress, Telefon RIDLEKTION(Id, Datum, Tidpunkt, Ledare RIDTILLFÄLLE(Person, Häst, Lektion Anmärkning: En person kan endast rida en häst per ridtillfälle. En häst kan endast ridas av en person per ridtillfälle. RIDLEKTION.Ledare << PERSON.Personnummer RIDTILLFÄLLE.PERSON << PERSON.Personnummer RIDTILLFÄLLE.Häst << HÄST.Namn RIDTILLFÄLLE.Lektion << RIDLEKTION.Id Översätt till SQL och relationsalgebra: a Vilken häst har favoritmaten Melass? PI Namn (SIGMA Favoritmat= Melass (HÄST SELECT Namn FROM HÄST WHERE Favoritmat = Melass b Ge Namn och adress till de personer som aldrig deltagit som ledare i en ridlektion. Alla PI Personnummer (PERSON Ledare(Personnummer PI Ledare (RIDLEKTION Valda Alla - LEDARE Alla PI Namn,Adress (Valda NATURAL JOIN PERSON SELECT Namn, Adress FROM PERSON WHERE Personnummer NOT IN
(SELECT Ledare FROM RIDLEKTION c Vilka (deras namn har ridit hästen Darley Arabian? Darleyriddare(Personnummer PI Person (SIGMA Häst= Darley Arabian (RIDTILLFÄLLE PI Namn (Darleyriddare NATURAL JOIN RIDTILLFÄLLE SELECT Namn WHERE Personnummer = Person AND Häst = Darley Arabian d Vad är telefonnummret till de personer som ridit hästar med en mankhöjd över 2 meter? 2m_hästar(Häst PI Namn (SIGMA Mankhöjd>2 (HÄST 2m_personer(Personnumner PI Person (RIDTILLFÄLLE NATURAL JOIN 2m_hästar PI Namn,Telefon (2m_personer NATURAL JOIN PERSON SELECT Namn, Telefon, HÄST WHERE Personnummer = Person AND HÄST.Namn = RIDTILLFÄLLE.Häst AND Mankhöjd > 2 e Vilka hästar har aldrig ridits? PI Namn (HÄST - PI Häst (RIDTILLFÄLLE SELECT Namn FROM HÄST
WHERE Namn NOT IN FROM RIDTILLFÄLLE f Vilken häst har högst mankhöjd? högst PI MAX(Mankhöjd (HÄST PI Namn (HÄST JOIN Häst.Mankhöjd=Högst.Mankhöjd Högst SELECT Namn FROM HÄST WHERE Mankhöjd = (SELECT MAX(Mankhöjd FROM H ÄST g Ge Namn, Adress och telefonnumemr till de personer som ridit både hästen Darley Arabian och hästen Bayerly Turk. Darleyriddare PI Person (SIGMA Häst= Darley Arabian RIDTILLFÄLLE Bayerlyriddare PI Person (SIGMA Häst= Bayerly Turk RIDTILLFÄLLE Båda Darleyriddare INTERSECT Bayerlyriddare PI Namn,Adress,Telefonnummer (Båda NATURAL JOIN PERSON CREATE VIEW Båda AS ( (SELECT Personnummer AND Häst = Darley Arabian INTERSECT (SELECT Personnummer AND Häst = Bayerly Turk SELECT Namn, Adress, Telefonnummer FROM Båda, PERSON WHERE Båda.Personnummer = PERSON.Personnummer
h Ge Namn, Adress och telefonnummer till de personer som ridit hästen Darley Arabian eller hästen Bayerly Turk men inte båda hästarna. Kandidater PI Person (SIGMA Häst= Darley Arabian OR Häst= Bayerly Turk (RIDTILLFÄLLE Darleyriddare PI Person (SIGMA Häst= Darley Arabian (RIDTILLFÄLLE Bayerlyriddare PI Person (SIGMA Häst= Bayerly Turk (RIDTILLFÄLLE Båda Darleyriddare INTERSECT Bayerlyriddare Nästanklart Kandidater - Båda PI Namn,Adress,Telefonnummer (Nästanklart NATURAL JOIN PERSON CREATE VIEW Nästaklart AS ( (SELECT Personnummer, HÄST AND ((Häst = Darley Arabian OR (Häst = Bayerly Turk DIFFERENCE ((SELECT Personnummer AND Häst = Darley Arabian INTERSECT (SELECT Personnummer AND Häst = Bayerly Turk SELECT Namn, Adress, Telefonnummer FROM Nästanklart, PERSON WHERE Båda.Personnummer = PERSON.Personnummer Skapa en trigger som stipulerar att en person endast kan rida en häst per ridtillfälle och att en häst endast kan ridas av en person per ridtillfälle.
Notera först att primärnyckeln i denna tabell (RIDTILLFÄLLEINTE är korrekt (vilket inte var avsikten med uppgiften i och för sig. Givet att en person kan rida max en häst per ridtillfälle och vice versa så har vi två medlemmar i mängden av kandidatnycklar: {(Lektion, Person, (Lektion, Häst} Det räcker alltså att välja antingen Lektion+Person eller Lektion+Häst att ingå i primärnyckeln. Och då finns det ju bättre sätt att lösa uniciteten hos paren Lektion/Person respektive Lektion/Häst än att skriva en trigger. Nämligen att definiera ett av paren som PN (då kommer databashanteringssystemet att upprätthålla unicitet och sen definiera en contraint (via ALTER TABLE tex som säger att även paret Lektion/Häst ska vara unikt. Men för att ändå öva på en trigger (vilket var meningen med uppgiften så bortser jag från detta och implementerar att en person inte kan rida flera hästar per RIDTILLFÄLLE och att en häst inte kan ridas av flera personer per RIDTILLFÄLLE i följande trigger: CREATE TRIGGER personhastlektion AFTER INSERT ON RIDTILLFÄLLE REFERENCING NEW AS n FOR EACH ROW MODE DB2SQL WHEN (n.lektion IN (SELECT Lektion FROM ridtillfälle RT WHERE ((RT.Person = n.person AND RT.Häst!= n.häst OR (RT.Person!= n.person AND RT.Häst = n.häst AND n.lektion = RT.Lektion DELETE FROM ridtillfälle WHERE (Person=n.Person AND Häst=n.Häst AND Lektion=n.Lektion Om man vill BÅDE göra DELETE och SIGNAL:era vad som var fel till användaren kan man omge sina actions med ett BEGIN ATOMIC action 1 ; action 2 ; ; action n ; END tex: CREATE TRIGGER personhastlektion AFTER INSERT ON RIDTILLFÄLLE REFERENCING NEW AS n FOR EACH ROW MODE DB2SQL WHEN (n.lektion IN (SELECT Lektion FROM ridtillfälle RT WHERE ((RT.Person = n.person AND RT.Häst!= n.häst OR (RT.Person!= n.person AND RT.Häst = n.häst AND n.lektion = RT.Lektion BEGIN ATOMIC
DELETE FROM ridtillfälle WHERE (Person=n.Person AND Häst=n.Häst AND Lektion=n.Lektion ; SIGNAL SQLSTATE 75000 ( En person får bara rida en häst per lektion och vice versa ; END Ett litet problem med detta är att just Command Center i DB2 inte vill ta semikolon som avskiljare mellan actions inne i triggern. Det går däremot bra att köra koden ovan i ett Command Line Processor fönster (där optionen t, dvs att semikolon tolkas som satsavskiljare är på. Ett ytterligare alternativ är att använda det grafiska trigger-verktyget i Control Center. Även där går det bra att stipulera flera händelser, i vårt fall DELETE och SIGNAL, i sin trigger. ÖVNING 14 Förutsätt samma databasschema som i övning 13. Översätt till SQL och relationsalgebra: a Vilka personer har ridit samtliga hästar? alla_hästar(häst PI Namn (HÄST person_häst PI Person,Häst (RIDTILLFÄLLE person_häst KVOT alla_hästar SELECT Personnummer FROM PERSON WHERE NOT EXISTS (SELECT H.Namn FROM HÄST H WHERE H.Namn NOT IN FROM RIDTILLFÄLLE b Vilka personer har ridit samtliga hästar utom Darley Arabian? alla_utom_darley(häst PI Namn (SIGMA Namn! = Darley Arabian (HÄST person_häst PI Person,Häst (RIDTILLFÄLLE nästan person_häst KVOT alla_utom_darley nästan (PI Person (SIGMA Namn = Darley Arabian (RIDTILLFÄLLE SELECT Personnummer FROM PERSON WHERE NOT EXISTS (SELECT H.Namn FROM HÄST H
WHERE H.Namn!= Darley Arabian AND H.Namn NOT IN FROM RIDTILLFÄLLE AND Personnummer NOT IN (SELECT Person FROM RIDTILLFÄLLE WHERE Häst = Darley Arabian c Vem har ridit hästen Bayerly Turk flest gånger? Bayerlyriddare SIGMA Namn = Bayerly Turk (RIDTILLFÄLLE Person_summor(Person, Antal Person F Count(Häst (Bayerlyriddare Maxet F MAX(Antal (Personsummor PI Person (SIGMA Personsummor.Antal=Maxet.Antal (Personsummor X Maxet CREATE VIEW Bayerlyriddare AS (SELECT Person, Häst, Lektion FROM RIDTILLFÄLLE WHERE Häst = Bayerly Turk CREATE VIEW Personsummor AS (SELECT Person, count(häst AS Antal FROM Bayerlyriddare GROUP BY Person SELECT Person, Antal FROM Personsummor WHERE Antal = (SELECT MAX(Antal FROM Personsummor d Vilka (par av personer har ridit exakt samma hästar? Ingen lösning på relationsalgabran (än alla förslag emottages varmt! SELECT P1.Personnummer, P2.Personnumer FROM PERSON P1, PERSON P2 WHERE P1.Personnummer!= P2.Personnummer AND NOT EXISTS (SELECT RT1.Häst FROM RIDTILLFÄLLE RT1 WHERE RT1.Person=P2.Personnummer AND RT1.Häst NOT IN
FROM RIDTILLFÄLLE RT2 WHERE RT2.Person = P1.Personnummer AND NOT EXISTS (SELECT RT1.Häst FROM RIDTILLFÄLLE RT1 WHERE RT1.Person=P1.Personnummer AND RT1.Häst NOT IN FROM RIDTILLFÄLLE RT2 WHERE RT2.Person = P2.Personnummer e Ange favoritmat för de hästar som ridits vid minst två tillfällen. RT1 RIDTILLFÄLLE RT2 RIDTILLFÄLLE H Häst PI (Namn,Favoritmat (SIGMA (RT1.Häst=Namn AND (RT2.Häst=Namn AND ((RT1.Person!=RT2.Person OR (RT.Lektion!=RT1.Lektion (RT1 X RT2 X HÄST SELECT Namn, Favoritmat FROM HÄST, RIDTILLFÄLLE RT1, RIDTILLFÄLLE RT2 WHERE RT1.Häst = Namn AND RT2.Häst = Namn AND ((RT1.Person!= RT2.Person OR (RT1.Lektion!= RT2.Lektion ÖVNING 15 Betrakta följande relationsschema: PERSON(Personnummer, Kön, Fader, Moder PERSON.Fader << PERSON.Personnummer PERSON.Moder << PERSON.Personnummer Definiera följande vyer med SQL och relationsalgebra: FASTER(Person, Faster MORFAR(Person, Morfar FÖRFADER(Person, Förfader CREATE VIEW Faster(Person, Faster AS (SELECT Barn.Personnnummer, Faster.Personnummer FROM PERSON Barn, Person Far, Person Farfar, Person Farmor, Person Faster WHERE Barn.Fader=Far.Personnummer AND Far.Fader=Farfar.Personnummer AND Far.Moder=Farmor.Personnummer
AND Faster.Fader=Farfar.Personnummer AND Faster.Moder=Farmor.Personnummer CREATE VIEW Morfar(Person, Morfar AS (SELECT Barn.Personnnummer, Morfar.Personnummer FROM PERSON Barn, Person Mor, Person Morfar WHERE Barn.Moder=Mor.Personnummer AND Mor.Fader=Morfar.Personnummer CREATE VIEW Faster(Person, Faster AS (SELECT Barn.Personnnummer, Faster.Personnummer FROM PERSON Barn, Person Far, Person Farfar, Person Farmor, Person Faster WHERE Barn.Fader=Far.Personnummer AND Far.Fader=Farfar.Personnummer AND Far.Moder=Farmor.Personnummer AND Faster.Fader=Farfar.Personnummer AND Faster.Moder=Farmor.Personnummer CREATE VIEW Förfader(Person, Förfader AS (SELECT Barn.Personnnummer, Förfader.Personnummer FROM PERSON Barn, PERSON Förfader WHERE Barn.Fader=Förfader.Personnummer OR Barn.Moder=Förfader.Personnummer OR (Barn.Moder, Förfader.Personnummer IN (SELECT Person, Förfader FROM Förfader OR (Barn.Fader, Förfader.Personnummer IN (SELECT Person, Förfader FROM Förfader