2014-02-16 92 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