Установить значение null в столбце внешнего ключа?

У меня есть эта таблица

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 будет пустым и когда я попытаюсь вставить это значение в таблицу CustomerMaster, Я получаю эту ошибку, говоря

Оператор INSERT противоречил ограничениям FOREIGN KEY "fk_cdCityId_CityId". Конфликт произошел в базе данных "TestDatabase", в таблице "dbo.CityMaster". Заявление завершено.

Итак, я хочу знать, как обойти это. Я знаю, что если уникальный или первичный ключевой столбец ссылается как внешний ключ, он не может быть нулевым. Но как насчет времени, когда я установил on delete set null? В этом случае, если эта строка удалена из CityMaster, она будет установлена ​​в null в CustomerMaster (я имею в виду все ее ссылки). поэтому, если это возможно, почему и как я могу установить значение в этом внешнем ключе null вручную? И если это невозможно каким-либо образом, то какой лучший способ обойти ситуацию, которую я описал?

Ответ 1

Если CityId установлено на NULL, тогда ограничение внешнего ключа не будет проверяться, и все будет хорошо.

С другой стороны, если CityId равно 0 (скажем, потому что вы указали DEFAULT ((0)) на нем...), и нет соответствующей строки в CityMaster для 0,BranchId, тогда это действительно чтобы проверка ограничения завершилась с ошибкой.

Ограничение внешнего ключа для составного ключа проверяется только, если все задействованные столбцы не являются NULL.

Ответ 2

Изменить insert query @

[CityId] [int] DEFAULT NULL

Это позволит вам сохранить значение Null, поскольку оно было объявлено по умолчанию.