2013-12-19 32 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

最好的解决方案是简单地清理数据,你的更新声明是好的。

相关问题