SQL Server外鍵關系是強制約束,外鍵值也可以是空(NULL)


在SQL Server中,實際上外鍵值可不可以為空(NULL),和外鍵關系是不是強制約束無關。

 

我們先在SQL Server數據庫中建立兩張表People和Car,一個People可以有多個Car,所以這兩張表是一對多關系。

 

 

建立表

People建表語句:

CREATE TABLE [dbo].[People](
    [ID] [int] NOT NULL,
    [Name] [nvarchar](50) NULL,
    [Age] [int] NULL,
    [Sex] [nvarchar](50) NULL,
 CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

其中列ID是People表的主鍵

 

Car建表語句:

CREATE TABLE [dbo].[Car](
    [ID] [int] NOT NULL,
    [Brand] [nvarchar](50) NULL,
    [PeopleID] [int] NULL,
 CONSTRAINT [PK_Car] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Car]  WITH CHECK ADD  CONSTRAINT [FK_Car_People] FOREIGN KEY([PeopleID])
REFERENCES [dbo].[People] ([ID])
GO

ALTER TABLE [dbo].[Car] CHECK CONSTRAINT [FK_Car_People]
GO

其中列ID是Car表的主鍵,此外列PeopleID是Car表的外鍵,其關聯People表的主鍵ID。我們還為People表和Car表之間的外鍵關系[FK_Car_People]設置了強制約束(CHECK)。

注意上面外鍵約束[FK_Car_People]中CHECK關鍵字代表是強制約束,而如果使用NOCHECK關鍵字代表是非強制約束。

 

 

外鍵關系語法擴展

建立外鍵關系[FK_Car_People]為強制約束(CHECK的SQL語句如下:

--下面CHECK關鍵字表示建立外鍵關系時就開啟強制約束
ALTER TABLE [dbo].[Car]  WITH CHECK ADD  CONSTRAINT [FK_Car_People] FOREIGN KEY([PeopleID])
REFERENCES [dbo].[People] ([ID])
GO

--注意上面建立外鍵關系[FK_Car_People]后,下面這句ALTER TABLE語句也不能少
ALTER TABLE [dbo].[Car] CHECK CONSTRAINT [FK_Car_People]
GO

 

建立外鍵關系[FK_Car_People]為非強制約束(NOCHECK)的SQL語句如下:

--下面NOCHECK關鍵字表示建立外鍵關系時不開啟強制約束,也就是非強制約束
ALTER TABLE [dbo].[Car]  WITH NOCHECK ADD  CONSTRAINT [FK_Car_People] FOREIGN KEY([PeopleID])
REFERENCES [dbo].[People] ([ID])
GO

--注意上面建立外鍵關系[FK_Car_People]后,下面這句ALTER TABLE語句也不能少
ALTER TABLE [dbo].[Car] NOCHECK CONSTRAINT [FK_Car_People]
GO

 

上面建立好外鍵關系[FK_Car_People]后,可以通過下面的語句再將外鍵關系[FK_Car_People]改為強制(CHECK)或非強制(NOCHECK)約束,其實就是刪除外鍵關系[FK_Car_People]后再重建:

更改外鍵關系[FK_Car_People]為強制約束(CHECK)的SQL語句如下:

--刪除外鍵關系[FK_Car_People]
ALTER TABLE [dbo].[Car] DROP CONSTRAINT [FK_Car_People]

--下面CHECK關鍵字表示建立外鍵關系時就開啟強制約束
ALTER TABLE [dbo].[Car]  WITH CHECK ADD  CONSTRAINT [FK_Car_People] FOREIGN KEY([PeopleID])
REFERENCES [dbo].[People] ([ID])
GO

--注意上面建立外鍵關系[FK_Car_People]后,下面這句ALTER TABLE語句也不能少
ALTER TABLE [dbo].[Car] CHECK CONSTRAINT [FK_Car_People]
GO

更改外鍵關系[FK_Car_People]為非強制約束(NOCHECK)的SQL語句如下:

--刪除外鍵關系[FK_Car_People]
ALTER TABLE [dbo].[Car] DROP CONSTRAINT [FK_Car_People]

--下面NOCHECK關鍵字表示建立外鍵關系時不開啟強制約束,也就是非強制約束
ALTER TABLE [dbo].[Car]  WITH NOCHECK ADD  CONSTRAINT [FK_Car_People] FOREIGN KEY([PeopleID])
REFERENCES [dbo].[People] ([ID])
GO

--注意上面建立外鍵關系[FK_Car_People]后,下面這句ALTER TABLE語句也不能少
ALTER TABLE [dbo].[Car] NOCHECK CONSTRAINT [FK_Car_People]
GO

 

在本例中,外鍵關系[FK_Car_People]應該是強制約束(CHECK的,所以下面我們來為People表和Car表插入數據。

 

 

插入數據

下面我們為People表插入兩條數據:

INSERT INTO [dbo].[People](ID,Name,Age,Sex)
VALUES
(1,N'張三',25,N''),
(2,N'李四',26,N'');

查詢結果如下:

 

然后我們為Car表插入五條數據:

INSERT INTO [dbo].[Car](ID,Brand,PeopleID)
VALUES
(1,N'奔馳',1),
(2,N'寶馬',1),
(3,N'大眾',2),
(4,N'別克',NULL),
(5,N'豐田',NULL);

注意我們在最后兩條數據"別克"和"豐田"中,插入了空值(NULL)到Car表的外鍵列PeopleID。但是語句並沒有報錯,五條數據都被成功插入了,查詢結果如下:

 

所以Car表的外鍵列PeopleID能不能為空(NULL),和其外鍵關系[FK_Car_People]是不是強制約束(CHECK)無關,它只和Car表允不允許外鍵列PeopleID為空(NULL)相關。

現在我們把Car表的外鍵列PeopleID改為不允許為空(NULL),然后再次插入前面的五條數據:

DELETE FROM [dbo].[Car]

ALTER TABLE [dbo].[Car]
ALTER COLUMN [PeopleID] INT NOT NULL

INSERT INTO [dbo].[Car](ID,Brand,PeopleID)
VALUES
(1,N'奔馳',1),
(2,N'寶馬',1),
(3,N'大眾',2),
(4,N'別克',NULL),
(5,N'豐田',NULL);

這時插入語句就會報錯了,因為此時Car表的外鍵列PeopleID不能為空(NULL):

 

所以SQL Server中的外鍵關系強制約束,約束的實際上是外鍵的非空值,而外鍵的空值(NULL)並不受外鍵強制約束。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM