REVERT (Transact-SQL)
將執行內容切換回最後一個 EXECUTE AS 陳述式的呼叫者。
語法
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 就沒有任何影響。此時,在工作階段卸除之前,執行內容仍然有效。
使用 REVERT WITH COOKIE
用來設定工作階段執行內容的 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 AdventureWorks2008R2;
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
B. 使用 WITH COOKIE 子句
下列範例會將工作階段的執行內容設為指定使用者,並且指定 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