REVERT can be specified within a module such as a stored procedure or user-defined function, or as a stand-alone statement. When specified inside a module, REVERT is applicable only to EXECUTE AS statements defined in the module. For example, the following stored procedure issues an EXECUTE AS statement followed by a REVERT statement.
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
Assume that in the session in which the stored procedure is run, the execution context of the session is explicitly changed to login1, as shown in the following example.
-- Sets the execution context of the session to 'login1'.
EXECUTE AS LOGIN = 'login1';
GO
EXECUTE dbo.usp_myproc;
The REVERT statement that is defined inside usp_myproc switches the execution context set inside the module, but does not affect the execution context set outside the module. That is, the execution context for the session remains set to login1.
When specified as a standalone statement, REVERT applies to EXECUTE AS statements defined within a batch or session. REVERT has no effect if the corresponding EXECUTE AS statement contains the WITH NO REVERT clause. In this case, the execution context remains in effect until the session is dropped.
Using REVERT WITH COOKIE
The EXECUTE AS statement that is used to set the execution context of a session can include the optional clause WITH NO REVERT COOKIE = @varbinary_variable. When this statement is run, the SQL Server 2005 Database Engine passes the cookie to @varbinary_variable. The execution context set by that statement can only be reverted to the previous context if the calling REVERT WITH COOKIE = @varbinary_variable statement contains the correct @varbinary_variable value.
This mechanism is useful in an environment in which connection pooling is used. Connection pooling is the maintenance of a group of database connections for reuse by applications across multiple end users. Because the value passed to @varbinary_variable is known only to the caller of the EXECUTE AS statement (in this case, the application), the caller can guarantee that the execution context they establish cannot be changed by the end user that invokes the application. After the execution context is reverted, the application can switch context to another principal.