SQL FOREIGN KEY 約束
一個表中的 FOREIGN KEY 指向另一個表中的 UNIQUE KEY(唯一約束的鍵)。
讓我們通過一個實例來解釋外鍵。請看下面兩個表:
“Persons” 表:
P_Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Hansen | Ola | Timoteivn 10 | Sandnes |
2 | Svendson | Tove | Borgvn 23 | Sandnes |
3 | Pettersen | Kari | Storgt 20 | Stavanger |
“Orders” 表:
O_Id | OrderNo | P_Id |
---|---|---|
1 | 77895 | 3 |
2 | 44678 | 3 |
3 | 22456 | 2 |
4 | 24562 | 1 |
請注意,“Orders” 表中的 “P_Id” 列指向 “Persons” 表中的 “P_Id” 列。
“Persons” 表中的 “P_Id” 列是 “Persons” 表中的 PRIMARY KEY。
“Orders” 表中的 “P_Id” 列是 “Orders” 表中的 FOREIGN KEY。
FOREIGN KEY 約束用於預防破壞表之間連接的行為。
FOREIGN KEY 約束也能防止非法數據插入外鍵列,因為它必須是它指向的那個表中的值之一。
CREATE TABLE 時的 SQL FOREIGN KEY 約束
下面的 SQL 在 “Orders” 表創建時在 “P_Id” 列上創建 FOREIGN KEY 約束:
MySQL:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
)
SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
P_Id int FOREIGN KEY REFERENCES Persons(P_Id)
)
如需命名 FOREIGN KEY 約束,並定義多個列的 FOREIGN KEY 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
ALTER TABLE 時的 SQL FOREIGN KEY 約束
當 “Orders” 表已被創建時,如需在 “P_Id” 列創建 FOREIGN KEY 約束,請使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
如需命名 FOREIGN KEY 約束,並定義多個列的 FOREIGN KEY 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
撤銷 FOREIGN KEY 約束
如需撤銷 FOREIGN KEY 約束,請使用下面的 SQL:
MySQL:
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders
SQL Server / Oracle / MS Access:
ALTER TABLE Orders
DROP CONSTRAINT fk_PerOrders
禁用、啟用外鍵約束
作用
當我們表已經設置了外鍵關聯的時候,想要刪除或者表中的數據會造成錯誤,或者要多次修改,很麻煩。我們可以暫時禁用外鍵約束來規避掉這種問題。
SQLServer禁用、啟用外鍵約束
---啟用or禁用指定表所有外鍵約束
alter table PUB_STRU NOCHECK constraint all;
alter table PUB_STRU CHECK constraint all;
---生成啟用or禁用指定表外鍵約束的sql
select 'ALTER TABLE ' + b.name + ' NOCHECK CONSTRAINT ' + a.name +';' from sysobjects a ,sysobjects b where a.xtype ='f' and a.parent_obj = b.id and b.name='表名';
select 'ALTER TABLE ' + b.name + ' CHECK CONSTRAINT ' + a.name +';' from sysobjects a ,sysobjects b where a.xtype ='f' and a.parent_obj = b.id and b.name='表名';
--生成的sql如下
ALTER TABLE PUB_STRU NOCHECK CONSTRAINT PUBSTRU_FK1;
ALTER TABLE PUB_STRU NOCHECK CONSTRAINT PUBSTRU_FK2;
ALTER TABLE PUB_STRU CHECK CONSTRAINT PUBSTRU_FK1;
ALTER TABLE PUB_STRU CHECK CONSTRAINT PUBSTRU_FK2;
--查看約束狀態(查詢字典表 sys.foreign_keys,該字典表開始出現於sqlserver2005及以上版本):
select name , is_disabled from sys.foreign_keys order by name;
--其中:name : 外鍵約束名稱 is_disabled : 是否已禁用
例子
--刪除外鍵
alter table AdItem drop constraint AdOrder_AdItem_FK1
--增加外鍵
alter table AdItem
add constraint AdOrder_AdItem_FK1 foreign key (AI_nOrderNo) references AdOrder(AO_nOrderNo)
--單個表的一個外鍵
alter table Student nocheck constraint FK__Student__SchoolN__4222D4EF
alter table Student check constraint FK__Student__SchoolN__4222D4EF
--單個表的所有外鍵
alter table Student nocheck constraint all
alter table Student check constraint all
--某個數據庫的所有表
EXEC sp_MSforeachtable @command1='alter table ? NOCHECK constraint all; EXEC sp_MSforeachtable @command1='alter table ? CHECK constraint all;
MySQL 啟動和禁用外鍵約束
我們可以使用
SET FOREIGN_KEY_CHECKS=0;
來禁用外鍵約束.
之后再用
SET FOREIGN_KEY_CHECKS=1;
來啟動外鍵約束.
來啟動外鍵約束.
查看當前FOREIGN_KEY_CHECKS的值可用如下命令
SELECT @@FOREIGN_KEY_CHECKS;