Как вы добавляете отношения с внешними ключами? - PullRequest
2 голосов
/ 17 марта 2009

Я работаю с существующей базой данных 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 между этими объектами?

EDIT

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 ]

4 голосов
/ 17 марта 2009

самый простой способ сделать это через редактор диаграмм базы данных; делайте их по одному и сохраняйте диаграмму, чтобы повлиять на таблицы после каждого соединения. Если он «взрывается», это, скорее всего, потому что таблицы содержат значения внешнего ключа, которые не существуют; сначала вам придется их почистить.

2 голосов
/ 17 марта 2009

Предположим, у меня было две таблицы, которые должны были иметь внешний ключ, но не имели. Первое, что нужно сделать, это проверить, не возникнет ли проблема с данными, если я установлю внешний ключ.

что-то вроде приведенного ниже кода даст вам записи в дочерней таблице, которые не совпадают в родительской таблице.

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

Как только вы увидите, что не так с существующими данными, вам нужно создать способ исправить это. Исправление будет зависеть от того, какие данные у вас не имеют отношения к родительской таблице и что представляют таблицы. Предположим, что ваша родительская таблица содержит номер VIN для автомобилей в качестве PK. Если ваша дочерняя таблица содержит автомобили, над которыми работал магазин, вы можете решить проблему, добавив несуществующие VINS в основную таблицу, потому что вы не захотите потерять историю того, над чем работали. Существуют и другие структуры, в которых вы можете просто удалить записи, которые не совпадают в дочерней таблице, поскольку они не имеют смысла. В других случаях вы можете захотеть обновить эти записи до некоторого значения по умолчанию (возможно, клиент в таблице клиентов называется неизвестным). В других случаях вам может потребоваться перейти к таблицам аудита или резервным копиям, чтобы найти значение PK, который был удален без удаления связанных дочерних записей. Фактический способ решения этой проблемы в значительной степени зависит от того, для чего используются данные, и насколько важно сохранить все исторические записи. Поскольку вам никогда не следует удалять какие-либо записи, которые могут быть связаны с финансовой транзакцией по юридическим (и бухгалтерским) причинам, вам следует быть максимально осторожными с ними.

После исправления всех данных вы запускаете код для создания ограничения FK.

2 голосов
/ 17 марта 2009

Если вам нужно добавить их после создания таблицы, синтаксис будет

 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
0 голосов
/ 17 марта 2009

Поскольку у меня нет SQL Server на этом ПК и я не запоминаю синтаксис, проще всего создать две новые тестовые таблицы, создать TableA с полем ID, TableB с полем FK TableA.ID, а затем сценарий TableB, чтобы увидеть синтаксис ADD CONSTRAINT. Сделайте это с помощью SQL Server Management Studio через диаграмму базы данных.

Однако, если вы смогли успешно создать FK на диаграмме данных, и вы не можете только добавлять или обновлять записи, я думаю, что-то еще не так. Запишите в таблицу person_campaigns и опубликуйте код.

...