2013-12-19 65 views
0

我正在使用SQL Server Management Studio中的數據庫,並且有兩個表,Route和Tractor(這是一個簡化示例)。目前,路由表中包含一個名爲TractorID的列。它不是Tractor表ID列的外鍵或索引,但它在我們的應用程序中用於通過其ID搜索拖拉機表。這使我們的用戶可以在過去刪除拖拉機而不影響拖拉機的使用路線。當列已經有數據時將列升級到外鍵

我現在正在升級數據庫,以便TractorID列是拖拉機表ID列的外鍵,但我遇到了問題。由於用戶已經刪除了拖拉機,並且在路由表中沒有更新,因此有幾條拖拉機ID不在拖拉機表中的路徑。我需要事先將這些假ID設置爲null,以便我可以將列升級到外鍵。

我這樣做使用下面的語句:

UPDATE Route SET Route.TractorID = NULL 
WHERE Route.TractorID IS NOT NULL AND NOT EXISTS(SELECT * FROM Tractor 
WHERE Tractor.ID = Route.TractorID) 

到目前爲止,該聲明似乎這樣的伎倆,但我擔心的是如何有效的。我們有幾個數據庫,每個月需要升級250萬條路線。我認爲這個子查詢觸發每一行,所以我希望找到一個解決方案,可能涉及將路線和拖拉機表加在一起(JOIN Tractor ON Route.TractorID = Tractor.ID),然後將TractorID設置爲NULL,如果該行的聯接不成功(即TractorID與任何Tractor.ID s不匹配)。

這可能嗎?或者,我現在的解決方案夠好嗎?提前致謝。

回答

1

第一步是確保Route表中的TractorID列有一個索引。

CREATE NONCLUSTERED INDEX IX_Route_TracorID ON Route(TractorID) 

對於更新,您可以使用左外連接,查找所有孤立TractorID的,並將它們設置爲NULL

UPDATE Route 
SET TractorID = NULL 
FROM Route AS R 
LEFT OUTER JOIN Tractor AS T 
ON R.TractorID = T.ID 
WHERE T.ID IS NULL 

的左連接應該是遠遠快於NOT EXISTS。

+0

太棒了!這是我正在尋找的。需要在所有可能的聯接中刷新自己... – Otteravenger

0

最好的解決方案是簡單地清理數據,你的更新聲明是好的。

相關問題