sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man återställer förtroende för en främmande nyckelbegränsning i SQL Server (T-SQL-exempel)

I SQL Server, en främmande nyckel-begränsning (och en CHECK constraint) kan antingen vara betrodd eller inte betrodd.

När en begränsning är pålitlig betyder det att begränsningen har verifierats av systemet. När den inte är betrodd har begränsningen inte har verifierats av systemet.

I grund och botten, när du har en opålitlig begränsning, kan du också ha ogiltiga data i din databas. Med detta menar jag att du kan ha data som bryter mot begränsningen.

Detta innebär att du inte längre upprätthåller referensintegritet i dina relationer, vilket normalt inte är bra praxis när du tar hand om en relationsdatabas i produktion.

I den här artikeln kommer jag att kontrollera mina befintliga begränsningar för deras "pålitlighet", och sedan uppdaterar jag dem så att de blir pålitliga igen.

Exempel 1 – Granska befintliga begränsningar

Du kan ta reda på om en begränsning är pålitlig eller inte 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 | 1             | 1                |
| FK_Albums_Genres  | 0             | 1                |
+-------------------+---------------+------------------+

OK, så det här säger mig att jag har två begränsningar för främmande nycklar och att båda inte är betrodda.

En av begränsningarna är inaktiverad, så det är logiskt att den inte är betrodd (dålig data kan komma in i databasen när begränsningen är inaktiverad).

Men den andra begränsningen är aktiverad, så den borde verkligen inte vara opålitlig. Att vara opålitlig innebär att det kan finnas ogiltiga data i databasen. Det betyder inte att det finns ogiltig data, bara att det kan vara.

I grund och botten, genom att vara aktiverad, kommer den att kontrollera framtida data, men den kan inte garantera befintliga data. Om en begränsning är pålitlig kan du vara säker på att all befintlig data är giltig.

Returnera endast otillförlitliga begränsningar

Du kanske tycker att du föredrar att använda en WHERE klausul för att endast returnera de opålitliga begränsningarna. Så här:

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

Resultat:

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

Så i det här fallet är resultatet detsamma (eftersom alla nuvarande begränsningar är otillförlitliga).

Exempel 2 – Återställ förtroende

För att återställa förtroendet för din aktiverade begränsning, återaktivera den helt enkelt samtidigt som du använder WITH CHECK alternativ.

Så här:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;

Nu när vi frågar sys.foreign_keys vi får ett annat resultat:

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

Resultat:

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

Vi kan se att begränsningen nu är betrodd, eftersom is_not_trusted flaggan är inställd på 0 .

Exempel 3 – Hur blev begränsningen otillförlitlig?

När du inaktiverar en begränsning av främmande nyckel blir den automatiskt opålitlig. När du återaktiverar samma begränsning har du möjlighet att återställa dess förtroende. Om du inte gör detta förblir den opålitlig.

När du aktiverar en främmande nyckel-begränsning har du möjlighet att ange WITH CHECK eller WITH NOCHECK . Om du anger det senare förblir din begränsning opålitlig när den väl har aktiverats.

Det är viktigt att notera att WITH NOCHECK är standardalternativet, så om du inte uttryckligen anger att det ska vara pålitligt, kommer begränsningen att aktiveras som otillförlitlig.

Det är dock tvärtom när du skapar en främmande nyckel-begränsning. När du först skapar begränsningen är standardalternativet WITH CHECK . Så om du utelämnar den här inställningen kommer den att vara betrodd som standard (såvida du inte har ogiltiga data, i så fall kommer den inte att aktiveras). Du kan dock åsidosätta den här inställningen genom att uttryckligen ange WITH NOCHECK när du skapar begränsningen.

För att visa hur dina aktiverade begränsningar lätt kan förbli opålitliga, återaktiverar jag den andra nyckeln (den inaktiverade), men jag använder standardinställningen:

ALTER TABLE Albums 
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             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Så genom att vara lat (eller glömsk) och inte explicit specificera WITH CHECK , lyckades jag aktivera en begränsning samtidigt som dess status "inte betrodd" behölls intakt.

Nyckeln till detta är:om du vill att dina återaktiverade begränsningar ska vara pålitliga bör du alltid aktivera dem med WITH CHECK .


  1. Beställning av resultat av ivrigt laddade kapslade modeller i Node Sequelize

  2. Spool-kommando:Mata inte ut SQL-satsen till filen

  3. REGEX för att välja n:te värde från en lista, vilket tillåter nollvärden

  4. Använda Oracle JDeveloper 12c med Oracle Database 12c på Oracle Cloud Platform, del 3