在SQL Server中重命名存储过程

35

我正尝试使用sp_rename系统存储过程来重命名SQL Server 2008中的存储过程。然而,第三个参数让我困扰,我一直收到以下错误:

Msg 15249, Level 11, State 1, Procedure sp_rename, Line 75
Error: Explicit @objtype 'P' is unrecognized.

正如消息所示,我将一个 P 作为参数的值传递。我这样调用 sproc:

EXEC sp_rename @objName = @procName, @newname = @WrappedName, @objtype = 'P';

我仔细查阅了文档,文档中说明这是从sys.objects获取的值。我运行了以下代码,以确保我没有疯掉。

select * from sys.objects where name = 'MySprocName'

实际返回的类型是 P。

有人知道我应该传递什么吗?我不想留空,因为我正在创建一个通用的存储过程来重命名任意的存储过程,如果一个存储过程与其他东西发生名称冲突,我不想担心这个问题。

9个回答

68

只需省略 @objtype 参数(默认值为 null),它就可以正常工作。

EXEC sp_rename 'sp_MyProc', 'sp_MyProcName'

您会收到以下警告,但是该过程将被重命名。

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

正如其他人所说,您应该删除并重新创建该过程。


20
根据文档,'P'不是正确的选项。您应该尝试使用'OBJECT',因为它看起来最接近您要做的事情。但是,请注意以下警告...

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

此外(来自同一MSDN页面):

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


谢谢,我看过了但不知道为什么错过了我需要输入的正确值。 - Peter Oehlert
请注意,删除存储过程将删除所有相关权限。重命名的最佳方式是使用sp_rename,然后修改proc以更正sys_modules。 - Boogier

2

重命名存储过程有两种方法:

  1. 删除和重新创建存储过程:问题是会导致权限丢失。
  2. 使用 sp_rename 重命名存储过程:权限将保持完好。存储过程将被重命名。但是,sys.sql_modules 仍将具有旧的定义。

我更喜欢第二种方法。我按照以下步骤进行操作:

  1. 复制存储过程内容
  2. 重命名存储过程
EXEC sp_rename 'dbo.OldStoredProcedureName','NewStoredProcedureName'
GO
  1. ALTER PROCEDURE 将修改后的存储过程代码放入sys.sql_modules
ALTER PROCEDURE dbo.NewStoredProcedureName
...

现在,存储过程名称也已更新,代码已在 sys.sql_modules 中刷新,并且权限也保持不变。

2
  • The third parameter(@objtype) is required when you want to rename a database object other than a stored procedure. Otherwise it is necessary to pass a third parameter. For example renaming a column using sp_rename will look something like this.

    USE AdventureWorks2012;  
    GO  
    EXEC sp_rename 'Sales.SalesTerritory.TerritoryID', 'TerrID', 'COLUMN';  
    GO
    
  • To rename a user-defined stored procedure using sp_rename,you can do something like this and it literally works

sp-rename

然而,Microsoft、数据库专家(以及其他人)不建议使用此存储过程,因为它会在内部破坏一些东西,并可能导致以后出现异常结果。因此这是不好的。以下是Microsoft的说法:
引用一个存储过程、函数、视图或触发器的名称将不会更改sys.sql_modules目录视图中的定义列或使用OBJECT_DEFINITION内置函数获取的相应对象的名称。因此,我们建议不要使用sp_rename来重命名这些对象类型。而是删除并重新创建具有新名称的对象。
重命名表或列等对象不会自动重命名对该对象的引用。您必须手动修改引用重命名对象的任何对象。例如,如果您重命名了一个表列并且该列在触发器中被引用,则必须修改触发器以反映新的列名。在重命名对象之前,请使用sys.sql_expression_dependencies列出对该对象的依赖项。
您可以在这里阅读相关内容:sp_rename (Transact-SQL)

1
我不确定 @objtype 变量,但我知道通过 sp_rename 重命名是不好的。
创建存储过程时,它在 sys.objects 中有一条记录,存储过程的定义将存储在 sys.sql_modules 中。
使用 sp_rename 只会更改 sys.objects 中的名称,而不是 sys.sql_modules 中的名称,因此您的定义将不正确。
最好的解决方案是删除并重新创建。

对于我正在做的事情实际上并不重要。我正在进行一些注入,其中我动态创建一个基于原始定义的过程,将原始定义重命名为新名称,然后从我的注入版本中调用原始定义。当我完成仪器化后,我会撤消这个过程。 - Peter Oehlert

0

瓦伦蒂诺·弗兰肯说的都是真的。但要记住,当你删除并创建存储过程时,会丢失所有元数据(Create_Date、Modify_Date等)。

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

这也是真的。但我发现,在进行重命名后运行修改脚本,它会在模块的定义中修正名称。

我一直想知道SSMS界面是如何在不使用T-SQL的情况下自动完成所有这些操作的。(也许它每次使用界面重命名存储过程时都会运行一个修改脚本?我不知道。)如果微软能够公开发布在进行SSMS重命名时背后发生的事情,那将很有趣。


SSMS(Sequel Server Management Studio)可以完成任务,但也有其自身的问题。重命名后,要查看已更名的存储过程列表,必须右键单击“存储过程”,然后选择“刷新”。即使刷新后,某些内部缓存仍处于不正确的状态;例如,编辑器不知道更改(查询中出现新名称时的红色下划线),而且我认为我见过一个错误消息,但实际上并不需要。要解决这个问题,必须关闭并重新启动SSMS。 - IAM_AL_X

0
在 SQL 2000 的时代,使用 DROP/CREATE 更为安全--因为当你使用 sp_rename 时,SQL 会让存储过程的元数据不同步。要想学习如何进行高级 DDL 操作,最好的方法是在连接了 Profiler 跟踪器的情况下使用 SSMS 对对象进行重命名。

0

sp_rename不支持过程:

更改当前数据库中用户创建对象的名称。此对象可以是表、索引、列、别名数据类型或 Microsoft .NET Framework 公共语言运行时 (CLR) 用户定义类型

只需创建具有相同主体和新名称的新过程,然后删除旧过程即可。


1
这不正确。使用@objtype指定“OBJECT”,可以使sp_rename正常工作。 - Peter Oehlert
6
@Peter:可能不是百分之百准确,但肯定不建议使用sp_rename。_"重命名存储过程、函数、视图或触发器将不会更改sys.sql_modules目录视图中定义列中相应对象名称的名称。因此,我们建议不要使用sp_rename来重命名这些对象类型,而是使用其新名称删除并重新创建对象。"_(来自[MSDN](http://msdn.microsoft.com/en-us/library/ms188351.aspx)) - Valentino Vranken

-1

sp_rename只会改变数据库中用户创建的对象的名称。重命名存储过程不会改变sys.sql_modules目录视图的定义列中相应对象名称的名称。

因此,我们建议您不要重命名此对象类型。而是使用新名称删除并重新创建存储过程。即使您试图使用它来更改视图、函数或触发器的名称,也不应该使用它。如果您尝试使用它,它会将其重命名,但您还将收到诸如以下警告消息:

更改对象名称的任何部分都可能破坏脚本和存储过程。

有关更多信息,请访问。

http://onlyforcoder.blogspot.in/2017/11/sprename-where-to-use-where-not-to-use.html http://blog.sqlauthority.com/2008/08/26/sql-server-how-to-rename-a-column-name-or-table-name/


这应该被踩。这是对其他人之前呈现的信息的无用重复。同样适用于“blogspot”链接。而“sqlauthority”链接则完全离题。 - IAM_AL_X

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接