zoukankan      html  css  js  c++  java
  • 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)并不受外键强制约束。

  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/11140645.html
Copyright © 2011-2022 走看看