如何在不破坏您的SQL数据库的前提下对一个列进行重命名

重命名一张表或视图的列并不是一个SQL开发者每天都需要做的事情。然而,当遇到这种情况的时候,如何能轻松容易地做这件事情呢?

仅仅是重命名一个列并不难。将 Sales.SalesTerritory表里的TerritoryID 列重命名为TerID,执行下面的语句:

EXECUTE sp_rename 'Sales.SalesTerritory.TerritoryID', 'TerrID', 'COLUMN';

问题是您会得到下面的警告信息:

注意:更改对象名的任一部分都可能会破坏脚本和存储过程

另外,更严重可能会出现:

对象 ‘Sales.SalesTerritory.TerritoryID’ 无法重命名,因为它参与了强制依赖关系。

这些脚本会破坏什么?

您有一个Sales.vTer存储过程引用了Sales.SalesTerritory表里的TerritoryID 列。sp_rename存储过程会只重命名Sales.SalesTerritory表里的TerritoryID 列,
而不会重命名Sales.vTer存储过程里Sales.SalesTerritory表里的TerritoryID 列。

因此,Sales.SalesTerritory表会包含 TerrID列,但是存储过程会调用Sales.SalesTerritory.TerritoryID,但是实际上并不存在。这个脚本会遭到破坏并执行失败。

什么是强制依赖?

一种被“强制的”依赖关系当所引用对象有一个架构绑定表达式。消息也显示了,如果有任何其他的对象为了成功地重命名列名,您必须要删掉旧的列或者使用新列名进行重建

如何找到在列名更改之后受影响的存储过程和其他对象?

SQL Server Management Studio 可以跟踪依赖,经由它的视图依赖选项。它显示了被选对象所依赖的对象,不过您依然需要逐个地更新引用重命名列的对象。

要重命名一个列使用sp_rename,您需要:

  1. 找到所有引用表/视图列的依赖对象
  2. drop掉所有强制依赖
  3. 执行sp_rename来重命名列
  4. 重新创建所有在步骤2被drop掉的强制依赖对象
  5. 如果您想重命名多个列,那么重复步骤1到4

这不是一个有吸引力的过程。对于继续下去,它会让您放弃重命名

如何免去这么多麻烦来轻松重命名一个列?

ApexSQL Search 可以帮忙。这是一个免费的SQL Server Management Studio 和Visual Studio插件并且能找到SQL数据库对象里的文本,SQL数据库表和视图里的数据。
它允许您不破坏依赖关系去更改表、视图、存储过程、函数、列、参数名和架构,同时可视化所有的对象依赖关系。

  1. 打开 SQL Server Management Studio 或者 Visual Studio
  2. 在对象浏览器/服务器浏览器,导航到您想重命名的表或视图列
  3. 在列上右击并在选择ApexSQL Search菜单上选项“Safe rename” 选项:

  4. 要查看将要被执行的更改,点击“Generate preview”在“Safe rename column”对话框里
  5. 在 “Generated script”tab窗格里显示了将要重命名列所要执行的脚本

  6. 打开“警告”tab窗格来查看在重命名的过程中会遇到的潜在问题的信息。

  7. 打开“序列”tab窗格来查看在重命名期间将会被执行的动作。这些动作当您使用sp_rename 存储过程的时候您需要手工遍历的。

  8. 打开“依赖”tab窗格来查看依赖于重命名列的对象。这些对象会被自动修改以防止脚本遭到破坏。如果您使用sp_rename 存储过程,您必须手动找到并修改它们。

  9. 如果您想在执行脚本之前修改它,点击“打开”按钮。生成好的脚本会在SQL Server Management Studio查询编辑器/ Visual Studio编辑器里打开

    审查,然后修改它如果需要的话,并点击“执行”来执行它或者保存脚本到一个文件里。

  10. 要执行该脚本,点击“重命名”按钮

重命名一个列将会变得容易的和免费的。您不需要分析您所有的数据库和查找各自的依赖。使用 ApexSQL Search 来为您达到目的。它会找到所有依赖对象,重命名并在必要时进行删除-重建,来避免破坏脚本

翻译者: 林勇桦

July 2, 2015