2014-05-08 45 views
1

我不认为我可以在关于我的问题的标题中具体。让我这样说,远离谈论项目的内容。如何将主键值分配给外键?

我在我的数据库中有很多表,其中两个是PersonsAddress。需要规范化并设置这两个实体之间的多对多关系,我不保留这些表中的任何外键相互引用。例如,我不存储外键到Address表中,在Person表中

而是,我的外键位于名为PersonAddress的第三个表中。此表包括什么,但只有两个外键在自己的表引用的主键(PersonAddress

在Microsoft SQL Server,我们挂有问题的表到其他两个,使得表的属性(PersonId, AddressId)另外两个表名为PersonAddress外键,允许删除和更新级联操作。 (反正)

在第一次,它似乎会工作得很好。但是,一旦我们继续向数据库输入数据,就会发现外键值在第三个表中保持不变,我们可以在这两个表中看到每个主键值Person和Address

任何帮助将不胜感激,谢谢提前为您的未来尝试,家伙。

+1

您已经添加ON DELETE CASCADE ON UPDATE CASCADE而定义的外键? – Deepshikha

+0

你能澄清你正在执行什么声明,你认为应该是什么效果? – Lennart

回答

3

您做了正确的事情来创建中间表以创建多对多关系,并且它按预期工作。在PersonAddress表

  • SQL服务器将不会自动删除相关项目,但这样自己
  • 我会把主键上横跨两个其他ID的表,如果您还没有这样做会失败 - 让他们都作为FK也是如此。

请澄清这个问题,如果它没有回答它。

+0

确保你看看DeepShikha的答案......看起来你可能可以级联更新和删除。 – Ruskin

1

要反映或级联在父表中引用列中完成的更改(即,如果更改了父表的主键列中的值),还要反映在子表中(即,您希望在子表外键键列也被更新为相同的值),您应该在定义外键时添加Cascade选项。

为:

create table PersonAddress 
    ( 
    PersonId int 
    , AddressId int 
    ,CONSTRAINT FK_PersonId Foreign key (PersonId) 
    references Person(id) ON UPDATE CASCADE ON DELETE CASCADE 
    ,CONSTRAINT FK_AddressId Foreign key (AddressId) 
    references Address(id) ON UPDATE CASCADE ON DELETE CASCADE 
    ); 

正如你已经到位表定义修改外键约束,我们必须首先删除现有外键约束,然后再用新的定义重新创建它。 所以,写为:

IF EXISTS (SELECT * FROM sys.objects 
WHERE name = 'FK_PersonId' AND [type] = 'F') 
ALTER TABLE PersonAddress 
DROP Constraint FK_PersonId 

GO 

ALTER TABLE PersonAddress 
ADD CONSTRAINT [FK_PersonId] 
FOREIGN KEY (PersonId) REFERENCES Person(id) 
ON DELETE CASCADE ON UPDATE CASCADE 
GO 

您可以检查试运行here