是否有任何理由避免使用 sp_rename 重命名对象?

got*_*tqn 6 sql-server t-sql sql-server-2012 sql-server-2014

文档中明确指出:

更改对象名称的任何部分都可能破坏脚本和存储过程。我们建议您不要使用此语句重命名存储过程、触发器、用户定义函数或视图;相反,删除对象并使用新名称重新创建它。

重命名怎么样:

  • 主键
  • 唯一键
  • 外键
  • 默认约束
  • 索引

我将重命名上述所有对象以匹配我们的内部命名约定,但我想为此编写一个自动脚本(因为有数千个约束)。

我能想到的唯一问题是,如果索引与hintin 语句一起使用,它将被破坏。

您能说出任何其他不将sp_rename用于此类目的的原因吗?

Jul*_*eur 6

  • 更新

sp_rename 更新 sys.objects 中的名称,但不会更新定义或引用它的对象。

  • 对象定义

重命名存储过程、函数、视图或触发器不会更改 sys.sql_modules 目录视图的定义列中相应对象名称的名称。因此,我们建议不要使用 sp_rename 来重命名这些对象类型。相反,删除并使用新名称重新创建对象。(微软)

当您运行此查询时:

Create Procedure Test
as
begin
    set nocount on
end
Go
Exec sp_rename 'Test', 'Tests'
GO
Select * From sys.sql_modules
sp_helptext 'Tests'
Run Code Online (Sandbox Code Playgroud)

中的definitionsql_modules仍然包含Test

object_id   definition ...
599673184   Create Procedure Test as begin set nocount on Select id From T1 end
Run Code Online (Sandbox Code Playgroud)
  • 重命名表(或对象)

重命名对象时,任何使用它并引用旧名称的对象都将失败。

这是一个视图和一个被重命名的表:

Create Table T1(id int)
Go
Create View V1 AS Select id From dbo.T1
Go  
Exec sp_rename 'T1', 'T2'
Run Code Online (Sandbox Code Playgroud)

同样,如果您查看定义,过程和视图都引用了 T1(不再存在):

object_id   definition
759673754   Create Procedure Test as begin set nocount on Select id From T1 end
791673868   Create View V1 AS Select id From dbo.T1
Run Code Online (Sandbox Code Playgroud)

当您从中选择或执行时,两者都会因此错误而失败:

Invalid object name 'dbo.T1'.
Could not use view or function 'V1' because of binding errors.
Run Code Online (Sandbox Code Playgroud)

如果刷新视图,则会出现相同的错误:

sp_refreshview 'v1'
Run Code Online (Sandbox Code Playgroud)

所有引用旧名称的对象都将中断。

  • 依赖关系

在重命名对象(表、过程、函数等)之前,您可以使用sys.sql_expression_dependencies( MSDN )查看其依赖项(已弃用:sys.sql_dependencies MSDNsys.sysdepends( MSDN )