共用方式為


EXECUTE AS 子句 (Transact-SQL)

適用於:SQL ServerAzure SQL 資料庫Azure SQL 受控執行個體

在 SQL Server 中,您可以定義下列使用者自訂模組的執行內容:函數 (內嵌資料表值函式除外)、程序、佇列和觸發程序。

您可以指定執行模組的內容,來控制資料庫引擎是使用哪一個使用者帳戶,以驗證該模組參考之物件的權限。 此舉可以在使用者自訂模組以及其所參考物件之間的物件鏈結管理權限時,提供更大的彈性和控制權。 您只需要授與模組本身的權限給使用者即可,不必授與使用者參考物件的明確權限。 只有執行模組的使用者,必須具有模組所存取之物件的權限。

Transact-SQL 語法慣例

Syntax

本節描述 的 EXECUTE ASSQL Server 語法。

函式(內嵌資料表值函式除外)、預存程式和 DML 觸發程式:

{ EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' }

具有資料庫範圍的 DDL 觸發程式:

{ EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' }

具有伺服器範圍和登入觸發程式的 DDL 觸發程式:

{ EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' }

佇列:

{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }

引數

CALLER

指定模組內的陳述式,是在該模組的呼叫者內容當中執行。 執行該模組的使用者,不僅必須具有模組本身的適當權限,也必須具有該模組所參考之任何資料庫物件的權限。

CALLER 是佇列以外的所有模組的預設值,與 SQL Server 2005 (9.x) 行為相同。

CALLER無法在或 CREATE QUEUE 語句中ALTER QUEUE指定。

SELF

EXECUTE AS SELF 相當於 EXECUTE AS <user_name>,其中指定的使用者是建立或改變模組的人員。 建立或修改模組的人員的實際使用者標識符會儲存在 或 execute_as_principal_id 目錄檢視的數據sys.sql_modulessys.service_queues行中。

SELF 是佇列的預設值。

注意

若要變更目錄檢視中execute_as_principal_id數據行的使用者識別碼sys.service_queues,您必須在 語句中EXECUTE AS明確指定ALTER QUEUE設定。

OWNER

指定模組內的語句會在模組目前擁有者的內容中執行。 如果模組沒有指定的擁有者,則會使用模組架構的擁有者。 OWNER 無法針對 DDL 或登入觸發程式指定。

重要

OWNER 必須對應至單一帳戶,而且不能是角色或群組。

'user_name'

指定模組內的陳述式,在 user_name 指定的使用者內容中執行。 會針對 user_name 來驗證模組內任何物件的權限。 無法針對具有伺服器範圍或登入觸發程式的 DDL 觸發程式指定user_name。 請改為使用 login_name

user_name 必須存在於目前資料庫中,而且必須是單一帳戶。 user_name不能是群組、角色、憑證、金鑰或內建帳戶,例如NT AUTHORITY\LocalServiceNT AUTHORITY\NetworkServiceNT AUTHORITY\LocalSystem

執行內容的使用者標識碼會儲存在元數據中,而且可以在 或 execute_as_principal_id 目錄檢視的數據sys.sql_modulessys.assembly_modules行中檢視。

'login_name'

指定模組內的陳述式,在 login_name 所指定的 SQL Server 登入內容中執行。 會針對 login_name 來驗證模組內任何物件的權限。 login_name 只能針對具有伺服器範圍的 DDL 觸發程序或登入觸發程序來指定。

login_name不能是群組、角色、憑證、金鑰或內建帳戶,例如NT AUTHORITY\LocalServiceNT AUTHORITY\NetworkServiceNT AUTHORITY\LocalSystem

備註

資料庫引擎如何評估模組內參考物件的權限,會隨著呼叫物件和所參考物件之間的擁有權鏈結而不同。 在舊版的 SQL Server 中,擁有權鏈結是唯一可以避免授與參考物件存取權給呼叫使用者的方法。

擁有權鏈結具有下列限制:

  • 只適用於 DML 語句: SELECTINSERTUPDATEDELETE
  • 呼叫和被呼叫物件的擁有者必須相同。
  • 不適用於模組內的動態查詢。

無論模組指定的執行內容為何,下列動作一定適用:

  • 執行模組時,資料庫引擎 會先確認執行模組的使用者具有EXECUTE模組的許可權。

  • 擁有權鏈結規則仍然適用。 換句話說,如果呼叫和被呼叫物件的擁有者一樣,就不會檢查基礎物件的任何權限。

當使用者執行已指定在 以外的 CALLER內容中執行的模組時,會檢查使用者執行模組的許可權,但模組所存取之物件的其他許可權檢查會針對 子句中指定的 EXECUTE AS 使用者帳戶執行。 執行該模組的使用者,實際上就是模擬指定的使用者。

模組子 EXECUTE AS 句中指定的內容只有在模組執行期間才有效。 模組執行完畢之後,內容便還原給呼叫者。

指定使用者或登入名稱

在修改模組以在另一個內容下執行之前,無法卸除模組子句中指定的 EXECUTE AS 資料庫用戶或伺服器登入。

子句中指定的EXECUTE AS使用者或登入名稱必須分別以 或 sys.database_principals中的sys.server_principals主體存在,否則建立或改變模組作業會失敗。 另外,建立或變更模組的使用者,必須具有該主體的 IMPERSONATE 權限。

如果使用者透過 Windows 群組成員資格隱含存取 SQL Server 的資料庫或實例,當模組存在下列其中一項需求時,就會隱含地建立 子句中指定的 EXECUTE AS 使用者:

  • 指定的使用者或登入,是 sysadmin 固定伺服器角色的成員。
  • 建立該模組的使用者,有權建立主體。

如果這兩項需求都不符合,則建立模組作業便會失敗。

重要

如果 SQL Server (MSSQLSERVER) 服務是以本機帳戶執行(本地服務或本機使用者帳戶),則它不會有許可權取得 子句中所 EXECUTE AS 指定之 Windows 網域帳戶的群組成員資格。 此舉會使模組執行作業失敗。

例如,假設有下列情況:

  • CompanyDomain\SQLUsers group 可以存取 Sales 資料庫。

  • CompanyDomain\SqlUser1 是的成員 SQLUsers ,因此可以存取 Sales 資料庫。

  • 建立或變更該模組的使用者,有權建立主體。

在執行下列 CREATE PROCEDURE 陳述式時,CompanyDomain\SqlUser1 會隱含建立為 Sales 資料庫中的資料庫主體。

USE Sales;
GO

CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT USER_NAME();
GO

使用 EXECUTE AS CALLER 獨立語句

EXECUTE AS CALLER使用模組內的獨立語句,將執行內容設定為模組的呼叫端。

假設下列預存程序是由 SqlUser2 呼叫。

CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'SqlUser1'
AS
SELECT USER_NAME(); -- Shows execution context is set to SqlUser1.
EXECUTE AS CALLER;

SELECT USER_NAME(); -- Shows execution context is set to SqlUser2, the caller of the module.
REVERT;

SELECT USER_NAME(); -- Shows execution context is set to SqlUser1.
GO

使用 EXECUTE AS 定義自訂許可權集合

當您想要定義自定義許可權集合時,指定模組的執行內容會很有用。 例如,某些動作,例如 TRUNCATE TABLE 沒有可授與的許可權。 藉由將 TRUNCATE TABLE 語句併入模組內,並指定該模組以具有改變數據表許可權的使用者身分執行,您可以將許可權擴充為將數據表截斷至您在模組上授 EXECUTE 與許可權的使用者。

若要檢視具有指定執行環境定義的模組定義,請使用 sys.sql_modules 型錄視圖。

最佳做法

指定一個登入或使用者,它具有執行在模組中定義的作業時所需要的最低權限。 例如,除非需要這些許可權,否則請勿指定資料庫擁有者帳戶。

權限

若要執行以 EXECUTE AS指定的模組,呼叫端必須具有 EXECUTE 模組的許可權。

若要執行指定的 CLR 模組 EXECUTE AS ,以存取另一個資料庫或伺服器中的資源,目標資料庫或伺服器必須信任模組來源資料庫的驗證器 (來源資料庫)。

若要在建立或修改模組時指定 EXECUTE AS 子句,您必須擁有 IMPERSONATE 指定主體的許可權,以及建立模組的許可權。 您永遠都可以模擬自己本身。 如果未指定或 EXECUTE AS CALLER 指定任何執行內容, IMPERSONATE 則不需要許可權。

若要指定 可透過 Windows 群組成員資格隱含存取資料庫的login_nameuser_name ,您必須具有 CONTROL 資料庫的許可權。

範例

以下範例在 AdventureWorks2025 資料庫中建立一個儲存程序,並將執行上下文指派給 OWNER

CREATE PROCEDURE HumanResources.uspEmployeesInDepartment
@DeptValue INT
WITH EXECUTE AS OWNER
AS
SET NOCOUNT ON;
SELECT e.BusinessEntityID,
       c.LastName,
       c.FirstName,
       e.JobTitle
FROM Person.Person AS c
     INNER JOIN HumanResources.Employee AS e
         ON c.BusinessEntityID = e.BusinessEntityID
     INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
         ON e.BusinessEntityID = edh.BusinessEntityID
WHERE edh.DepartmentID = @DeptValue
ORDER BY c.LastName, c.FirstName;
GO

-- Execute the stored procedure by specifying department 5.
EXECUTE HumanResources.uspEmployeesInDepartment 5;
GO