2011-08-02 99 views
0

我有10個表。每個表由其他5個表的外鍵引用。更改主鍵值

我需要更改這10個表的主鍵值。有沒有辦法改變它,以便它會自動改變所有的外鍵?

我正在使用sql server 2008並且有管理工作室。

+1

出於好奇,你爲什麼要這麼做? –

+0

@Abe Miessler:我必須改變我的db結構。我想創建所有這10個表超類型。 – Naor

回答

4

您需要設置ON UPDATE CASCADE對於那些外鍵:

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

一個使用存儲的特效和其他觸發器。兩者似乎都有點痛苦。

+0

我不是在尋找一個代碼,只需按一下按鈕即可。這只是單一的改變,以解決我的數據庫計劃。 – Naor

5

下面是一個示例,說明如何使用ON UPDATE CASCADE外鍵選項執行此操作。你會感興趣的部分是兩個ALTER TABLE陳述。

如果您爲主鍵使用IDENTITY列,則由於無法更新IDENTITY列而變得更加困難。

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 Diver:我知道!我有標識列,所以我爲每個表所做的是: 1.創建new_id列。 2.將new_id設置爲新的ID。 3.刪除約束。 4.使用new_id更新引用。 5.放下主鍵。 6.刪除舊的ID列。 7.用new_id創建新的主鍵。 8.將new_id重命名爲id。 9.再次創建約束條件。 我期待着避免這一切。我正在尋找一個命令,允許更新主鍵及其引用AUTOMATICALY,因爲我有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