REVERT (Transact-SQL)

將執行內容切換回最後一個 EXECUTE AS 陳述式的呼叫者。

主題連結圖示Transact-SQL 語法慣例

語法

REVERT
    [ WITH COOKIE = @varbinary_variable ]

引數

  • WITH COOKIE = @varbinary\_variable
    指定在對應 EXECUTE AS 獨立陳述式中建立的 Cookie。@varbinary_variable 是 varbinary(100)。

備註

您可以在模組 (例如,預存程序或使用者自訂函數,或是獨立陳述式) 中指定 REVERT。如果 REVERT 是在模組內部指定,則只能用於模組中定義的 EXECUTE AS 陳述式。例如,下列預存程序會發出後面接有 REVERT 的 EXECUTE AS 陳述式。

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; 

在 usp_myproc 內定義的 REVERT 陳述式,會切換模組中的執行內容集,但不會影響模組外的執行內容集。換句話說,工作階段的執行內容仍然設為 login1。

當 REVERT 被指定為獨立陳述式時,則會套用至批次或工作階段內定義的 EXECUTE AS 陳述式。如果對應的 EXECUTE AS 陳述式含有 WITH NO REVERT 子句,REVERT 就沒有任何影響。此時,在工作階段卸除之前,執行內容仍然有效。

用來設定工作階段執行環境的 EXECUTE AS 陳述式可包含選擇性子句 WITH NO REVERT COOKIE = @varbinary\_variable。當這個陳述式執行時,Database Engine 會將 Cookie 傳遞給 @varbinary\_variable。只有當呼叫的 REVERT WITH COOKIE = @varbinary\_variable 陳述式包含正確的 @varbinary\_variable 值時,該陳述式所設定的執行環境才能還原到先前的環境。

這項機制在使用連接共用的環境中相當有用。連接共用是一組資料庫連接的維護,這些連接是供多位使用者的應用程式重複使用。由於傳到 @varbinary\_variable 的值,只有 EXECUTE AS 陳述式的呼叫者才知道 (本例是指應用程式),因此呼叫者可以保證叫用應用程式的使用者,不能變更他們所建立的執行內容。在還原執行內容之後,應用程式就可以將內容切換回另一個主體。

權限

不需要任何權限。

範例

A. 使用 EXECUTE AS 和 REVERT 來切換內容

下列範例會利用多個主體來建立一個內容執行堆疊。然後再用 REVERT 陳述式,將執行內容重設為前一個呼叫者。REVERT 陳述式在上移堆疊時會執行多次,直到執行內容設為原始呼叫者為止。

USE AdventureWorks;
GO
-- Create two temporary principals.
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
GO
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 the temporary principals.
DROP LOGIN login1;
DROP LOGIN login2;
DROP USER user1;
DROP USER user2;
GO

下列範例會將工作階段的執行內容設為指定使用者,並且指定 WITH NO REVERT COOKIE = @varbinary\_variable 子句。REVERT 陳述式必須指定傳給 EXECUTE AS 陳述式中的 @cookie 變數值,才能順利將內容還原回呼叫者。若要執行這個範例,則必須具備在範例 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