Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak przywrócić zaufanie w ograniczeniu klucza obcego w programie SQL Server (przykłady T-SQL)

W SQL Server, ograniczenie klucza obcego (i CHECK) ograniczenie) może być zaufana lub niezaufana.

Kiedy ograniczenie jest zaufane, oznacza to, że ograniczenie zostało zweryfikowane przez system. Gdy nie jest zaufane, ograniczenie nie zostały zweryfikowane przez system.

Zasadniczo, gdy masz niezaufane ograniczenie, możesz również mieć nieprawidłowe dane w swojej bazie danych. Rozumiem przez to, że możesz mieć dane, które naruszają ograniczenie.

Oznacza to, że nie zachowujesz już integralności referencyjnej w swoich relacjach, co zwykle nie jest dobrą praktyką podczas dbania o relacyjną bazę danych w środowisku produkcyjnym.

W tym artykule sprawdzę moje istniejące ograniczenia pod kątem ich „wiarygodności”, a następnie zaktualizuję je, aby ponownie stały się godne zaufania.

Przykład 1 – Sprawdź istniejące ograniczenia

Możesz dowiedzieć się, czy ograniczenie jest zaufane, czy nie, wysyłając zapytanie do sys.foreign_keys widok systemu.

Tak:

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

Wynik:

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

OK, to mówi mi, że mam dwa ograniczenia klucza obcego i oba z nich nie są zaufane.

Jedno z ograniczeń jest wyłączone, więc ma sens, że nie jest zaufane (złe dane mogą dostać się do bazy danych, gdy ograniczenie jest wyłączone).

Ale drugie ograniczenie jest włączone, więc naprawdę nie powinno być nieufne. Brak zaufania oznacza, że ​​w bazie danych mogą znajdować się nieprawidłowe dane. Nie oznacza to, że jest nieprawidłowe dane, tylko że może być.

Zasadniczo, po włączeniu, sprawdzi przyszłe dane, ale nie może ręczyć za istniejące dane. Jeśli ograniczenie jest zaufane, możesz być pewien, że wszystkie istniejące dane są prawidłowe.

Zwróć tylko niezaufane ograniczenia

Może się okazać, że wolisz użyć WHERE klauzula zwracająca tylko niezaufane ograniczenia. Tak:

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

Wynik:

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

Więc w tym przypadku wynik jest taki sam (ponieważ wszystkie obecne ograniczenia są niezaufane).

Przykład 2 – Przywróć zaufanie

Aby przywrócić zaufanie do włączonego ograniczenia, po prostu włącz je ponownie podczas korzystania z WITH CHECK opcja.

Tak:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;

Teraz, gdy zapytamy sys.foreign_keys otrzymujemy inny wynik:

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

Wynik:

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

Widzimy, że ograniczenie jest teraz zaufane, ponieważ is_not_trusted flaga jest ustawiona na 0 .

Przykład 3 – Jak Ograniczenie stało się Niezaufane?

Po wyłączeniu ograniczenia klucza obcego automatycznie staje się ono niezaufane. Po ponownym włączeniu tego samego ograniczenia masz możliwość przywrócenia jego zaufania. Jeśli tego nie zrobisz, pozostanie niezaufane.

Po włączeniu ograniczenia klucza obcego masz możliwość określenia WITH CHECK lub WITH NOCHECK . Jeśli określisz później, Twoje ograniczenie pozostanie niezaufane po włączeniu.

Należy pamiętać, że WITH NOCHECK jest opcją domyślną, więc jeśli nie określisz wyraźnie, że powinno być zaufane, ograniczenie zostanie włączone jako niezaufane.

Jednak jest odwrotnie, gdy tworzysz ograniczenie klucza obcego. Kiedy tworzysz ograniczenie po raz pierwszy, domyślną opcją jest WITH CHECK . Jeśli więc pominiesz to ustawienie, będzie ono domyślnie zaufane (chyba że masz nieprawidłowe dane, w takim przypadku nie zostanie włączone). Możesz jednak zmienić to ustawienie, jawnie określając WITH NOCHECK kiedy tworzysz ograniczenie.

Aby zademonstrować, jak twoje włączone ograniczenia mogą łatwo pozostać niezaufane, ponownie włączę drugi klucz (wyłączony), ale użyję ustawienia domyślnego:

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

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

Wynik:

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

Więc będąc leniwym (lub zapominalskim) i nie określając jawnie WITH CHECK , udało mi się włączyć ograniczenie, zachowując jego status „niezaufany” w stanie nienaruszonym.

Kluczowym wnioskiem z tego jest:jeśli chcesz, aby Twoje ponownie włączone ograniczenia były zaufane, zawsze powinieneś je włączać za pomocą WITH CHECK .


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Konwertuj „datetime2” na „datetimeoffset” w SQL Server (przykłady T-SQL)

  2. Jaka jest różnica między VARCHAR i NVARCHAR w serwerze SQL - SQL Server / T-SQL Tutorial Część 32

  3. Klucz obcy do klucza złożonego

  4. T-sql - określ, czy wartość jest liczbą całkowitą

  5. Kiedy powinienem użyć CROSS APPLY zamiast INNER JOIN?