REVERT (Transact-SQL)
將執行內容切換回最後一個 EXECUTE AS 陳述式的呼叫者。
- 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。在執行這個陳述式時,SQL Server 2005 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
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

