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.. 刷新使用错误中指定的类型的模块的元数据可能会解决问题。

Transact-SQL 语法约定

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_TRIGGERSERVER_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 代码示例使用 AdventureWorks2022AdventureWorksDW2022 示例数据库,可从 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