Tabelldefinisjoner og valideringsregler.
CREATE TABLE Kommune
(
KommuneNr CHAR(4),
KommuneNavn VARCHAR(50) UNIQUE NOT NULL,
CONSTRAINT KommunePN PRIMARY KEY ( KommuneNr )
);
CREATE TABLE Bilmodell
(
Bilmerke VARCHAR(50),
Bilmodell VARCHAR(50),
Gruppe CHAR(15),
AntallHK SMALLINT NOT NULL,
CONSTRAINT BilmodellPN PRIMARY KEY (Bilmerke, Bilmodell ),
CONSTRAINT RegelBilgruppe CHECK
( Gruppe IN ( 'personbil', 'varebil', 'lastebil', 'buss' ) ),
CONSTRAINT RegelHestekrefter CHECK
( AntallHK BETWEEN 1 AND 299 )
);
CREATE TABLE Bilsalg
(
Bilmerke VARCHAR(50),
Bilmodell VARCHAR(50),
KommuneNr CHAR(4),
År SMALLINT,
Måned SMALLINT,
Antall SMALLINT NOT NULL,
CONSTRAINT BilsalgPN PRIMARY KEY
(Bilmerke, Bilmodell, KommuneNr, År, Måned ),
CONSTRAINT KommuneFN
FOREIGN KEY (KommuneNr) REFERENCES Kommune (KommuneNr),
CONSTRAINT BilmodellFN FOREIGN KEY (Bilmerke, Bilmodell)
REFERENCES Bilmodell (Bilmerke, Bilmodell),
CONSTRAINT RegelÅr CHECK
( År BETWEEN 1980 AND 2100 ),
CONSTRAINT RegelMåned CHECK
( Måned BETWEEN 1 AND 12 )
);
MS Access må settes opp med støtte for SQL Server syntaks for å kunne bruke CHECK-regler. Med standardoppsett må reglene i stedet legges inn som valideringsregler ved tabelldefinisjon i utformingsvisning.
MySQL godtar syntaksen for CHECK, men utfører ikke kontrollen. Man kan i stedet bruke triggere, se kapittel 13.
MariaDB har ikke støtte for CHECK og gir feilmelding. Igjen er løsningen å bruker triggere.
I følge oppgaveteksten skulle man sikre at KommuneNavn ikke skulle inneholde repetisjoner. Teknisk gjøres dette med UNIQUE som vist i koden over. I praksis er det en dårlig idé, fordi det faktisk finnes flere kommuner med samme navn.
Registrere en ny bilmodell.
INSERT INTO Bilmodell(Bilmerke, Bilmodell, Gruppe, AntallHK)
VALUES ('Toyota', 'Avensis', 'personbil', 90);
Endre antall hestekrefter for bilmodellen (fra 1b).
UPDATE Bilmodell
SET AntallHK = 95
WHERE Bilmerke = 'Toyota' AND Bilmodell = 'Avensis'
Slette bilmodellen (fra 1b).
DELETE FROM Bilmodell
WHERE Bilmerke = 'Toyota' AND Bilmodell = 'Avensis'
Bruk av fremmednøkler for å begrense lovlige verdier.
Definer en ny tabell Gruppe med en enkelt kolonne Betegnelse. Fyll tabellen med fire rader (personbil, varebil, lastebil og buss), og la Bilmodell.Gruppe være fremmednøkkel mot den nye tabellen. Alternativt kan man innføre et løpenummer Gruppe.GruppeNr som primærnøkkel, og lagre dette nummeret i Bilmodell (Bilmodell.Gruppe må da få en talldatatype).
Primærnøkkel for RolleIFilm.
Alle de tre forslagene til primærnøkkel blir for strenge. Løsningen er å definere FilmNr+Rollenavn+Skuespiller som primærnøkkel.
Skriptfil for videobutikken Blanca.
MS Access har ikke funksjonalitet for å utføre skriptfiler. Hver enkelt SQL-setning må utføres for seg.
DROP TABLE Utleie;
DROP TABLE Eksemplar;
DROP TABLE Film;
DROP TABLE Kunde;
CREATE TABLE Kunde
(
KNr INTEGER,
Fornavn VARCHAR(50),
Etternavn VARCHAR(50),
CONSTRAINT KundePN PRIMARY KEY (KNr)
);
CREATE TABLE Film
(
FNr INTEGER,
Tittel VARCHAR(100),
År SMALLINT,
Land VARCHAR(100),
Sjanger VARCHAR(50),
Alder SMALLINT,
Tid SMALLINT,
Pris DECIMAL(8,2),
CONSTRAINT FilmPN PRIMARY KEY (FNr)
);
CREATE TABLE Eksemplar
(
FNr INTEGER,
EksNr SMALLINT,
Format CHAR(3),
CONSTRAINT EksemplarPN PRIMARY KEY (FNr, EksNr),
CONSTRAINT FilmFN FOREIGN KEY (FNr)
REFERENCES Film (FNr)
);
CREATE TABLE Utleie
(
FNr INTEGER,
EksNr SMALLINT,
Dato DATE,
KlSlett TIME,
KNr INTEGER,
CONSTRAINT UtleiePN PRIMARY KEY (FNr, EksNr, Dato, KlSLett),
CONSTRAINT UtleieFN1 FOREIGN KEY (KNr)
REFERENCES Kunde (KNr),
CONSTRAINT UtleieFN2 FOREIGN KEY (FNr, EksNr)
REFERENCES Eksemplar (FNr, EksNr)
);
INSERT INTO Kunde(KNr, Fornavn, Etternavn)
VALUES (1, 'Ola', 'Hansen');
INSERT INTO Kunde(KNr, Fornavn, Etternavn)
VALUES (2, 'Lise', 'Pettersen');
INSERT INTO Film(FilmNr, Tittel, År, Land, Sjanger, Alder, Tid, Pris)
VALUES (1, 'Casablanca', 1942, 'USA', 'Drama', 15, 102, 149.00)
INSERT INTO Eksemplar(FNr, EksNr, Format)
VALUES (1, 1, 'DVD');
INSERT INTO Eksemplar(FNr, EksNr, Format)
VALUES (1, 2, 'Blue-ray');
INSERT INTO Utleie(FNr, EksNr, Dato, KlSlett, KNr)
VALUES (1, 1, '02.01.2015', '14:45', 1);
INSERT INTO Utleie(FNr, EksNr, Dato, KlSlett, KNr)
VALUES (1, 2, '02.01.2015', '14:53', 1);
Det er naturlig å vurdere autonummerering for Kunde.KNr og Film.FNr.
I MS Access kan Film.Pris gis datatype CURRENCY.
Skriptfil for forsikringsselskap.
Vi bruker her en mer kompakt måte å skrive INSERT-setninger, der flere rader settes inn uten å gjenta kolonnenavnene for hver gang. Dette fungerer bla. i MySQL.
DROP TABLE IF EXISTS Skadesak;
DROP TABLE IF EXISTS Forsikring;
DROP TABLE IF EXISTS Kunde;
CREATE TABLE Kunde
(
KundeNr INT AUTO_INCREMENT,
FødselsDato DATE,
Fornavn VARCHAR(30),
Etternavn VARCHAR(50),
CONSTRAINT KundePK PRIMARY KEY (KundeNr)
);
CREATE TABLE Forsikring
(
ForsNr INT AUTO_INCREMENT,
KundeNr INT NOT NULL,
RegNr CHAR(7) UNIQUE NOT NULL,
RegAar INT NOT NULL,
KmPrAar INT NOT NULL,
ForsType VARCHAR(10) NOT NULL,
Bonus INT,
AarsPremie DECIMAL(8, 2),
CONSTRAINT ForsikringPK PRIMARY KEY (ForsNr),
CONSTRAINT ForsikringKundeFK FOREIGN KEY (KundeNr) REFERENCES Kunde(KundeNr)
);
CREATE TABLE Skadesak
(
SaksNr INT AUTO_INCREMENT,
ForsNr INT NOT NULL,
RegDato DATE,
SkadeType VARCHAR(30),
CONSTRAINT SkadesakPK PRIMARY KEY (SaksNr),
CONSTRAINT SkadesakForsikringFK FOREIGN KEY (ForsNr) REFERENCES Forsikring(ForsNr)
);
INSERT INTO
Kunde(FødselsDato, Fornavn, Etternavn)
VALUES
('1988-07-17', 'Ola', 'Hansen'),
('1991-11-04', 'Kari', 'Mo'),
('1970-02-28', 'Anette', 'Lien');
INSERT INTO
Forsikring(KundeNr, RegNr, RegAar, KmPrAar, ForsType, Bonus, AarsPremie)
VALUES
(1, 'LY12345', 2012, 22000, 'Kasko', 50, 4500.00),
(1, 'AD33445', 1997, 11000, 'Ansvar', 70, 2300.00),
(2, 'KZ99887', 2010, 18000, 'Kasko', 20, 7800.00),
(3, 'PN29298', 2010, 25000, 'Delkasko', 50, 5200.00);
INSERT INTO
Skadesak(ForsNr, RegDato, SkadeType)
VALUES
(1, '2014-02-10', 'Kollisjon'),
(2, '2014-12-16', 'Brannskade'),
(2, '2015-07-30', 'Kollisjon'),
(2, '2015-10-01', 'Tyveri'),
(3, '2015-10-30', 'Glassrute');