在外键列中设置空值?

时间:2012-09-19 13:02:55

标签: sql-server foreign-keys relational-database constraints relationship

我有这张桌子

CREATE TABLE [dbo].[CityMaster](
    [CityID] [int] NOT NULL,
    [City] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [BranchId] [varchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT [DF__CityM__Branc__74444068]  DEFAULT ((0)),
    [ExternalBranchId] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
 CONSTRAINT [PK_CityMaster] PRIMARY KEY CLUSTERED 
(
    [City] ASC,
    [BranchId] ASC
),
 CONSTRAINT [uk_citymaster_cityid_branchid] UNIQUE NONCLUSTERED 
(
    [CityID] ASC,
    [BranchId] ASC
)
)

和另一张表

CREATE TABLE [dbo].[CustomerMaster](
    [ID] [int] NOT NULL,
    [CustomerCode] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [CustomerName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [CustomerAddress] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [CustomerPhone] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [CustomerEmailId] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [CustomerPriority] [int] NOT NULL CONSTRAINT [DF_CustomerMaster_CustomerPriority]  DEFAULT ((0)),
    [CustomerRegisterDate] [datetime] NULL,
    [CustomerIsActive] [bit] NULL CONSTRAINT [DF_CustomerMaster_CustomerIsActive]  DEFAULT ((1)),
    [BranchId] [varchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT [DF__CustomerM__Branc__67DE6983]  DEFAULT ((0)),
    [CityId] [int] NULL CONSTRAINT [DF_CustomerMaster_CityId]  DEFAULT ((0)),
 CONSTRAINT [PK_CustomerMaster] PRIMARY KEY CLUSTERED 
(
    [CustomerCode] ASC,
    [BranchId] ASC
)
) ON [PRIMARY]

ALTER TABLE [dbo].[CustomerMaster]  WITH CHECK ADD  CONSTRAINT [fk_cdCityId_CityId] FOREIGN KEY([CityId], [BranchId])
REFERENCES [dbo].[CityMaster] ([CityID], [BranchId])

ALTER TABLE [dbo].[CustomerMaster] CHECK CONSTRAINT [fk_cdCityId_CityId]

如您所见,CityId, BranchId上有一个外键。我遇到的问题是,如果用户没有进入他的城市(他可以选择不这个,这个字段不是强制性的,那么CityId将是空白的,当我尝试在{{{ 1}}表,我得到这个错误说

INSERT语句与FOREIGN KEY约束“fk_cdCityId_CityId”冲突。冲突发生在数据库“TestDatabase”,表“dbo.CityMaster”中。 声明已经终止。

所以,我想知道一种绕过这个的方法。我知道如果将唯一或主键列引用为外键,则它不能为空。但是,当我设定时,时代呢? CustomerMaster?在这种情况下,如果该行从on delete set null中删除,则会在CityMaster中设置为null(我的意思是所有引用)。那么,如果可能的话,为什么以及如何手动设置此外键CustomerMaster中的值? 如果这无法通过任何方式实现,那么绕过我描述的情况的最佳方法是什么?

2 个答案:

答案 0 :(得分:18)

如果CityId设置为NULL,则不会检查外键约束,一切都会好。

另一方面,如果CityId为0(例如,因为您已在其上指定了DEFAULT ((0)) ...),CityMaster0,BranchId没有匹配的行1}},这确实会导致约束检查失败。

仅当所涉及的列的所有 NULL时,才会检查复合键上的外键约束。

答案 1 :(得分:3)

insert query @

的变化
[CityId] [int] DEFAULT NULL

这将允许您在声明为默认值时存储Null值。