2015-09-18 70 views
0

我正在创建一个项目的数据库,我需要为另一个外键声明一个外键,以便检查约束。外键上的外键 - SQL Server

我有一个Person表和Groups表,这两个表都包含一个DepartmentID。每当我在Task表中插入新任务时,我想检查Groups.DepartmentID是否与Person.DepartmentID匹配。

这个想法是任务链接到一个人,并且有两种类型,一个组合类型,它定义了它的数据库工作,财务工作等等,以及定义它的维护,培训等的任务类型。当一个人试图添加具有不适合他/她部门的groupType的任务应该失败。

我试图将这些属性添加到Task表作为一个外键,但声明对非唯一的或者非主键的外键是不是在Microsoft SQL Server(该DepartmentIDPersonGroup表接受不能是唯一的!)。

任何人都知道如何解决这个问题?

CREATE TABLE Department 
(
    ID int PRIMARY KEY IDENTITY, 
    Name varchar(50), 
    UNIQUE ("Name") 
) 

CREATE TABLE Groups 
(
    ID int IDENTITY, 
    GroupType varchar(50) PRIMARY KEY, 
    Description varchar(255) DEFAULT ('-'), 
    DepartmentID int 
     FOREIGN KEY (DepartmentID) REFERENCES Department(ID), 
) 

CREATE TABLE Person 
(
    ID int PRIMARY KEY IDENTITY, 
    Name varchar(50), 
    DepartmentID int 
     FOREIGN KEY (DepartmentID) REFERENCES Department(ID) 
) 

CREATE TABLE TaskType 
(
    ID int IDENTITY, 
    TaskType varchar(50) PRIMARY KEY, 
    Description varchar(255) DEFAULT ('-'), 
) 

CREATE TABLE Task 
(
    ID int IDENTITY, 
    TimeFrame decimal(4,2), 
    Yearcount int, 
    GroupType varchar(50), 
    TaskType varchar(50), 
    WeekNr int, 
    ExceptionDetail varchar(255) DEFAULT ('-'), 
    PersonID int 
) 

这些是FK在未接受了任务表的属性:

GDID int FOREIGN KEY REFERENCES Groups(DepartmentID), 
PDID int FOREIGN KEY REFERENCES Person(DepartmentID), 
CHECK (GDID = PDID),  

UNIQUE ("TaskType", "GroupType", "WeekNr", "Yearcount"), 
FOREIGN KEY (TaskType) REFERENCES TaskType(TaskType), 
FOREIGN KEY (PersonID) REFERENCES Person(ID), 
FOREIGN KEY (GroupType) REFERENCES Groups(GroupType) 
+0

先生,您需要在其他表中使用主键/唯一键。你为什么想这样试试? 'Foreignkey数据应该在主表中唯一可用' –

+0

哪些外键被sql拒绝?请张贴失败的陈述。 – Paolo

+0

这些:GDID INT FOREIGN KEY REFERENCES组(DepartmentID), PDID INT FOREIGN KEY REFERENCES人(DepartmentID), – Alim

回答

1

添加更宽“超级键”,以这些表包括主键附加列 ,然后使用它们声明外键。无论您还删除多余的小外键是一个品味的问题:

CREATE TABLE Groups(
ID int IDENTITY, 
GroupType varchar(50) PRIMARY KEY, 
Description varchar(255) DEFAULT ('-'), 
DepartmentID int FOREIGN KEY (DepartmentID) REFERENCES Department(ID), 
constraint Group_Dep_XRef UNIQUE (GroupType,DepartmentID) 
) 

CREATE TABLE Person(
ID int PRIMARY KEY IDENTITY, 
Name varchar(50), 
DepartmentID int FOREIGN KEY (DepartmentID) REFERENCES Department(ID), 
constraint Person_Dept_XRef UNIQUE (ID,DepartmentID) 
) 

CREATE TABLE Task(
ID int IDENTITY, 
TimeFrame decimal(4,2), 
Yearcount int, 
GroupType varchar(50), 
TaskType varchar(50), 
WeekNr int, 
ExceptionDetail varchar(255) DEFAULT ('-'), 
PersonID int, 
DepartmentID int, 
constraint FK_Group_Dept_XRef FOREIGN KEY (GroupType,DepartmentID) 
     references Group (GroupType,DepartmentID), 
constraint FK_Person_Dept_XRef FOREIGN KEY (PersonID,DepartmentID) 
     references Person (ID,DepartmentID), 
UNIQUE ("TaskType", "GroupType", "WeekNr", "Yearcount"), 
FOREIGN KEY (TaskType) REFERENCES TaskType(TaskType), 
FOREIGN KEY (PersonID) REFERENCES Person(ID), --Redundant now 
FOREIGN KEY (GroupType) REFERENCES Groups(GroupType) --Also redundant 
) 

(我也巩固GDIDPDIDDepartmentID - 如果他们总是意味着要平等,为什么商店,两次,然后必须有另一个约束维护自己的平等?)


如果主键(或唯一键)足以唯一地识别每个行则任何更宽的键,其中包括的键列其他列也必须足以唯一标识每行。

+0

谢谢! – Alim