Om du har en främmande nyckel-begränsning i SQL Server som för närvarande är inaktiverad kan du använda koden nedan för att återaktivera den.
När du aktiverar en främmande nyckel-begränsning har du möjlighet att ange om du vill kontrollera befintliga data i tabellen eller inte. Detta gäller även när du aktiverar en CHECK
begränsning.
Nedan finns kodexempel för att aktivera en främmande nyckel-begränsning, samtidigt som du anger vart och ett av dessa olika alternativ.
Exempel 1 – Aktivera en begränsning med hjälp av MED KONTROLL
Detta är den rekommenderade metoden (såvida du inte har en specifik anledning att inte använda den).
Här är ett exempel på att aktivera en främmande nyckel-begränsning som heter FK_Albums_Artists
:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;
Här anger jag uttryckligen WITH CHECK
, som säger åt SQL Server att kontrollera befintlig data innan begränsningen aktiveras. Om någon data bryter mot begränsningen kommer begränsningen inte att aktiveras och du får ett felmeddelande.
Detta är bra, eftersom det upprätthåller referensintegritet.
När du skapar en ny begränsning för främmande nyckel är detta standardinställningen. Men när du aktiverar en befintlig begränsning (som vi gör här), är det inte standardinställningen.
Exempel 2 – Aktivera en begränsning med WITH NOCHECK
I det här exemplet är begränsningen aktiverad utan att kontrollera befintlig data:
ALTER TABLE Albums WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;
Här anger jag uttryckligen WITH NOCHECK
, som säger åt SQL Server att inte kontrollera befintliga data. Detta innebär att begränsningen kommer att aktiveras även om tabellen redan innehåller data som bryter mot begränsningen.
Detta är standardinställningen när du aktiverar en begränsning (men inte när du skapar en).
En av de få anledningarna (förmodligen den enda anledningen) du skulle använda detta är om du vill behålla ogiltiga data i databasen. Du kanske har ett engångsundantag där du måste ange en rad eller fler med ogiltiga data, men du kräver att all framtida data överensstämmer med begränsningen.
Det finns dock fortfarande risker med att göra detta. Här är vad Microsoft har att säga om detta:
Vi rekommenderar inte att du gör detta, förutom i sällsynta fall. Den nya begränsningen utvärderas i alla senare datauppdateringar. Alla begränsningsöverträdelser som undertrycks av
WITH NOCHECK
När begränsningen läggs till kan framtida uppdateringar misslyckas om de uppdaterar rader med data som inte följer begränsningen.
Så använder WITH NOCHECK
kan eventuellt orsaka problem senare.
Exempel 3 – Aktivera en begränsning med hjälp av standardalternativet
Här är ett exempel med standardalternativet:
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists;
Detta exempel är motsvarigheten till föregående exempel. Eftersom jag inte angav om jag skulle kontrollera eller inte, antar SQL Server att jag vill ha WITH NOCHECK
.
Så se till att uttryckligen specificera WITH CHECK
om du vill undvika referensintegritetsproblem.
Att använda WITH NOCHECK tar bort förtroende
När du aktiverar en begränsning med (standard) WITH NOCHECK
, en konsekvens du bör vara medveten om är att SQL Server inte längre kommer att lita på den begränsningen. Den flaggar den som inte betrodd. Egentligen har den redan flaggats som inte betrodd när du inaktiverar begränsningen.
SQL Server har en is_not_trusted
flaggan som den sätter till 1
när du inaktiverar en främmande nyckel-begränsning (vilket betyder att den inte är betrodd), och det enda sättet att ställa in den på 0
(trusted) är att ange WITH CHECK
när du återaktiverar begränsningen. Å andra sidan använder du WITH NOCHECK
bara aktiverar det utan att kontrollera befintliga data.
Genom att använda WITH CHECK
, ser du till att begränsningen kontrollerar all befintlig data innan den aktiveras. Det enda sättet det kan aktiveras är om all befintlig data överensstämmer med begränsningen. När den har kontrollerat alla befintliga data kan begränsningen sedan litas på.
Exempel 4 – Kontrollera statusen Trusted/Disabled
Du kan kontrollera statusen betrodd och inaktiverad genom att fråga sys.foreign_keys
systemvy.
Så här:
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 | +-------------------+---------------+------------------+
Detta säger mig att begränsningen som jag aktiverade i föregående exempel ( FK_Albums_Artists ) är inte betrodd.
Detta beror på att jag aktiverade det med standardinställningen, som är WITH NOCHECK
.
Om jag återaktiverar det med WITH CHECK
, här är vad som händer:
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 | +-------------------+---------------+------------------+
Lyckligtvis hade jag i det här fallet inga data som bröt mot begränsningen, så begränsningen aktiverades framgångsrikt och dess förtroende återställdes.
Om det fanns data som bröt mot begränsningen skulle ett fel ha visats och jag skulle tvingas åtgärda informationen innan jag kunde återställa förtroendet för begränsningen.