Como faço para criar uma chave estrangeira composta para uma tabela com uma única chave primária? Por exemplo, suponha que eu tenha as seguintes tabelas:
CREATE TABLE Branches (
BranchId UniqueIdentifier DEFAULT NewSequentialID(),
CONSTRAINT pk_BranchId PRIMARY KEY (BranchId)
);
CREATE TABLE Expectations (
ExpectationId UniqueIdentifier DEFAULT NewSequentialID(),
BranchId UniqueIdentifier NOT NULL,
CONSTRAINT fk_Expectations_BranchId FOREIGN KEY (BranchId) REFERENCES Branches(BranchId),
CONSTRAINT pk_ExpectationId PRIMARY KEY (ExpectationId)
);
CREATE TABLE ClassSections (
ClassId UniqueIdentifier NOT NULL,
BranchId UniqueIdentifier NOT NULL,
CONSTRAINT fk_ClassSections_ClassId FOREIGN KEY (ClassId) REFERENCES Classes(ClassId),
CONSTRAINT fk_ClassSections_BranchId FOREIGN KEY (BranchId) REFERENCES Branches(BranchId),
CONSTRAINT pk_ClassSections PRIMARY KEY (ClassID, BranchId)
);
CREATE TABLE ClassExpectations (
ClassId UniqueIdentifier NOT NULL,
BranchId UniqueIdentifier NOT NULL,
ExpectationId UniqueIdentifier NOT NULL,
CONSTRAINT fk_ClassExpectations_ClassId FOREIGN KEY (ClassId) REFERENCES Classes(ClassId),
CONSTRAINT fk_ClassExpectations_BranchId FOREIGN KEY (BranchId) REFERENCES Branches(BranchId),
CONSTRAINT fk_ClassExpectations_ExpectationId FOREIGN KEY (ExpectationId) REFERENCES Expectations(ExpectationId),
CONSTRAINT fk_ClassExpectations_ExpectationIdBranchId FOREIGN KEY (ExpectationId, BranchId) REFERENCES Expectations(ExpectationId, BranchId),
CONSTRAINT pk_ClassDueDates PRIMARY KEY (ClassId, ExpectationId)
);
Estou tentando adicionar a seguinte restrição, mas não permite:
ALTER TABLE ClassExpectations ADD CONSTRAINT fk_ClassExpectations_ExpectationIdBranchId FOREIGN KEY (ExpectationId, BranchId) REFERENCES Expectations(ExpectationId, BranchId);
Continuo recebendo o erro:
Não há chaves primárias ou candidatas na tabela referenciada 'Expectations' que correspondam à lista de colunas de referência na chave estrangeira
De que outra forma posso garantir que um ExpectationId nunca seja adicionado a ClassExpectations sem seu BranchId correspondente (da tabela Expectations)?
A resposta é um pouco como a velha piada: "Doutor, doutor! Dói quando faço isso ."
Se você deseja uma chave estrangeira para uma entidade, essa entidade precisa ter uma chave exclusiva definida para ser referenciada.
O fato de sua
Expectations
tabela ter uma chave candidata exclusivaExpectations.ExpectationId
não deve impedir que você defina outra chave candidata que combine ExpectationId e BranchId. Isso parece uma violação da terceira forma normal e, tecnicamente, é. No entanto, isso só é verdade porque você define ExpectationId como exclusivo. Você poderia ter definido ExpectationId como uma sequência dentro de BranchId, de forma que ExpectationId não seja exclusivo por conta própria. Assim, você pode pensar nela como aExpectation
tabela que define a combinação de dois valores únicos como sendo o fato de interesse.De qualquer forma, se você quiser definir uma chave estrangeira para
Expectation
isso, é a combinação deExpectationId
e , emBranchId
seguida, não há como contornar isso, a não ser definir a chave primária dessa maneira.