引用表'PayRoll'中没有主键或候选键与外键'fk_EmployeeNumber'中的引用列列表匹配

时间:2014-01-14 04:01:20

标签: sql sql-server

我在使用名为HoursandEarnings的表格时遇到了一些问题,我一直收到错误消息,

  

“引用的表中没有主键或候选键   'PayRoll'与外键中的引用列列表匹配   'fk_EmployeeNumber'“

create table Address
(
PostalCode nvarchar(6) not null,
Address nvarchar(50) not null,
City nvarchar(30) not null,
Province nvarchar(30) not null,
constraint pk_postalcode primary key(PostalCode)
)

create table Payperiod
(
StartDate DateTime not null,
EndDate DateTime not null,
constraint pk_StartDate primary key(StartDate)
)


create table PayRoll
(
EmployeeNumber nvarchar(30) not null,
StartDate DateTime not null
constraint fk_StartDate references Payperiod(StartDate),
PostalCode nvarchar(6) not null
constraint fk_PostalCode references Address(PostalCode),
Department nvarchar(50) not null,
TotalEarningsCurrent decimal(5,2) not null,
TotalEarningsYearToDate decimal(5,2) not null,
Netpay decimal(5,2) not null,
EmployeeName nvarchar(30) not null,
constraint pk_PayRoll primary key(EmployeeNumber,StartDate)
)


create table HoursandEarnings
(
EmployeeNumber nvarchar(30) not null
constraint fk_EmployeeNumber references PayRoll(EmployeeNumber),
StartDate DateTime not null
constraint fk_StartDate references Payperiod(StartDate),
HoursAndEarningsDescription nvarchar(50) not null, 
HoursandEarningsCurrent decimal(5,2) not null,
HoursandEarningsYearToDate decimal(5,2) not null,
constraint pk_HoursandEarnings primary 
key clustered(EmployeeNumber,StartDate,HoursAndEarningsDescription)
)




create table EmployerPaidBenefits
(
EmployeeNumber nvarchar(30) not null
constraint fk_EmployerPaidBenefits_EmployeeNumber references PayRoll(EmployeeNumber),
StartDate DateTime not null
constraint fk_EmployerPaidBenefits_StartDate references Payperiod(StartDate),
EmployerpaidBenefitsDescription nvarchar(50) not null,
EmployerPaidBenefitsCurrent decimal(5,2) not null,
EmployerPaidBenefitsYearToDate decimal(5,2) not null
constraint pk_EmployerPaidBenefits 
primary key(EmployeeNumber,StartDate,EmployerpaidBenefitsDescription)
)

create table Taxesanddeductions
(
EmployeeNumber nvarchar(30) not null,
constraint fk_Taxesanddeductions_EmployeeNumber references PayRoll(EmployeeNumber),
StartDate DateTime not null
constraint fk_Taxesanddeductions_StartDate references Payperiod(StartDate),
TaxesandDeductionsDescription nvarchar(50) not null,
TaxesandDeductionsCurrent decimal(5,2) not null,
EmployerPaidBenefitsYeartoDate decimal(5,2) not null,
constraint pk_Taxesanddeductions 
primary  key(EmployeeNumber,StartDate,TaxesandDeductionsDescription)

) 

1 个答案:

答案 0 :(得分:2)

因为表(EmployeeNumber,StartDate)上有一个复合键PayRoll,所以需要在引用它的其他表中引用外键中的两个键。

如果EmployeeNumber在表Payroll中是唯一的,那么您可以在EmployeeNumber上只创建Payroll主键,然后在另一个上创建外键3个Payroll表将按原样有效。(不是这样)

不相关,但我相信您可能会在PostalCode上使Address成为主键时遇到问题 - 这意味着只有一个具有相同PostalCode的地址可能会添加到表中。我会建议使用代理密钥。

修改

外键中两列的示例:

constraint fk_HE_EmployeeNumber 
   foreign key(EmployeeNumber, StartDate) 
   references PayRoll(EmployeeNumber, StartDate)

另请注意,主键和外键约束名在数据库中必须是唯一的(不只是在表中) - 您需要重命名重复键,如fk_StartDate

SqlFiddle here

您可能还会在某些时候发现复合/复合键的占用和额外存储要求可能会使简单代理键(如int identity()或Guids)的实现变得更简单。