Kjell Toft Hansen 02.10.2008 Opphavsrett: Forfatter og AITeL Lærestoffet er utviklet for faget LO151D Informatikk 1: databaser Oppgave 1 1. Spørring: SELECT oh.*, delnr, kvantum FROM ordrehode oh, ordredetalj od WHERE oh.levnr = 44 AND oh.ordrenr = od.ordrenr; ordrenr dato levnr status delnr kvantum 13 1986 09 13 44 p 51173 20 14 1986 12 17 44 p 201 100 14 1986 12 17 44 p 202 100 14 1986 12 17 44 p 51173 30 15 1987 01 03 44 p 201 100 15 1987 01 03 44 p 202 100 2. Spørring: SELECT navn, levby FROM levinfo l, prisinfo p WHERE delnr = 1 AND l.levnr = p.levnr; navn levby Kontorekspressen Oslo Kontorutstyr Trondheim 3. Spørring: SELECT l.levnr, navn, ROUNDpris,2) FROM levinfo l, prisinfo p WHERE l.levnr = p.levnr AND delnr = 201 -- hvis flere leverandører har samme minstepris AND pris = SELECT MINpris) FROM prisinfo WHERE delnr = 201
levnr navn pris 44 Billig og Bra 1.60 4. Spørring: SELECT oh.ordrenr, dato, od.delnr, beskrivelse, kvantum, ROUNDpris,2) pris, CONCAT'Sum = ',ROUNDpris*kvantum, 2)) totalpris FROM ordrehode oh, ordredetalj od, delinfo d, prisinfo p WHERE oh.ordrenr = 16 AND oh.ordrenr = od.ordrenr AND od.delnr = p.delnr AND p.levnr = oh.levnr AND od.delnr = d.delnr; ordrenr dato delnr beskrivelse kvantum pris totalpris 16 1987 01 30 201 Svarte kulepenner 50 1.90 Sum = 95.00 16 1987 01 30 202 Blå kulepenner 50 6.50 Sum = 325.00 16 1987 01 30 1909 Skriveunderlag 10 0.85 Sum = 8.50 16 1987 01 30 51173 Binders 20 0.57 Sum = 11.40 5. Spørring: SELECT delnr, levnr FROM prisinfo WHERE pris > SELECT pris FROM prisinfo WHERE katalognr = 'X7770' delnr levnr 1 6 1 9 3 6 3 9 3 82 4 6 4 82 202 6 51200 6 side 2 av 6
6. Hvorfor gjøre noe slikt? Jo, vi har en gammel database der datamodelleringen ikke er nøye nok utført. En glemte at fylke burde ha vært en egen entitetstype og dermed en egen tabell. Relasjonen Levinfo tilfredsstiller ikke 3NF fordi vi har en transitiv avhengighet der. Vi kan også legge merke til at vi burde tatt ut bynavnet og bare beholdt postnummeret i Levinfo, av samme grunn. Vi forsøker nå å rette på dette i ettertid etter at flere applikasjoner jobber mot de eksisterende tabellene. Spørring 1: CREATE TABLE byfylke SELECT DISTINCT levby, fylke FROM levinfo; Legg merke til at tabellen Byfylke blir opprettet uten entitetsintegritet. Dette kan tilføyes i etterkant med: ALTER TABLE byfylke ADD PRIMARY KEYlevby Tabellen vil nå inneholde følgende rader: levby fylke Oslo NULL Trondheim S Trøndelag Ås Østfold Ål Telemark Tabellen har følgende struktur: DESCRIBE byfylke; Field Type Null Key Default Extra levby varchar20) NO PRI fylke varchar20) YES NULL Spørring 2: CREATE TABLE levinfo2 SELECT levnr, navn, adresse, levby, postnr FROM levinfo; Legg merke til at tabellen Levinfo2 blir opprettet uten entitets- og referanseintegritet. Det kan tilføyes i etterkant. ALTER TABLE levinfo2 ADD PRIMARY KEYlevnr), ADD FOREIGN KEYlevby)REFERENCES byfylkelevby side 3 av 6
Tabellen har fått følgende struktur: Field Type Null Key Default Extra levnr int11) NO PRI navn varchar20) NO adresse varchar20) YES NULL levby varchar20) NO MUL postnr int11) NO Tabellen vil nå inneholde følgende rader: levnr navn adresse levby postnr 6 Kontorekspressen Skolegata 3 Oslo 1234 9 Kontorutstyr Villa Villekulla Trondheim 7099 12 Mister Office Storgt 56 Ås 1456 44 Billig og Bra Aveny 56 Oslo 1222 81 Kontorbutikken Gjennomveien 78 Ål 3345 82 Kontordata Åsveien 178 Trondheim 7023 Spørring i): CREATE VIEW lev_utsnitt SELECT levnr, navn, adresse, l.levby, fylke, postnr FROM levinfo2 l, byfylke b WHERE l.levby = b.levby; Nå kan vi hente ut data fra utsnittet: SELECT * FROM lev_utsnitt; Vi følgende resultattabell: levnr navn adresse levby fylke postnr 6 Kontorekspressen Skolegata 3 Oslo NULL 1234 44 Billig og Bra Aveny 56 Oslo NULL 1222 9 Kontorutstyr Villa Villekulla Trondheim S Trøndelag 7099 82 Kontordata Åsveien 178 Trondheim S Trøndelag 7023 12 Mister Office Storgt 56 Ås Østfold 1456 81 Kontorbutikken Gjennomveien 78 Ål Telemark 3345 For å finne ut om vi kan endre de fysiske tabellene Levinfo2 og Fylke ved å sende endringssetninger til vinduet Lev_utsnitt, kan vi slå opp i datakatalogen med følgende datakatalogspørring: SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'lev_utsnitt'; side 4 av 6
Spørringen gir følgende resultattabell: TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE NULL kjellha lev_utsnitt /* ALGORITHM=UNDEFINED NONE YES kjellha@% DEFINER */ select `l`.`levnr` `l... Vi kan endre den tabellen der vi i utsnittet har én rad per primærnøkkelverdi. Her vil det si tabellen Levinfo2. Men vi kan ikke endre tabellen Byfylke via utsnittet Lev_utsnitt) fordi vi kan få mer enn én rad med samme fylkesnavn) i selve utsnittet. Når attributtet fylke er primærnøkkel i Byfylke får vi dermed et brudd på entitetsintegritetsregelen. Hvis vi legger inn følgende data i utsnittet: INSERT INTO lev_utsnitt levnr, navn, adresse, levby, fylke, postnr) VALUES100, 'Binders ', 'Tiller', 'Trondheim', 'S-Trøndelag',7018 Får vi følgende feilmelding: LeverandørbyenTrondheim kan ikke legges inn i tabellen Byfylke fordi den er registrert der fra før og attributtet levby er en primærnøkkel. 7. Spørring: SELECT DISTINCT levby FROM levinfo l WHERE NOT EXISTS SELECT * FROM prisinfo p WHERE l.levnr = p.levnr levby Ås Ål side 5 av 6
8. Spørringer: Trinn1: Lag en virtuell tabell som viser hvem som kan levere hele eller deler av ordren: CREATE VIEW kan_levere_til_ordrenlev_nr, del_nr, pris, total_pris) SELECT levnr, od.delnr, pris, pris*kvantum FROM prisinfo p, ordredetalj od WHERE p.delnr = od.delnr AND ordrenr = 18; Når vi spør mot vinduet Kan_lever_til_ordren får vi følgende resultattabell: lev_nr del_nr pris total_pris 6 3 1199 2398 9 3 1050 2100 82 3 1299 2598 6 4 550 4400 82 4 899 7192 Trinn2: Fra denne velger vi så ut de leverandørene som kan levere like mange deler til ordren som ordren krever. Dvs. kan levere hele ordren: CREATE VIEW kan_levere_hele_ordrenlev_nr, total_pris) SELECT lev_nr, SUMtotal_pris) FROM kan_levere_til_ordren GROUP BY lev_nr HAVING COUNT*) = SELECT COUNT*) FROM ordredetalj WHERE ordrenr = 18 Når vi spør mot vinduet Kan_lever_hele_ordren får vi følgende resultattabell: lev_nr total_pris 6 6798 82 9790 Trinn3: Til slutt finner vi ut hvem som leverer billigst: SELECT lev_nr, total_pris FROM kan_levere_hele_ordren WHERE total_pris = SELECT MINtotal_pris) FROM kan_levere_hele_ordren Vi følgende resultattabell: lev_nr total_pris 6 6798 side 6 av 6