2009-03-17 2 views
2

Я работаю с существующей базой данных 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

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

+0

будет иметь значение по умолчанию, влияющее на это? – RSolberg

+0

@ [RSolberg]: только если значение по умолчанию фактически использовалось в строке и не ссылалось на существующую строку в родительской таблице. –

+0

@Steven - Я предполагаю, что это моя проблема. Пример cmsjr все равно не будет работать для меня. – RSolberg

0

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

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

+0

Спасибо - я добавил скрипт создания выше. – RSolberg

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 
+0

Все ошибки 3 ... Msg 8139, уровень 16, состояние 0, строка 1 Число ссылочных столбцов в внешнем ключе отличается от числа ссылочных столбцов таблицей «person_campaigns». – RSolberg

+0

Извините, попробуйте отредактированную версию. – cmsjr

+0

Это снова заблудилось ... Я добавил вывод для скриптов create table для всех 4 выше. – RSolberg

2

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

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

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

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

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