2009-09-14 83 views
2

現在我們已經用盡了int的PK列(這是一個IDENTITY)我想這樣做到bigint,但簡單的ALTER TABLE似乎無法處理大桌子。所以我的問題是:如何在保留實際值的情況下更改PK列的類型,以及是否還需要更改引用表?更改巨大的表PK列數據類型

回答

4

除了KLE的建議,下面的查詢可能會有所幫助:

要禁用引用oldTable嘗試執行以下查詢的輸出表中的所有約束條件:

SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name 
FROM sys.foreign_keys fk 
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id 
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable' 

要將所有數據到新表,同場的變化試試這個:

INSERT INTO newTable 
SELECT CONVERT(BIGINT, ID) AS ID, COL1, COL2, ..., COLN 
FROM oldTable 

要刪除舊錶:

DROP TABLE oldTable 

到新表重命名爲舊名:

sp_rename newTable, oldTable 

要重新啓用上引用oldTable表中的所有限制,嘗試執行以下查詢的輸出:

SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name 
FROM sys.foreign_keys fk 
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id 
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable' 

希望它有幫助...

+0

如果使用此方法,不要忘記重新創建表 – 2009-09-14 11:06:45

+0

上的索引,我認爲更好地禁用受影響的表上的所有觸發器 – 2009-09-14 12:56:27

-1

我認爲你只能創建一個新的PK數據類型的數據庫,然後導出/導入數據,或批量插入到新的,然後重命名新的數據庫。當然,如果你有很多被引用的表,並且你的新的PK數據類型與以前不兼容,這實際上是這樣的。

3

我們會做的是:

保存表

  1. 創建一個新表具有正確的結構
  2. 禁用這些表上引用的那些所有的約束和他們
  3. 移動所有數據到新表中,並改變字段;它可以通過分批完成
  4. 刪除舊錶的時候它是空的
  5. 新表重命名爲舊名稱
  6. 使可能需要修正過所有表上的一些FK列所有約束(和約束...但它們不是PK,因此它們是可以修改的)

    6編輯(多虧阿列克謝)

此我清潔,可批量使用,很好理解。

+1

某些數據類型不兼容。一般而言,您應該將所有引用的表格更改爲。如果你有很多引用表 - 這可能會成爲「依賴地獄」 – 2009-09-14 08:08:54

0

您還需要更改子表。畢竟,你現在會試圖在它們中插入一個大的int。我會先改變子表格

這不是一個簡單或短的過程。我建議你告訴你的用戶數據庫將在設定的日期停機維護(你可以估計需要多長時間才能完成開發),並將數據庫重置爲單用戶模式這些變化。在切換到另一個表時,您不希望丟失用戶添加(或更改)到一個表的數據。如果因爲某些原因你不能擁有一個maintence窗口(爲了數據的完整性,我強烈建議你這樣做),那麼你必須首先更改子表以避免插入錯誤,如果你真的接近極限並且會幾乎立即看到大量數字。

確保腳本包含默認值,觸發器,檢查約束索引等整個數據庫結構,因爲您將要重新創建所有內容。

確保通過dev上的腳本完成所有這些。一旦你測試了這個過程,這將使得更容易做一個產品。