sql >> Database >  >> RDS >> Sqlserver

Een beperking van een externe sleutel inschakelen in SQL Server (T-SQL-voorbeelden)

Als u een externe-sleutelbeperking in SQL Server hebt die momenteel is uitgeschakeld, kunt u de onderstaande code gebruiken om deze weer in te schakelen.

Wanneer u een externe-sleutelbeperking inschakelt, hebt u de mogelijkheid om aan te geven of u al dan niet bestaande gegevens in de tabel wilt controleren. Dit geldt ook wanneer u een CHECK . inschakelt beperking.

Hieronder staan ​​codevoorbeelden voor het inschakelen van een externe sleutelbeperking, terwijl u elk van deze verschillende opties specificeert.

Voorbeeld 1 – Schakel een beperking in met WITH CHECK

Dit is de aanbevolen methode (tenzij u een specifieke reden heeft om deze niet te gebruiken).

Hier is een voorbeeld van het inschakelen van een externe sleutelbeperking met de naam FK_Albums_Artists :

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; 

Hier vermeld ik expliciet WITH CHECK , die SQL Server vertelt om de bestaande gegevens te controleren voordat de beperking wordt ingeschakeld. Als gegevens de beperking schenden, wordt de beperking niet ingeschakeld en krijgt u een foutmelding.

Dit is goed, omdat het referentiële integriteit afdwingt.

Wanneer u een nieuwe externe-sleutelbeperking maakt, is dit de standaardinstelling. Wanneer u echter een bestaande beperking inschakelt (zoals we hier doen), is dit niet de standaardinstelling.

Voorbeeld 2 – Schakel een beperking in met WITH NOCHECK

In dit voorbeeld is de beperking ingeschakeld zonder de bestaande gegevens te controleren:

ALTER TABLE Albums 
WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;

Hier vermeld ik expliciet WITH NOCHECK , die SQL Server vertelt om de bestaande gegevens niet te controleren. Dit betekent dat de beperking wordt ingeschakeld, zelfs als de tabel al gegevens bevat die de beperking schenden.

Dit is de standaardinstelling bij het inschakelen van een beperking (maar niet bij het maken ervan).

Een van de weinige redenen (waarschijnlijk de enige reden) dat u dit zou gebruiken, is als u ongeldige gegevens in de database wilt behouden. Misschien heeft u een eenmalige uitzondering waarbij u een rij of meer ongeldige gegevens moet invoeren, maar u wilt dat alle toekomstige gegevens aan de beperking voldoen.

Er zijn echter nog steeds risico's verbonden aan het doen hiervan. Dit is wat Microsoft hierover te zeggen heeft:

We raden af ​​om dit te doen, behalve in zeldzame gevallen. De nieuwe beperking wordt geëvalueerd in alle latere gegevensupdates. Alle beperkingsschendingen die worden onderdrukt door WITH NOCHECK wanneer de beperking wordt toegevoegd, kunnen toekomstige updates mislukken als ze rijen bijwerken met gegevens die niet aan de beperking voldoen.

Dus gebruik WITH NOCHECK kan later mogelijk problemen veroorzaken.

Voorbeeld 3 – Schakel een beperking in met de standaardoptie

Hier is een voorbeeld met de standaardoptie:

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

Dit voorbeeld is het equivalent van het vorige voorbeeld. Omdat ik niet heb aangegeven of ik wel of niet moet controleren, gaat SQL Server ervan uit dat ik WITH NOCHECK wil .

Zorg er dus voor dat u expliciet WITH CHECK opgeeft als u referentiële integriteitsproblemen wilt vermijden.

Gebruik WITH NOCHECK verwijdert vertrouwen

Wanneer u een beperking inschakelt met (de standaard) WITH NOCHECK , is een gevolg waarvan u zich bewust moet zijn dat SQL Server die beperking niet langer zal vertrouwen. Het markeert het als niet vertrouwd. Het is eigenlijk al gemarkeerd als niet vertrouwd wanneer u de beperking uitschakelt.

SQL Server heeft een is_not_trusted vlag die wordt ingesteld op 1 wanneer u een externe sleutelbeperking uitschakelt (wat betekent dat deze niet vertrouwd is), en de enige manier om deze in te stellen op 0 (vertrouwd) is om WITH CHECK op te geven wanneer u de beperking opnieuw inschakelt. Aan de andere kant, met behulp van WITH NOCHECK schakelt het gewoon in zonder bestaande gegevens te controleren.

Door WITH CHECK . te gebruiken , zorgt u ervoor dat de beperking alle bestaande gegevens controleert voordat deze wordt ingeschakeld. De enige manier waarop het kan worden ingeschakeld, is als alle bestaande gegevens voldoen aan de beperking. Nadat alle bestaande gegevens zijn gecontroleerd, kan de beperking worden vertrouwd.

Voorbeeld 4 – Controleer de vertrouwde/uitgeschakelde status

U kunt de vertrouwde en uitgeschakelde status controleren door de sys.foreign_keys . op te vragen systeemweergave.

Zoals dit:

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Resultaat:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Dit vertelt me ​​dat de beperking die ik in het vorige voorbeeld heb ingeschakeld ( FK_Albums_Artists ) wordt niet vertrouwd.

Dit komt omdat ik het heb ingeschakeld met de standaardinstelling, namelijk WITH NOCHECK .

Als ik het opnieuw inschakel met WITH CHECK , dit is wat er gebeurt:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Resultaat:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 0                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Gelukkig had ik in dit geval geen gegevens die de beperking schonden, dus de beperking werd met succes ingeschakeld en het vertrouwen werd hersteld.

Als er gegevens waren die de beperking schenden, zou er een fout zijn weergegeven en zou ik de gegevens moeten herstellen voordat ik het vertrouwen in de beperking kon herstellen.


  1. PostgreSQL implementeren voor hoge beschikbaarheid

  2. Oracle Case Statement uitgelegd met tips en voorbeelden

  3. Hoe Extract() werkt in PostgreSQL

  4. SQL MIN() voor beginners