2010-12-14 52 views
2

我有一個表message在一個數據庫中有近一百萬行。它有一個externalId列,它是varchar(50)。存儲在其中的值是guid,但我想更新此列爲uniqueidentifierSQL Server重構從varchar(50)到uniqueidentifier和周圍問題的列

所以我想我要添加一個新的列是uniqueidentifier。將所有值複製到此列,然後刪除原始列。然後我會將這一列重命名爲externalId

我的問題是有數百個存儲特效等,我需要確保我不會破壞任何東西。我也必須通過所有代碼grep並進行更改,以便我們期望Guid而不是字符串。 (我正在使用C#)

有沒有人有一些提示或建議?

我會更好做只是複製此列,並沒有觸及現有列,使,做了選擇就可以使用GUID列,而不是字符串的任何代碼(目前它有時倍出!)。我也將不得不更新任何代碼,然後插入到這張表中插入一個GUID ...)

我愛遺留廢話................... ...

+0

運說'我愛遺留廢話...'的SQL腳本,你開始你自己的人來的遺產在幾年內哭... – 2010-12-14 15:47:54

+0

是的,但我不使用存儲的特效。所以如果我想重構,我可以在代碼中完成,並且知道它會起作用。 – superlogical 2010-12-14 16:13:51

回答

0

事實證明,我把非聚集索引放在那個列上的速度非常快。我只是在Sql Server管理工作室中選擇了查詢,然後點擊「分析數據庫引擎優化顧問中的查詢」。它告訴我,這列需要一個指數,甚至產生你需要添加它:)

CREATE NONCLUSTERED INDEX [IX_message_external_id] ON [dbo].[message] 
(
    [external_id] ASC 
) 
INCLUDE ([message_id], 
[message_type_id], 
[message_status_id], 
[template_id], 
[user_id], 
[raw_message_body]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY] 
1

我可以給你的唯一真正的提示是一次完成。不要做這件事,因爲你會遇到問題。

添加列,複製值,刪除舊列,然後重命名新列。然後重新編譯您的所有存儲過程。這會給你一個問題領域的清單。修復它們並重新編譯。如果這部分看起來不錯,那麼繼續閱讀代碼。作爲遺產,你可能會發現很多其他問題,你甚至不知道。

該代碼將是最困難的領域。這些問題很可能涉及運行時錯誤。制定一個涵蓋絕對一切的測試計劃,並通過它。

+0

如何重新編譯所有存儲過程? – superlogical 2010-12-14 16:06:55

+0

@Jake Scott:只需編寫腳本並運行腳本。由於sql服務器試圖執行alter語句,它會拋出任何錯誤。 – NotMe 2010-12-14 16:51:24

+0

@Jake Scott:順便說一句,你可以輕鬆地腳本所有的proc的一次去。 – NotMe 2010-12-14 16:57:39

4

你可以簡單地

alter table message 
    alter column externalId uniqueidentifier 

的風險在於,如果任何存儲在列中的值都沒有的GUID,你會看到這樣的錯誤:

Conversion failed when converting from a character string to uniqueidentifier. 
4

我可能會接近這像這樣:

  • 在副本上工作
  • 添加類型的新列externalIdGuiduniqueidentifier
  • 嘗試將所有externalId轉換成新externalIdGuid

如果這樣的作品,那麼你所有的externalId是有效的GUID的 - 在這種情況下,你可能只是簡單地轉換成鍵入uniqueidentifier列:

ALTER TABLE dbo.Message 
    ALTER COLUMN externalID uniqueidentifier 
0

一個非常快速和安全的方式來檢查,如果你的開發系統上破壞任何東西是重命名你的表格message_legacy,使視圖稱爲消息,其投射到外部編號唯一標識符。這不應該與底層數據混淆,但會給你一個可行的接口,看看你的存儲過程和其他代碼將如何表現。請記住,如同您在桌面上一樣授予此視圖的相同權限,否則您可能會得到與權限相關的錯誤,而不是類型相關的錯誤,這是您真正想測試的內容。

如果您獲得可接受的結果,請繼續並更改列定義。就我個人而言,我會重命名該表,創建一個新列表,並更改列類型,插入new_table select * from old_table,然後刪除舊錶。

祝你好運!

1

我不會這樣做。是的,如果它是一個Uniqueidentifier,那麼它會更好,但除非你有一個特定的問題,如果不改變它就無法克服,那麼你的用戶的價值是什麼。

如果你確實決定去做。您可以查詢sys.procedures。它比使用syscomments或INFORMATION_SCHEMA.ROUTINES更好

+0

我需要加速此代碼,因爲它正在超時查找980,000 +行中的字符串值。 – superlogical 2010-12-14 16:08:17

相關問題