この記事では、Transact-SQLを使用してSQLServerで外部キーを作成する方法を示します。 (既存のテーブルを更新するのではなく)テーブルの作成時に外部キーを作成する方法を示します。
外部キーは、別のテーブルの主キー列を参照する列です。これにより、テーブル間に関係が作成されます。
例1-準備
この例では、1つのテーブルを使用してテストデータベースを作成します。このテーブルには、外部キーが参照する主キーが含まれます。
データベースを作成します:
CREATE DATABASE FK_Test;
次に、主キーテーブルを作成します。
USE FK_Test; CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60) );
例2–外部キーを作成する
主キーを持つテーブルができたので、その主キーを参照する外部キーを持つ別のテーブルを作成しましょう。
CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCES Country(CountryId), CityName nvarchar(60) );
これは、外部キーを作成する最も簡単な方法です。 REFERENCES
を追加するだけです 外部キー制約を持つ列への(主キーテーブルと列とともに)句。
明確にするために、外部キーを定義する部分は次のとおりです。
REFERENCES Country(CountryId)
これは列定義に含まれており、この列がCountryId
を参照することを単に示しています Country
の列 テーブル。
この場合、外部キーとそれが参照する主キーの両方が同じ名前(CountryId
)を共有します。 )。ただし、これは必須ではありません。外部キー列は、それが参照する列とは完全に異なる名前を持つことができます(ただし、外部キー関係に参加するすべての列は、同じ長さとスケールで定義する必要があります)。
この例では、SQLServerが外部キーの名前を自動的に生成します。名前を付けなかったからです。外部キーの名前を作成する方法を確認するために読んでください。
ただし、最初に、作成した外部キー制約を確認しましょう。
例3–外部キー制約を確認する
T-SQLを使用して外部キーを返す方法はたくさんありますが、そのうちの1つを次に示します。
EXEC sp_fkeys @fktable_name = City;
結果(垂直出力を使用):
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
sp_fkeys
システムストアドプロシージャは、外部キー、それに関連付けられた主キー、およびその他の関連する詳細に関する情報を返します。外部キーテーブルまたは主キーテーブルの名前を渡すだけで、関連する情報が返されます。
この例では、外部キーテーブルの名前(City
)を渡します。 。結果では、
FK_NAME
を見ることができます。 このテーブルに
FK__City__CountryId__38996AB5
という外部キー制約があることを確認する列 。これは私たちが作成したものです。
これで、City.CountryId
に値を挿入または更新しようとするたびに、外部キーが作成されました。 列の場合、外部キー制約は、同じ値がCountry.CountryId
にすでに存在する場合にのみ許可されます。 桁。これにより、データベース内で参照整合性が維持されます。
例4–その他のオプション
外部キー定義にさらにオプションを追加することが可能です。
たとえば、外部キーの名前を指定できます。主キーの対応する値が更新または削除された場合に、この列の値がどうなるかを指定することもできます。
ここでは、両方のテーブルを再度作成しますが、今回はこれらのオプションを明示的に指定します(主キーについても同じことを行います):
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) );
この場合、外部キー定義はCONSTRAINT
で始まります 、続いて外部キーの名前、続いてFOREIGN KEY
、その後に外部キー制約が適用される列が続きます(括弧内に挿入)。
次に、同じREFERENCES
が表示されます。 前の例で見た句。
ON DELETE CASCADE
およびON UPDATE CASCADE
句は、Country
に加えられた変更を確実にするために使用されます テーブルは自動的にCity
に伝播されます テーブル。たとえば、親(主キー)テーブルから行が削除されると、対応する行はすべて参照(外部キー)テーブルから削除されます。
ON DELETE
のデフォルト値 およびON UPDATE
NO ACTION
です 。この場合、データベースエンジンはエラーを発生させ、親テーブルの行に対する更新または削除アクションがロールバックされます。
SET NULL
を使用することもできます 外部キー列をNULL
に設定します (外部キー列がnull許容である必要があります)、またはSET DEFAULT
デフォルト値に設定するには(外部キー列にデフォルト定義が必要です。列がNULL可能であり、明示的なデフォルト値が設定されていない場合は、NULL
列の暗黙のデフォルト値になります。
この例では、主キーに名前を付ける機会もありました。主キーの構文は外部キーの構文に似ていますが、REFERENCES
がないことがわかります。 句(および追加されたCLUSTERED
引数。これは主キーのデフォルトです。
次に、外部キーを確認します:
EXEC sp_fkeys @fktable_name = City;
結果:
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
外部キーの名前が FK_City_Country になっていることがわかります 参照する列の主キー制約は、 PK_Country_CountryId と呼ばれます。 。
例5–複数の列の外部キー
複数列の主キーを参照する複数の列に外部キーを作成することもできます。複数列の主キーは、複合主キーとも呼ばれます。複合外部キーを作成するには、キーを定義するときに列をコンマで区切るだけです。
このように:
CONSTRAINT FK_FKName FOREIGN KEY (FKColumn1, FKColumn2) REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)
詳細な例については、SQLServerで複合外部キーを作成する方法を参照してください。
主キーは本当に必要ですか?
一意の制約または一意のインデックスを使用できるため、外部キーに主キーが絶対に必要なわけではありません。具体的には、Microsoftのドキュメントには次のように記載されています。
FOREIGN KEY
制約は、PRIMARY KEY
の列のみを参照できます またはUNIQUE
参照されるテーブルまたはUNIQUE INDEX
の制約 参照されたテーブル上。
したがって、通常はすべてのテーブルに主キーを設定することをお勧めしますが、外部キーはそれらを参照する必要はありません。