2011-08-02 16 views
0

私は10のテーブルを持っています。各テーブルは、他の5つのテーブルの外部キーによって参照されます。主キーの値を変更する

これらの10個のテーブルのプライマリキーの値を変更する必要があります。自動的にすべての外部キーが変更されるように変更する方法はありますか?

私はSQL Server 2008を使用しており、管理スタジオを持っています。

+1

なぜ好きではないのですか? –

+0

@Abe Miessler:私はdbの構造を変更する必要があります。私はこのすべての10テーブルにスーパータイプを作成したいと思います。 – Naor

答えて

4

ALTER TABLE bar 
ADD CONSTRAINT FK_foo_bar 
FOREIGN KEY (fooid) REFERENCES foo(id) 
ON UPDATE CASCADE 

その後、あなたは、単にFKSと参照フィールドを更新は、トランザクションの一部として更新されます。

UPDATE foo SET id = id + 1000 

制約を変更するには、それらを削除する必要があることに注意してください。

+0

UPDATE CASCADEは参照を保持するテーブルのFKフィールドを自動的に変更しますか? – Naor

+0

@Naor、それはかなりポイントです:) – Serguei

0

私はこれをやったことが一度もありません。それは悪い考えかもしれないようです。

http://support.microsoft.com/kb/142480

一つは保存されprocsのと他のトリガーを使用しています。それは私がこれを行うための2つの方法を乗り越えて、この記事を見つけた、と述べました。どちらも少し痛みがあるようです。

+0

私は、ボタンをクリックして定期的に行うコードを探していません。私のdbスキームを修正するには単なる変更です。 – Naor

5

ON UPDATE CASCADE外部キーオプションを使用してこれを行う方法の例を次に示します。興味のある部分は2つのALTER TABLEです。

IDENTITYの列を主キーに使用している場合は、IDENTITY列を更新できないため、これは難しくなります。

あなたはそれらの外部キーのUPDATE CASCADE ONに設定する必要があります
CREATE TABLE Parent 
(
    ParentId INT NOT NULL CONSTRAINT [PK_Parent] PRIMARY KEY CLUSTERED, 
    Name VARCHAR(10) NOT NULL 
) 

CREATE TABLE Child 
(
    ChildId INT NOT NULL CONSTRAINT [PK_Child] PRIMARY KEY CLUSTERED, 
    ParentId INT NOT NULL CONSTRAINT [FK_Child_ParentId] FOREIGN KEY REFERENCES Parent (ParentId), 
    Name VARCHAR(10) NOT NULL 
) 

INSERT INTO Parent (ParentId, Name) VALUES (1, 'Bob') 
INSERT INTO Parent (ParentId, Name) VALUES (2, 'Sue') 

INSERT INTO Child (ChildId, Name, ParentId) VALUES (1, 'Alice', 1) 
INSERT INTO Child (ChildId, Name, ParentId) VALUES (2, 'Billy', 2) 

SELECT * FROM Child 

-- Drop foreign key constraint and re-add 
ALTER TABLE Child 
    DROP CONSTRAINT [FK_Child_ParentId] 

ALTER TABLE Child 
ADD CONSTRAINT [FK_Child_ParentId] 
    FOREIGN KEY (ParentId) REFERENCES Parent (ParentId) ON UPDATE CASCADE 

UPDATE Parent SET ParentId = ParentId + 100 

SELECT * FROM Child --shows the new ParentIds 

DROP TABLE Child 
DROP TABLE Parent 
+0

+1は 'IDENTITY'カラムに関する注釈です。 – Serguei

+0

完了したら、カスケード更新をサポートしないように制約を更新する価値があります。 –

+0

@Chrisダイバー:私はそれを知っています!私はID列を持っているので、各テーブルで何をしたのですか: 1. new_id列を作成します。 2. new_idに新しいIDを設定します。 3.ドロップ制約。 4. new_idで参照を更新しました。 5.プライマリキーを削除します。 6.古いID列を削除します。 7. new_idを使用して新しい主キーを作成します。 8. new_idの名前をidに変更します。 9.再度制約を作成します。 私はこれをすべて避けるために探しています。私は行くために10のテーブルがあるため、主キーとその参照を自動的に更新できるようにする単一のコマンドを探しています。 – Naor

0

IDENTITY列の重要な欠点は、直接更新できないことです。

回避策は、ターゲット表でIDENTITYを使用するのではなく、余分な表に入れることです。最初にIDENTITYカラムを持つテーブルに挿入し、生成されたIDENTITY値をターゲットテーブルに挿入します。

SQL Server 2012には、テーブルに依存しないシーケンスが導入されています。これは、同じ問題の解決策です。シーケンスに余分なテーブルは必要ありません。

0

これは本当にあなたの質問に対する答えではないことを知っていますが、私はここで、(書き込み、挿入、更新または他の方法で)PK(主キー)列に設定する方法を探していました。

したがって、PK制約を無効にして値を挿入し、後で有効にする必要があります。更新は機能しません。

SET IDENTITY_INSERT IdentityTable ON 
INSERT IdentityTable(TheIdentity, TheValue) VALUES (3, 'First Row') 
SET IDENTITY_INSERT IdentityTable OFF