2009-03-17 10 views
2

私はテーブル間のFK関係で実装されていない既存のSQL 2005データベースを使用しています。データベースダイアグラムで関係を追加しようとしましたが、新しい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テーブルは、人、キャンペーン、および配置が結びついている場所です。これらのエンティティ間に適切なFK関係を追加するための適切なSQL構文を提供してください。

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

最も簡単な方法は、データベースダイアグラムエディタを介して行われています。それらを一度に1つずつ実行して、各接続が確立された後でテーブルに影響を及ぼすためにダイアグラムを保存します。それが "爆発する"場合は、表には存在しない外部キー値が含まれている可能性が高いです。これらを最初に清掃する必要があります。

+0

デフォルト値はこれに影響しますか? – RSolberg

+0

@ [RSolberg]:デフォルト値が実際に行で使用され、親テーブルの既存の行を参照していない場合のみ。 –

+0

@スティーブン - 私はそれが私の問題だと思っています。 cmsjrの例はまだ私にとってはうまくいかないでしょう。 – RSolberg

0

私はこのPCにSQL Serverを持っていないと私は構文を暗記していないので、一番簡単な方法は、TableAのを作成して、二つの新しいテストテーブルを作成することですIDフィールドを持つTableB、TableA.IDのFKであるフィールドを持つTableB、およびTableBをスクリプトアウトしてADD CONSTRAINT構文を確認します。データベースダイアグラムを使用してSQL Server Management Studioを使用してこれを行います。

ただし、データダイアグラムでFKを正常に作成でき、レコードの追加や更新ができない場合は、何か間違っていると思います。 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つのエラーが発生しました... メッセージ8139、レベル16、状態0、行1 外部キーの参照列の数は、参照された列の数、テーブル 'person_campaigns'と異なります。 – RSolberg

+0

ご迷惑をおかけしますが、編集してください。 – cmsjr

+0

もう一度エラーが発生しました...上記の4つのテーブルスクリプトを作成するための出力を追加しました。 – RSolberg

2

私は外部キーを持っていてはならないテーブルが2つあったとします。最初に行うことは、外部キーを設定するとデータに問題があるかどうかを確認することです。

次のコードのようなものは、親テーブルに一致しない子テーブルのレコードを取得します。

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制約を作成します。

関連する問題