Hvis du har en fremmednøgle-begrænsning i SQL Server, som i øjeblikket er deaktiveret, kan du bruge koden nedenfor til at genaktivere den.
Når du aktiverer en fremmednøglebegrænsning, har du mulighed for at angive, om du vil kontrollere eksisterende data i tabellen eller ej. Dette gælder også, når du aktiverer en CHECK
begrænsning.
Nedenfor er kodeeksempler på aktivering af en fremmednøglebegrænsning, mens hver af disse forskellige muligheder specificeres.
Eksempel 1 – Aktiver en begrænsning ved hjælp af MED KONTROL
Dette er den anbefalede metode (medmindre du har en specifik grund til ikke at bruge den).
Her er et eksempel på aktivering af en fremmednøgle-begrænsning kaldet FK_Albums_Artists
:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;
Her angiver jeg udtrykkeligt WITH CHECK
, som fortæller SQL Server at kontrollere de eksisterende data, før begrænsningen aktiveres. Hvis nogen data overtræder begrænsningen, vil begrænsningen ikke blive aktiveret, og du får en fejlmeddelelse.
Det er godt, fordi det håndhæver referentiel integritet.
Når du opretter en ny fremmednøglebegrænsning, er dette standardindstillingen. Men når du aktiverer en eksisterende begrænsning (som vi gør her), er det ikke standardindstillingen.
Eksempel 2 – Aktiver en begrænsning ved hjælp af MED NOCHECK
I dette eksempel er begrænsningen aktiveret uden at kontrollere de eksisterende data:
ALTER TABLE Albums WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;
Her angiver jeg udtrykkeligt WITH NOCHECK
, som fortæller SQL Server ikke at kontrollere de eksisterende data. Dette betyder, at begrænsningen vil blive aktiveret, selvom tabellen allerede indeholder data, der overtræder begrænsningen.
Dette er standardindstillingen, når du aktiverer en begrænsning (men ikke når du opretter en).
En af de få grunde (sandsynligvis den eneste grund) du ville bruge dette er, hvis du vil beholde ugyldige data i databasen. Måske har du en enkeltstående undtagelse, hvor du skal indtaste en række eller flere ugyldige data, men du kræver, at alle fremtidige data overholder begrænsningen.
Der er dog stadig risici forbundet med at gøre dette. Her er, hvad Microsoft har at sige om dette:
Vi anbefaler ikke at gøre dette, undtagen i sjældne tilfælde. Den nye begrænsning evalueres i alle senere dataopdateringer. Eventuelle overtrædelser af begrænsninger, der undertrykkes af WITH NOCHECK
Når begrænsningen tilføjes, kan det medføre, at fremtidige opdateringer mislykkes, hvis de opdaterer rækker med data, der ikke følger begrænsningen.
Så ved at bruge WITH NOCHECK
kan potentielt forårsage problemer senere.
Eksempel 3 – Aktiver en begrænsning ved hjælp af standardindstillingen
Her er et eksempel, der bruger standardindstillingen:
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists;
Dette eksempel svarer til det foregående eksempel. Fordi jeg ikke specificerede, om jeg skulle kontrollere eller ej, antager SQL Server, at jeg vil have WITH NOCHECK
.
Så sørg for eksplicit at angive WITH CHECK
hvis du vil undgå problemer med referenceintegritet.
Brug af WITH NOCHECK fjerner tillid
Når du aktiverer en begrænsning ved hjælp af (standard) WITH NOCHECK
, en konsekvens du bør være opmærksom på er, at SQL Server ikke længere vil stole på denne begrænsning. Det markerer det som ikke betroet. Faktisk er det allerede markeret som ikke betroet, når du deaktiverer begrænsningen.
SQL Server har en is_not_trusted
flag, som den sætter til 1
når du deaktiverer en fremmednøgle-begrænsning (hvilket betyder, at den ikke er tillid til), og den eneste måde at indstille den til 0
(trusted) er at angive WITH CHECK
når du genaktiverer begrænsningen. På den anden side bruger du WITH NOCHECK
bare aktiverer det uden at kontrollere eksisterende data.
Ved at bruge WITH CHECK
, sikrer du, at begrænsningen kontrollerer alle eksisterende data, før den aktiveres. Den eneste måde, det kan aktiveres på, er, hvis alle eksisterende data er i overensstemmelse med begrænsningen. Når den har kontrolleret alle eksisterende data, kan begrænsningen derefter stoles på.
Eksempel 4 – Tjek statussen Trusted/Deaktiveret
Du kan kontrollere statussen for tillid og deaktiveret ved at forespørge på sys.foreign_keys
systemvisning.
Sådan:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Resultat:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Dette fortæller mig, at den begrænsning, som jeg aktiverede i det forrige eksempel ( FK_Albums_Artists ) er ikke tillid til.
Dette er fordi jeg aktiverede det ved at bruge standardindstillingen, som er WITH NOCHECK
.
Hvis jeg genaktiverer den ved hjælp af WITH CHECK
, her er hvad der sker:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Resultat:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 0 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Heldigvis i dette tilfælde havde jeg ingen data, der overtrådte begrænsningen, så begrænsningen blev aktiveret, og dens tillid blev genoprettet.
Hvis der var data, der overtrådte begrænsningen, ville der være blevet vist en fejl, og jeg ville være tvunget til at rette dataene, før jeg kunne genoprette tilliden til begrænsningen.