sp_refreshsqlmodule (Transact-SQL)
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics(仅限专用 SQL 池)
更新当前数据库中指定的非绑定到架构的存储过程、用户定义函数、视图、DML 触发器、数据库级 DDL 触发器或服务器级 DDL 触发器的元数据。 如果更改这些对象的基础对象,则这些对象的持久元数据(如参数的数据类型)将会过时。 例如,你可能会看到类似于 The definition for user-defined data type 'typename' has changed
.. 刷新使用错误中指定的类型的模块的元数据可能会解决问题。
sp_refreshsqlmodule
[ @name = ] N'name'
[ , [ @namespace = ] { OBJECT | DATABASE_DDL_TRIGGER | SERVER_DDL_TRIGGER } ]
[ ; ]
参数
[ @name = ] N'name'
存储过程、用户定义的函数、视图、DML 触发器、数据库级 DDL 触发器或服务器级 DDL 触发器的名称。 @name为 nvarchar(776),没有默认值。 @name不能是公共语言运行时(CLR)存储过程或 CLR 函数。 @name不能绑定到架构。 @name 可以是多部分标识符,但只能引用当前数据库中的对象。
[ @namespace = ] N'namespace'
指定模块的类。 @namespace为 nvarchar(20),默认值为 OBJECT
. 当@name为 DDL 触发器时,需要@namespace。 有效输入为 DATABASE_DDL_TRIGGER
和 SERVER_DDL_TRIGGER
。
返回代码值
0
(成功)或非零数(失败)。
注解
sp_refreshsqlmodule
应在对影响其定义的模块基础的对象进行更改时运行。 否则,在查询或调用模块时可能会生成意外结果。 若要刷新视图,可以使用同 sp_refreshsqlmodule
一结果或 sp_refreshview
相同的结果。
sp_refreshsqlmodule
不会影响与对象关联的任何权限、扩展属性或 SET
选项。
若要刷新服务器级 DDL 触发器,可以在任何数据库的上下文中执行此存储过程。
注意
运行 sp_refreshsqlmodule
时,将删除与对象关联的任何签名。
权限
需要对相应模块拥有 ALTER
权限,对该对象引用的任何 CLR 用户定义类型和 XML 架构集合拥有 REFERENCES
权限。 ALTER ANY DATABASE DDL TRIGGER
当指定的模块是数据库级 DDL 触发器时,需要当前数据库中的权限。 CONTROL SERVER
当指定的模块是服务器级 DDL 触发器时,需要权限。
此外,对于使用 EXECUTE AS
子句定义的模块, IMPERSONATE
需要对指定的主体具有权限。 通常,刷新对象不会更改其 EXECUTE AS
主体,除非定义了 EXECUTE AS USER
模块,并且主体的用户名现在解析为与创建模块时用户不同的用户。
示例
本文中的 Transact-SQL 代码示例使用 AdventureWorks2022
或 AdventureWorksDW2022
示例数据库,可从 Microsoft SQL Server 示例和社区项目主页下载它。
A. 刷新用户定义的函数
以下示例刷新用户定义函数。 此示例创建别名数据类型 mytype
和使用 to_upper
的用户定义函数 mytype
。 然后, mytype
重命名为 myoldtype
,并创建一 mytype
个新的定义,这是一个不同的定义。 刷新了 dbo.to_upper
函数,以使它引用 mytype
的新实现,而非其旧实现。
在第一步中,创建别名类型。
USE AdventureWorks2022;
GO
IF EXISTS (SELECT 'mytype' FROM sys.types WHERE name = 'mytype')
DROP TYPE mytype;
GO
CREATE TYPE mytype FROM NVARCHAR(5);
GO
IF OBJECT_ID('dbo.to_upper', 'FN') IS NOT NULL
DROP FUNCTION dbo.to_upper;
GO
CREATE FUNCTION dbo.to_upper (@a mytype)
RETURNS mytype
WITH ENCRYPTION
AS
BEGIN
RETURN UPPER(@a);
END;
GO
SELECT dbo.to_upper('abcde');
GO
接下来,增加别名类型的长度。
sp_rename 'mytype', 'myoldtype', 'userdatatype';
GO
CREATE TYPE mytype FROM NVARCHAR(10);
GO
函数参数仍使用旧类型,由于截断而失败。
SELECT name, TYPE_NAME(user_type_id)
FROM sys.parameters
WHERE object_id = OBJECT_ID('dbo.to_upper');
GO
SELECT dbo.to_upper('abcdefgh'); -- Fails because of truncation
GO
刷新函数以绑定到重命名的类型。
EXEC sys.sp_refreshsqlmodule 'dbo.to_upper';
函数参数现在绑定到正确的类型,并且语句正常工作。
SELECT name, TYPE_NAME(user_type_id)
FROM sys.parameters
WHERE object_id = OBJECT_ID('dbo.to_upper');
GO
SELECT dbo.to_upper('abcdefgh');
GO
B. 刷新数据库级 DDL 触发器
下例刷新一个数据库级 DDL 触发器。
USE AdventureWorks2022;
GO
EXEC sys.sp_refreshsqlmodule
@name = 'ddlDatabaseTriggerLog',
@namespace = 'DATABASE_DDL_TRIGGER';
GO
°C 刷新服务器级 DDL 触发器
下例刷新一个服务器级 DDL 触发器。
USE master;
GO
EXEC sys.sp_refreshsqlmodule
@name = 'ddl_trig_database',
@namespace = 'SERVER_DDL_TRIGGER';
GO