Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come creare una chiave esterna in SQL Server (esempi T-SQL)

In questo articolo viene illustrato come creare una chiave esterna in SQL Server utilizzando Transact-SQL. Mostro come creare una chiave esterna al momento della creazione della tabella (anziché aggiornare una tabella esistente).

Una chiave esterna è una colonna che fa riferimento alla colonna della chiave primaria di un'altra tabella. Questo crea una relazione tra le tabelle.

Esempio 1 – Preparazione

In questo esempio creerò un database di test con una tabella. Questa tabella conterrà la chiave primaria a cui farà riferimento la nostra chiave esterna.

Crea il database:

CREATE DATABASE FK_Test;

Ora crea la tabella delle chiavi primarie:

USE FK_Test;

CREATE TABLE Country
(
    CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    CountryName nvarchar(60)
);

Esempio 2:creare la chiave esterna

Ora che abbiamo una tabella con una chiave primaria, creiamo un'altra tabella con una chiave esterna che faccia riferimento a quella chiave primaria.

CREATE TABLE City
(
    CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    CountryId int NOT NULL REFERENCES Country(CountryId),
    CityName nvarchar(60)
);

Questo è il modo più semplice per creare una chiave esterna. Tutto ciò che facciamo è aggiungere i REFERENCES clausola (insieme alla tabella e alla colonna della chiave primaria) alla colonna che avrà il vincolo di chiave esterna.

Per essere chiari, la parte che definisce la chiave esterna è questa:

REFERENCES Country(CountryId)

Questo è incluso nella definizione della colonna e indica semplicemente che questa colonna farà riferimento a CountryId colonna nel Country tabella.

In questo caso, sia la chiave esterna che la chiave primaria a cui fa riferimento, condividono lo stesso nome (CountryId ). Tuttavia, questo non è un requisito:la colonna della chiave esterna può avere un nome completamente diverso dalla colonna a cui fa riferimento (sebbene tutte le colonne che partecipano a una relazione di chiave esterna debbano essere definite con la stessa lunghezza e scala).

In questo esempio SQL Server genera automaticamente il nome della chiave esterna. Questo perché non ho fornito un nome. Continua a leggere per vedere come creare un nome per la tua chiave esterna.

Ma prima, controlliamo il vincolo di chiave esterna che abbiamo appena creato.

Esempio 3:verifica del vincolo di chiave esterna

Esistono molti modi per restituire una chiave esterna utilizzando T-SQL, ed eccone uno:

EXEC sp_fkeys @fktable_name = City;

Risultato (usando l'output verticale):

PKTABLE_QUALIFIER | FK_Test
PKTABLE_OWNER     | dbo
PKTABLE_NAME      | Country
PKCOLUMN_NAME     | CountryId
FKTABLE_QUALIFIER | FK_Test
FKTABLE_OWNER     | dbo
FKTABLE_NAME      | City
FKCOLUMN_NAME     | CountryId
KEY_SEQ           | 1
UPDATE_RULE       | 1
DELETE_RULE       | 1
FK_NAME           | FK__City__CountryId__38996AB5
PK_NAME           | PK__Country__10D1609FC8BFA7F2
DEFERRABILITY     | 7

I sp_fkeys la procedura memorizzata di sistema restituisce informazioni sulla nostra chiave esterna, la chiave primaria associata e altri dettagli rilevanti. Passi semplicemente il nome della tabella della chiave esterna o della tabella della chiave primaria e restituirà le informazioni pertinenti.

In questo esempio, passo il nome della tabella della chiave esterna:City . Nei risultati, possiamo guardare FK_NAME colonna per vedere che questa tabella ha un vincolo di chiave esterna chiamato FK__City__CountryId__38996AB5 . Questo è quello che abbiamo appena creato.

Quindi, ora che abbiamo creato la chiave esterna, ogni volta che tentiamo di inserire o aggiornare un valore in City.CountryId colonna, il vincolo di chiave esterna lo consentirà solo se lo stesso valore esiste già in Country.CountryId colonna. Ciò garantisce che l'integrità referenziale sia mantenuta all'interno del database.

Esempio 4 – Altre opzioni

È possibile aggiungere più opzioni alla definizione della chiave esterna.

Ad esempio, puoi fornire un nome per la chiave esterna. Puoi anche specificare cosa deve accadere ai valori in questa colonna se il valore corrispondente nella chiave primaria viene aggiornato o eliminato.

Qui creo di nuovo entrambe le tabelle, ma questa volta specifico esplicitamente queste opzioni (faccio lo stesso per le chiavi primarie):

CREATE TABLE Country
(
    CountryId int IDENTITY (1,1) NOT NULL,
      CONSTRAINT PK_Country_CountryId PRIMARY KEY CLUSTERED (CountryId),
    CountryName nvarchar(60)
);

CREATE TABLE City
(
    CityId int IDENTITY (1,1) NOT NULL,
      CONSTRAINT PK_City_CityId PRIMARY KEY CLUSTERED (CityId),
    CountryId int NOT NULL,
      CONSTRAINT FK_City_Country FOREIGN KEY (CountryID)
        REFERENCES Country (CountryID)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    CityName nvarchar(60)
);

In questo caso, la definizione della chiave esterna inizia con CONSTRAINT , seguito dal nome della chiave esterna, seguito da FOREIGN KEY , seguito dalla colonna a cui verrà applicato il vincolo di chiave esterna (inserita tra parentesi).

Quindi vediamo gli stessi REFERENCES clausola che abbiamo visto nell'esempio precedente.

Il ON DELETE CASCADE e ON UPDATE CASCADE le clausole vengono utilizzate per garantire che le modifiche apportate a Country vengono propagate automaticamente alla City tavolo. Ad esempio, se una riga viene eliminata dalla tabella padre (chiave primaria), tutte le righe corrispondenti vengono eliminate dalla tabella di riferimento (chiave esterna).

Il valore predefinito per ON DELETE e ON UPDATE è NO ACTION . In questo caso, Motore di database genera un errore e viene eseguito il rollback dell'azione di aggiornamento o eliminazione sulla riga nella tabella padre.

Puoi anche usare SET NULL per impostare la colonna della chiave esterna su NULL (richiede che la colonna della chiave esterna sia nullable) o SET DEFAULT per impostarlo sul valore predefinito (richiede che la colonna della chiave esterna abbia una definizione predefinita. Se una colonna è nullable e non è stato impostato alcun valore predefinito esplicito, NULL diventa il valore predefinito implicito della colonna).

In questo esempio ho anche colto l'occasione per nominare le chiavi primarie. Puoi vedere che la sintassi della chiave primaria è simile alla sintassi della chiave esterna, ma senza i REFERENCES clausola (e con aggiunta di CLUSTERED argomento, che è l'impostazione predefinita per le chiavi primarie).

Ora controlla la chiave esterna:

EXEC sp_fkeys @fktable_name = City;

Risultato:

PKTABLE_QUALIFIER | FK_Test
PKTABLE_OWNER     | dbo
PKTABLE_NAME      | Country
PKCOLUMN_NAME     | CountryId
FKTABLE_QUALIFIER | FK_Test
FKTABLE_OWNER     | dbo
FKTABLE_NAME      | City
FKCOLUMN_NAME     | CountryId
KEY_SEQ           | 1
UPDATE_RULE       | 0
DELETE_RULE       | 0
FK_NAME           | FK_City_Country
PK_NAME           | PK_Country_CountryId
DEFERRABILITY     | 7

Possiamo vedere che il nome della chiave esterna è ora FK_City_Country e il vincolo di chiave primaria della colonna a cui fa riferimento è chiamato PK_Country_CountryId .

Esempio 5 – Chiave esterna su più colonne

Puoi anche creare una chiave esterna su più colonne che faccia riferimento a una chiave primaria multicolonna. Le chiavi primarie multicolonna sono anche note come chiavi primarie composite. Per creare una chiave esterna composita, separa semplicemente le colonne con una virgola durante la definizione della chiave.

In questo modo:

CONSTRAINT FK_FKName FOREIGN KEY
 (FKColumn1, FKColumn2)
REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)

Vedere Come creare una chiave esterna composita in SQL Server per un esempio più dettagliato.

La chiave primaria è davvero necessaria?

Una chiave primaria non è assolutamente necessaria per le chiavi esterne, poiché potresti utilizzare un vincolo univoco o un indice univoco. In particolare, la documentazione Microsoft afferma questo:

FOREIGN KEY i vincoli possono fare riferimento solo alle colonne in PRIMARY KEY o UNIQUE vincoli nella tabella di riferimento o in un UNIQUE INDEX nella tabella di riferimento.

Quindi, sebbene sia generalmente buona norma avere chiavi primarie su tutte le tabelle, le tue chiavi esterne non sono obbligate a farvi riferimento.