sp_refreshsqlmodule (Transact-SQL)

適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance 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 トリガーの名前。 @namenvarchar(776) で、既定値はありません。 @name 共通言語ランタイム (CLR) ストアド プロシージャまたは CLR 関数にすることはできません。 @name スキーマ バインドにすることはできません。 @name はマルチパート識別子にすることができますが、現在のデータベース内のオブジェクトのみを参照できます。

[ @namespace = ] N'namespace'

指定したモジュールのクラス。 @namespacenvarchar(20) で、既定値は OBJECT です。 @nameが DDL トリガーの場合は、@namespaceが必要です。 有効な入力は DATABASE_DDL_TRIGGERSERVER_DDL_TRIGGER です。

リターン コードの値

0 (成功) または 0 以外の数値 (失敗)。

解説

sp_refreshsqlmodule は、モジュールの定義に影響を与えるモジュールの基になるオブジェクトに変更が加えられたときに実行する必要があります。 そうしないと、クエリまたは呼び出し時に、モジュールによって予期しない結果が生成される可能性があります。 ビューを更新するには、同じ結果で sp_refreshsqlmodule または sp_refreshview を使用できます。

sp_refreshsqlmodule は、オブジェクトに関連付けられている権限、拡張プロパティ、または SET オプションには影響しません。

サーバー レベルの DDL トリガーを更新するには、任意のデータベースのコンテキストからこのストアド プロシージャを実行します。

Note

オブジェクトに関連付けられている署名は、sp_refreshsqlmodule の実行時に削除されます。

アクセス許可

モジュールに対する ALTER 権限、およびオブジェクトによって参照される CLR ユーザー定義型と XML スキーマ コレクションに対する REFERENCES 権限が必要です。 指定したモジュールがデータベース レベルの DDL トリガーである場合は、現在のデータベース ALTER ANY DATABASE DDL TRIGGER アクセス許可が必要です。 指定したモジュールがサーバー レベルの DDL トリガーである場合は、 CONTROL SERVER アクセス許可が必要です。

さらに、 EXECUTE AS 句で定義されているモジュールの場合は、指定したプリンシパルに IMPERSONATE アクセス許可が必要です。 一般に、オブジェクトを更新しても、 EXECUTE AS プリンシパルは変更されません。ただし、モジュールが EXECUTE AS USER で定義されていて、プリンシパルのユーザー名がモジュールの作成時にユーザーとは別のユーザーに解決されるようになった場合を除きます。

この記事の Transact-SQL コード サンプルは AdventureWorks2022 または AdventureWorksDW2022 サンプル データベースを使用します。このサンプル データベースは、Microsoft SQL Server サンプルとコミュニティ プロジェクトのホーム ページからダウンロードできます。

A. ユーザー定義関数を更新する

次の例では、ユーザー定義関数を更新します。 この例では、エイリアス データ型、mytype、およびmytypeを使用するユーザー定義関数 (to_upper) を作成します。 次に、 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