2014-02-16 79 views
1

我有以下兩個數據庫表中定義:錯誤定義外鍵

CREATE TABLE [dbo].[Classrooms] (
    [ID]    INT   IDENTITY (1, 1) NOT NULL, 
    [SystemAccount_ID] INT   NOT NULL, 
    [ClassroomName] VARCHAR (30) NOT NULL, 
    CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED ([ID]), 
    CONSTRAINT [FK_Classrooms_SystemAccount] FOREIGN KEY ([SystemAccount_ID]) REFERENCES [dbo].[SystemAccounts] ([ID]) 
); 

CREATE TABLE [dbo].[Students] (
    [ID]    INT   IDENTITY (1, 1) NOT NULL, 
    [SystemAccount_ID] INT   NOT NULL, 
    [Classroom_ID]  INT   NULL, 
    [PhotoID]   INT   NULL, 
    [FirstName]  VARCHAR (20) NOT NULL, 
    [LastName]   VARCHAR (40) NOT NULL, 
    [NewsTemplate]  TINYINT  NOT NULL, 
    CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED ([ID] ASC), 
    CONSTRAINT [FK_Students_Classrooms] FOREIGN KEY ([Classroom_ID]) REFERENCES [dbo].[Classrooms] ([ID]), 
    CONSTRAINT [FK_Students_SystemAccounts] FOREIGN KEY ([SystemAccount_ID]) REFERENCES [dbo].[SystemAccounts] ([ID]) 
); 

數據模型的細節:

  • 學生通過Classroom_ID屬於零或一個教室FK
  • 學生屬於一個系統帳戶通過SystemAccount_ID FK
  • 教室屬於一個系統帳戶通過SystemAccount_ID FK(暗示系統交流計數可以有零個或多個教室)

什麼我試圖做的是當學生們被添加到一個教室強制執行(通過設置在學生表中的Classroom_ID鍵)的教室屬於同一系統帳戶作爲學生。我可以很容易地在業務邏輯層強制執行此操作,但是我會要求每個程序員都要記住這樣做。所以理想情況下,我可以在數據層做到這一點作爲一個約束。

我嘗試添加一個FK約束學生表:

CONSTRAINT [FK_Students_ToTable] FOREIGN KEY ([SystemAccount_ID]) REFERENCES [Classrooms]([SystemAccount_ID]) 

導致的SQL Server以下錯誤稱讚:

更新無法繼續,由於驗證錯誤。
請更正以下錯誤並重試。

SQL71516 ::引用表'[dbo]。[Classrooms]'不包含與外鍵中的引用列表匹配的主鍵或候選鍵。如果被引用的列是一個計算列,它應該被保留。

我已經嘗試了幾個不同的東西,但我的SQL mojo功能不足以破解這一個。任何幫助將不勝感激。

+0

上Classrooms.SystemAccount_ID添加唯一鍵'ALTER TABLE教室 ADD CONSTRAINT constraintName UNIQUE(SystemAccount_ID)' – Mihai

+1

您正在嘗試創建一個引用'CLassrooms'中'SystemAccount_ID'列的FK,但是**既不是該表的主鍵,也沒有唯一約束在那一欄。這兩個條件中的一個**必須被**給該列以被外鍵約束引用!或者你想引用'Classrooms.ID'列嗎? –

+1

@Mhaihai我忽略的一個細節是系統賬戶可以有零個或更多的教室。我假設你建議的獨特約束會阻止我將多個教室分配到同一個系統帳戶。 – BitsEvolved

回答

1

在兩列的組合添加UNIQUE約束在Classrooms

CREATE TABLE [dbo].[Classrooms] (
    [ID]    INT   IDENTITY (1, 1) NOT NULL, 
    [SystemAccount_ID] INT   NOT NULL, 
    [ClassroomName] VARCHAR (30) NOT NULL, 
    CONSTRAINT [PK_Table] 
    PRIMARY KEY CLUSTERED ([ID]), 
    CONSTRAINT [FK_Classrooms_SystemAccount] 
    FOREIGN KEY ([SystemAccount_ID]) 
    REFERENCES [dbo].[SystemAccounts] ([ID]), 
    CONSTRAINT [UQ_Classrooms_ID_SystemAccount_ID] 
    UNIQUE ([SystemAccount_ID], [ID]) 
); 

然後,在Students表,將兩者結合起來FOREIGN KEY約束爲一體,或在你的情況(因爲Classroom_ID ISNULLABLE)改變FK到Classroom使用兩列組合:

CREATE TABLE [dbo].[Students] (
    [ID]    INT   IDENTITY (1, 1) NOT NULL, 
    [SystemAccount_ID] INT   NOT NULL, 
    [Classroom_ID]  INT   NULL, 
    [PhotoID]   INT   NULL, 
    [FirstName]  VARCHAR (20) NOT NULL, 
    [LastName]   VARCHAR (40) NOT NULL, 
    [NewsTemplate]  TINYINT  NOT NULL, 
    CONSTRAINT [PK_Students] 
    PRIMARY KEY CLUSTERED ([ID] ASC), 
    CONSTRAINT [FK_Students_Classrooms] 
    FOREIGN KEY ([SystemAccount_ID], [Classroom_ID]) 
    REFERENCES [dbo].[Classrooms] ([SystemAccount_ID], [ID]), 
    CONSTRAINT [FK_Students_SystemAccounts]   -- this wouldn't be needed if 
    FOREIGN KEY ([SystemAccount_ID])    -- Classrooms_ID was NOT NULL 
    REFERENCES [dbo].[SystemAccounts] ([ID]) 
); 
+0

一旦我有機會回到它,我會嘗試接受這個答案。感謝您花時間幫助我。我很感激。 – BitsEvolved