你如何添加外键关系?

时间:2009-03-17 03:24:48

标签: sql sql-server-2005 foreign-keys data-integrity

我正在使用现有的SQL 2005数据库,该数据库未使用表之间的FK关系实现。我试图添加与数据库关系图的关系,我的应用程序立即爆炸尝试编辑或插入与新FK绑定的任何数据。

dbo.person [person_id | firstname | lastname | dateofbirth]
dbo.campaign [campaign_id | campaign_description]
dbo.disposition [disposition_id | disposition_description]
dbo.person_campaigns [person_campaign_id | person_id | campaign_id | disposition_id]

person_campaigns表是将人员,活动和处置捆绑在一起的地方。您能否提供适当的SQL语法来在这些实体之间添加适当的FK关系?

修改

CREATE TABLE [dbo].[person_campaigns](
    [person_campaigns_id] [int] IDENTITY(1,1) NOT NULL,
    [person_id] [int] NOT NULL,
    [d_campaign_id] [int] NOT NULL,
    [d_physician_disposition_id] [int] NULL,
 CONSTRAINT [PK_person_campaigns] PRIMARY KEY CLUSTERED 
(
    [person_campaigns_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[d_campaign](
    [d_campaign_id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](50) NULL,
    [year] [int] NULL,
    [isactive] [bit] NOT NULL,
 CONSTRAINT [PK_d_campaign] PRIMARY KEY CLUSTERED 
(
    [d_campaign_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[d_campaign] ADD  CONSTRAINT [DF_d_campaign_isactive]  DEFAULT ((1)) FOR [isactive]
GO

CREATE TABLE [dbo].[d_disposition](
    [d_disposition_id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](50) NULL,
    [isactive] [bit] NOT NULL,
 CONSTRAINT [PK_d_disposition] PRIMARY KEY CLUSTERED 
(
    [d_disposition_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[d_disposition] ADD  CONSTRAINT [DF_d_disposition_isactive]  DEFAULT ((1)) FOR [isactive]
GO

CREATE TABLE [dbo].[person](
    [person_id] [int] IDENTITY(1,1) NOT NULL,
    [firstname] [varchar](30) NULL,
    [lastname] [varchar](30) NULL,
    [dateofbirth] [datetime] NULL
 CONSTRAINT [PK__person__0BC6C43E] PRIMARY KEY CLUSTERED 
(
    [person_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

4 个答案:

答案 0 :(得分:4)

最简单的方法是通过数据库图表编辑器;一次执行一个并保存图表以在每次连接后影响表格。如果它“爆炸”,很可能是因为表中包含不存在的外键值;你必须先清理这些。

答案 1 :(得分:2)

如果必须在创建表后添加它们,则语法为

 create table  person (person_id int primary key 
,firstname varchar(10)
, lastname varchar(10)
, dateofbirth varchar(10))

create table campaign (campaign_id int primary key
, campaign_description varchar(10))
create table  disposition (disposition_id int primary key  
,disposition_description varchar(10))

create table person_campaigns(person_campaign_id int
,person_id int, campaign_id int ,disposition_id int)
go
alter table person_campaigns  add Constraint 
fk_person_campaigns_person_id
Foreign Key (person_id) References person(person_id)
GO

alter table person_campaigns add Constraint 
fk_person_campaigns_campaign_id
Foreign Key (campaign_id) References campaign(campaign_id)
GO

alter table person_campaigns add Constraint
fk_person_campaigns_disposition_id
Foreign Key (disposition_id) References disposition(disposition_id) 

GO

答案 2 :(得分:2)

假设我有两个表应该有外键但没有。首先要做的是检查是否存在数据问题,如果我设置了外键。

类似下面的代码可以获得子表中父表中没有匹配项的记录。

select t2.FKField, t2.PKfield from table2 t2
left join Table1 t1 on t2.fkfield = t1.pkfield
where t1.pkfield is null

一旦您看到现有数据有什么问题,那么您需要创建一种方法来解决它。修复程序将根据您拥有的与Parent表无关的数据以及表所代表的内容而有所不同。假设您的父表包含汽车的VIN编号作为PK。如果您的子表包含商店处理的汽车,您可能希望通过将不存在的VINS添加到主表来解决问题,因为您不希望丢失已处理的历史记录。还有其他结构,您可能只想删除子表中不匹配的记录,因为它们没有意义。在其他情况下,您可能希望将这些记录更新为某个默认值(可能是客户表中名为unknown的客户)。在其他情况下,您可能需要转到审计表或备份,以查找已删除的PK值,而不删除关联的子记录。解决此问题的实际方法在很大程度上取决于数据的用途以及保留所有历史记录的重要性。由于法律(和会计)原因,您永远不应删除任何可能与金融交易相关的记录,因此您需要特别小心。

修复所有数据后,运行代码以创建FK约束。

答案 3 :(得分:0)

由于我没有在这台PC上安装SQL Server而且我没有记住语法,最简单的方法是创建两个新的测试表,创建一个带有ID字段的TableA,TableB带有一个字段是TableA.ID的FK,然后编写TableB脚本以查看ADD CONSTRAINT语法。通过数据库图表使用SQL Server Management Studio执行此操作。

但是,如果您能够在数据图中成功创建FK,并且您只能添加或更新记录,我相信其他错误。写出person_campaigns表并发布代码。