Avanceret SQL
I dette kapitel vil vi se nærmere på den mere avancerede SQL — den man relativ sjældent bruger, og som derfor ikke kan betegnes som introducerende.
1. Nøgler
1.1 Kandidatnøgler
UNIQUE Vi har set hvordan man kan erklære en attribut som værende primærnøgle (eller flere, hvis det er en sammensat primærnøgle). Men en attribut kan også være kandidatnøgle uden at blive valgt som primærnøgle. En sådan attribut kunne have været primærnøgle, idet den altid har en unique værdi. Man kan angive for en attribut, at den kun må have unique værdier med UNIQUE.
I vores PersonDB er nr primærnøgle i postnummer-tabellen, men navnet på de forskellige postdistrikter og faktisk også unique — der er ikke to der hedder det samme! Vi kan sikre at denne egenskab bliver håndhævet af databasen (man vil få en fejl, hvis man prøver at indsætte værdier for attributten, der ikke er unique) med:
Source 1:
Ved attributten
CREATE TABLE postnummer (
  nr int,
  byen nvarchar(15) NOT NULL UNIQUE,
  
  PRIMARY KEY (nr)
)
eller:
Source 2:
Til sidst
CREATE TABLE postnummer (
  nr int,
  byen nvarchar(15) NOT NULL,
  
  PRIMARY KEY (nr),
  
  UNIQUE (byen)
)
Man ser at syntaksen (og det, at der er to måder hvorpå man kan skrive den) ligner erklæringen af primærnøgler.
Kan være null Bemærk, at man kan erklære en attribut unique selvom den tillader null-værdier. Det lyder umiddelbart lidt ulogisk, men man skal huske, at null i SQL har den specielle egenskab, at den ikke er lig med noget — heller ikke den selv (i.e. null != null). Man kan erklære et vilkårligt antal attributter unique.
1.2 Fremmednøgler
Når man erklærer en attribut, der er fremmednøgle, kan man både angive dette, samt hvilken primærnøgle den refererer til.
I vores PersonDB har person-tabellen en fremmednøgle: post_nummer, der refererer til primærnøglen: nr, i postnummer-tabellen. Dette kan i erklæringen af person-tabellen, anføres som:
Source 3:
Ved attributten
CREATE TABLE person (
  id int IDENTITY,
  navn varchar(25) NOT NULL,
  gade varchar(20),
  nr int,
  post_nummer int FOREIGN KEY REFERENCES postnummer(nr),
  alder int,
  
  PRIMARY KEY (id)
)
eller:
Source 4:
Til sidst
CREATE TABLE person (
  id int IDENTITY,
  navn varchar(25) NOT NULL,
  gade varchar(20),
  nr int,
  post_nummer int,
  alder int,
  
  PRIMARY KEY (id),
  
  FOREIGN KEY (post_nummer) REFERENCES postnummer(nr)
)
Man ser igen, at syntaksen er i stil med angivelsen af en primærnøgle (og en kandidatnøgle).
Hvis attributten har samme navn i begge tabeller, kan man udelade angivelsen ved tabel-navnet, altså: FOREIGN KEY (post_nummer) REFERENCES postnummer. Altså i dette tilfælde, hvis attributten hed: post_nummer, i begge tabeller (men det gør den ikke!).
Bemærk, at den tabel der refereres til skal være erklæret før dette (i vores script), ellers får man en fejlmeddelelse om at tabellen ikke findes!
1.2.1 Referentiel integritet
RESTRICT, CASCADE, SET NULL I forbindelse med erklæringen af fremmednøgler, har man også mulighed for at angive hvordan den referentielle integritet skal opretholdes ved henholdsvis sletning og opdatering af rækker i den tabel der refereres til. Der er de tre muligheder: RESTRICT (ikke tillade hverken sletning eller opdatering, hvis der er en fremmednøgle der refererer til primærnøglen), CASCADE (der ved sletning sletter de rækker, der har en fremmednøgle, der refererer til primærnøglen, og ved opdatering opdaterer fremmednøglerne) og SET NULL (hvor fremmednøglens værdi både ved sletning og opdatering sættes til null, hvis den refererede til primærnøglen). Man anfører både for sletning og opdatering, hvilken af de tre teknikker, der skal anvendes.
I vores PersonDB kunne dette f.eks. gøres for post_nummer i person-tabellen:
Source 5:
Referentiel integritet
CREATE TABLE person (
  id int IDENTITY,
  navn varchar(25) NOT NULL,
  gade varchar(20),
  nr int,
  post_nummer int,
  alder int,
  
  PRIMARY KEY (id),
  
  FOREIGN KEY (post_nummer)
    REFERENCES postnummer(nr)
    ON UPDATE CASCADE
    ON DELETE SET NULL
)
Her har vi valgt, at en ændring af postnummeret i postnummer-tabellen, skal føre til en ændring af de tilsvarende postnumre, der optræder som fremmednøgler i person-tabellen. Ved sletning af et postdistrikter (i.e. række) i postnummer-tabellen, har vi valgt at der skal ændres til null-værdier, for de tilsvarende fremmednøgler i person-tabellen.
2. Ændre tabeller
Når der her tales om at ændre tabeller, tænkes der ikke på rækkerne — nej, der tænkes selve tabellens design!
  [Ikke skrevet færdig]
3. Join
  [Ikke skrevet færdig]
4. Bruger-rettigheder
  [Ikke skrevet færdig]