10

mam tej tabeliustawić wartość pustą w kolumnie klucza obcego?

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 
) 
) 

i inną tabelę

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] 

Jak widać, istnieje klucz obcy na CityId, BranchId. Problem polega na tym, że jeśli użytkownik nie wejdzie do swojego miasta (może zrezygnować, to pole nie jest obowiązkowe, wtedy CityId będzie puste i gdy spróbuję wstawić tę wartość do tabeli CustomerMaster, otrzymam to błąd mówiąc

Instrukcja INSERT konflikt z ograniczeniem FOREIGN KEY "fk_cdCityId_CityId". konflikt wystąpiło w bazie danych "TestDatabase", tabela "dbo.CityMaster". oświadczenie zostało zakończone.

Więc, Chcę wiedzieć sposób obejścia tego. Wiem, jeśli kolumna klucza unikatowy lub podstawowy jest określany jako klucz obcy, nie może być wartością null.Ale co z razy, gdy ustawiam on delete set null? W takim przypadku, jeśli ten wiersz zostanie usunięty z CityMaster, zostanie ustawiony na null w CustomerMaster (mam na myśli wszystkie jego odniesienia). więc, jeśli to możliwe, dlaczego i jak mogę ręcznie ustawić wartość tego klucza obcego null? A jeśli nie jest to możliwe w jakikolwiek sposób, jaki jest najlepszy sposób na obejście sytuacji, którą opisałem?

Odpowiedz

17

Jeśli CityId jest ustawione na NULL, ograniczenie klucza obcego nie będzie sprawdzane, a wszystkie będą dobre.

Z drugiej strony, jeśli CityId jest 0 (powiedzmy, bo masz określony DEFAULT ((0)) na nim ...), a nie ma w CityMaster wiersz pasujący do 0,BranchId, to będzie rzeczywiście powodować ograniczenia CHECK na niepowodzenie.

Ograniczenie klucza obcego na kluczu złożonym jest sprawdzane tylko pod warunkiem, że wszystkie z kolumny są nie-NULL.

+0

@ damien-the-unbeliever: Tak, powinienem usunąć tę 'domyślną (0)' klauzulę? – Razort4x

+1

@ Razort4x - Powiedziałbym tak, tak. –

+0

Dobrze, to mi nie pomogło –

3

Zmiana insert query @

[CityId] [int] DEFAULT NULL 

pozwoli na przechowywanie Null wartość jak ogłosił ją jako domyślną.

Powiązane problemy