適用対象:SQL Server
Azure SQL データベース
Azure SQL Managed Instance
Azure Synapse Analytics
実行コンテキストを最後の EXECUTE AS 文の呼び出し元に戻します。
構文
REVERT
[ WITH COOKIE = @varbinary_variable ]
引数
COOKIE付き = @varbinary_variable
対応する EXECUTE AS スタンドアロン文で作成されたクッキーを指定します。 @varbinary_variable は varbinary(100) です。
注釈
REVERT は、ストアドプロシージャやユーザー定義関数などのモジュール内で指定することも、単独の文としても定義できます。 モジュール内で指定された場合、 REVERT はモジュール内で定義された EXECUTE AS 文にのみ適用されます。 たとえば、次のストアド プロシージャでは、EXECUTE AS ステートメントの後に REVERT ステートメントが実行されます。
CREATE PROCEDURE dbo.usp_myproc
WITH EXECUTE AS CALLER
AS
SELECT SUSER_NAME(), USER_NAME();
EXECUTE AS USER = 'guest';
SELECT SUSER_NAME(), USER_NAME();
REVERT;
SELECT SUSER_NAME(), USER_NAME();
GO
次の例のように、ストアド プロシージャが実行されるセッションで、セッションの実行コンテキストが明示的に login1 に変更されるとします。
-- Sets the execution context of the session to 'login1'.
EXECUTE AS LOGIN = 'login1';
GO
EXECUTE dbo.usp_myproc;
この場合、REVERT 内で定義された usp_myproc ステートメントでは、モジュール内で設定されている実行コンテキストが切り替えられますが、モジュール外で設定されている実行コンテキストに影響はありません。 つまり、セッションの実行コンテキストは login1 のままです。
単独の文として指定された場合、 REVERT バッチやセッション内で定義された文 EXECUTE AS に適用されます。
REVERT 対応する EXECUTE AS 文にWITH NO REVERT 節が含まれている場合、は影響しません。 この場合、実行コンテキストはセッションが削除されるまで有効です。
REVERT COOKIEを使っている
セッションの実行コンテキストを設定するために使われる EXECUTE AS 文には、オプションの節 WITH NO REVERT COOKIE = @*varbinary_variable*を含めることができます。 この文を実行すると、データベース エンジンはクッキーを @*varbinary_variable* に渡します。 その文によって設定される実行コンテキストは、呼び出し REVERT WITH COOKIE = @varbinary_variable 文が正しい *@varbinary_variable* 値を含む場合にのみ前のコンテキストに戻せます。
このメカニズムは、接続プールが使用される環境で役立ちます。 接続プールには、複数のエンド ユーザーがアプリケーションで再利用するデータベース接続のグループが管理されています。
*@varbinary_variable*に渡される値はEXECUTE AS文の呼び出し元(この場合はアプリケーション)のみが知っているため、呼び出し者は設定した実行コンテキストがアプリケーションを呼び出すエンドユーザーによって変更されないことを保証できます。 実行コンテキストが戻された後、アプリケーションではコンテキストを他のプリンシパルに切り替えることができます。
アクセス許可
権限は必要ありません。
例
A. EXECUTE ASとREVERTを使ってコンテキストを切り替える
次の例では、複数のプリンシパルを使用してコンテキスト実行スタックを作成した後、 REVERT ステートメントを使用して実行コンテキストを以前のコンテキストに戻します。 REVERT ステートメントは、実行コンテキストが最初の呼び出し元に設定されるまで、スタックの上層に向かって複数回実行されます。
このサンプルの場合、 master データベースで新しいログインを作成してください:
-- Create two temporary principals.
CREATE LOGIN login1 WITH PASSWORD = '<strong password>';
CREATE LOGIN login2 WITH PASSWORD = '<strong password>';
GO
次に、目的のテストやサンプルデータベースに接続します。例えば AdventureWorks2025:
CREATE USER user1 FOR LOGIN login1;
CREATE USER user2 FOR LOGIN login2;
GO
-- Give IMPERSONATE permissions on user2 to user1
-- so that user1 can successfully set the execution context to user2.
GRANT IMPERSONATE ON USER:: user2 TO user1;
GO
-- Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
-- Set the execution context to login1.
EXECUTE AS LOGIN = 'login1';
-- Verify that the execution context is now login1.
SELECT SUSER_NAME(), USER_NAME();
-- Login1 sets the execution context to login2.
EXECUTE AS USER = 'user2';
-- Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
-- The execution context stack now has three principals: the originating caller, login1, and login2.
-- The following REVERT statements will reset the execution context to the previous context.
REVERT;
-- Display the current execution context.
SELECT SUSER_NAME(), USER_NAME();
REVERT;
-- Display the current execution context.
SELECT SUSER_NAME(), USER_NAME();
--Remove temporary principals.
DROP USER user1;
DROP USER user2;
GO
masterデータベースでは:
DROP LOGIN login1;
DROP LOGIN login2;
B. WITH COOKIE 句を使用する
以下の例では、セッションの実行コンテキストを指定されたユーザーに設定し、WITH NO REVERT COOKIE = @varbinary_variable 節を指定します。 コンテキストを正常に呼び出し元に戻すには、REVERT ステートメントで、@cookie ステートメントの EXECUTE AS 変数に渡される値を指定する必要があります。 この例を実行するには、例 A で作成したログイン login1 とユーザー user1 が存在している必要があります。
DECLARE @cookie VARBINARY(100);
EXECUTE AS USER = 'user1' WITH COOKIE INTO @cookie;
-- Store the cookie somewhere safe in your application.
-- Verify the context switch.
SELECT SUSER_NAME(), USER_NAME();
--Display the cookie value.
SELECT @cookie;
GO
-- Use the cookie in the REVERT statement.
DECLARE @cookie VARBINARY(100);
-- Set the cookie value to the one from the SELECT @cookie statement.
SET @cookie = <value from the SELECT @cookie statement>;
REVERT WITH COOKIE = @cookie;
-- Verify the context switch reverted.
SELECT SUSER_NAME(), USER_NAME();
GO