sql >> Databáze >  >> RDS >> Sqlserver

Jak povolit omezení cizího klíče v SQL Server (příklady T-SQL)

Pokud máte na serveru SQL Server omezení cizího klíče, které je aktuálně zakázáno, můžete jej znovu povolit pomocí kódu níže.

Když povolíte omezení cizího klíče, máte možnost určit, zda chcete nebo nechcete kontrolovat jakákoli existující data v tabulce. To platí také, když povolíte CHECK omezení.

Níže jsou uvedeny příklady kódu pro povolení omezení cizího klíče při specifikaci každé z těchto různých možností.

Příklad 1 – Povolte omezení pomocí WITH CHECK

Toto je doporučená metoda (pokud nemáte konkrétní důvod ji nepoužívat).

Zde je příklad povolení omezení cizího klíče s názvem FK_Albums_Artists :

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; 

Zde výslovně uvádím WITH CHECK , který říká serveru SQL Server, aby zkontroloval existující data před povolením omezení. Pokud některá data porušují omezení, omezení nebude povoleno a zobrazí se chyba.

To je dobré, protože to vynucuje referenční integritu.

Když vytvoříte nové omezení cizího klíče, jedná se o výchozí nastavení. Když však povolíte existující omezení (jak to děláme zde), není výchozí nastavení.

Příklad 2 – Povolte omezení pomocí WITH NOCHECK

V tomto příkladu je omezení povoleno bez kontroly existujících dat:

ALTER TABLE Albums 
WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;

Zde výslovně uvádím WITH NOCHECK , který říká SQL Serveru, aby nekontroloval existující data. To znamená, že omezení bude povoleno, i když tabulka již obsahuje data, která omezení porušují.

Toto je výchozí nastavení při povolení omezení (ale ne při vytváření omezení).

Jeden z mála důvodů (pravděpodobně jediný důvod), proč byste to použili, je, pokud chcete v databázi ponechat neplatná data. Možná máte jednorázovou výjimku, kdy musíte zadat řádek nebo více neplatných dat, ale požadujete, aby všechna budoucí data odpovídala omezení.

Stále však existují rizika spojená s tím. Zde je to, co k tomu říká společnost Microsoft:

Nedoporučujeme to dělat, s výjimkou vzácných případů. Nové omezení je vyhodnoceno ve všech pozdějších aktualizacích dat. Jakákoli porušení omezení, která jsou potlačena pomocí WITH NOCHECK Když je omezení přidáno, může to způsobit selhání budoucích aktualizací, pokud aktualizují řádky daty, která omezení nedodržují.

Takže pomocí WITH NOCHECK může později způsobit problémy.

Příklad 3 – Povolení omezení pomocí výchozí možnosti

Zde je příklad použití výchozí možnosti:

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

Tento příklad je ekvivalentem předchozího příkladu. Protože jsem nespecifikoval, zda zkontrolovat nebo ne, SQL Server předpokládá, že chci WITH NOCHECK .

Ujistěte se tedy, že jste výslovně uvedli WITH CHECK pokud se chcete vyhnout problémům s referenční integritou.

Použití WITH NOCHECK odstraňuje důvěru

Když povolíte omezení pomocí (výchozí) WITH NOCHECK Jedním z důsledků, o kterém byste si měli být vědomi, je, že SQL Server již nebude tomuto omezení důvěřovat. Označí to jako nedůvěryhodné. Ve skutečnosti je již označen jako nedůvěryhodný, když omezení deaktivujete.

SQL Server má is_not_trusted příznak, který nastaví na 1 když zakážete omezení cizího klíče (což znamená, že není důvěryhodné), a jediný způsob, jak jej nastavit na 0 (důvěryhodný) je zadat WITH CHECK při opětovném povolení omezení. Na druhou stranu pomocí WITH NOCHECK pouze to povolí bez kontroly existujících dat.

Pomocí WITH CHECK , zajistíte, že omezení zkontroluje všechna existující data, než bude povoleno. Jediným způsobem, jak jej lze povolit, je, že všechna existující data vyhovují omezení. Jakmile zkontroluje všechna existující data, může být omezení důvěryhodné.

Příklad 4 – Kontrola stavu Důvěryhodný/Zakázán

Stav důvěryhodnosti a deaktivace můžete zkontrolovat dotazem na sys.foreign_keys systémový pohled.

Takhle:

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

Výsledek:

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

To mi říká, že omezení, které jsem povolil v předchozím příkladu ( FK_Albums_Artists ) není důvěryhodný.

Je to proto, že jsem to povolil pomocí výchozího nastavení, které je WITH NOCHECK .

Pokud jej znovu povolím pomocí WITH CHECK , stane se toto:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;

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

Výsledek:

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

Naštěstí v tomto případě jsem neměl žádná data, která by porušovala omezení, takže omezení bylo úspěšně povoleno a jeho důvěryhodnost byla obnovena.

Pokud by existovala data, která porušovala omezení, zobrazila by se chyba a byl bych nucen data opravit, než budu moci obnovit důvěru v omezení.


  1. Jak vytvořit alias pole nebo sloupce v MySQL?

  2. Jak funguje include() v PL-SQL?

  3. Co je nového v MariaDB Cluster 10.4

  4. Jak MID() funguje v MariaDB