共用方式為


EXECUTE (Transact-SQL)

適用於:sql Server Azure SQL 資料庫 Azure SQL 受控執行個體Azure Synapse Analytics Platform System (PDW) SQL 分析端點Microsoft網狀架構倉儲中的 Microsoft FabricSQL 資料庫Microsoft網狀架構

在 Transact-SQL 批次或下列其中一個模組中執行命令字串或字元字串:系統預存程序、使用者定義預存程序、CLR 預存程序、純量值使用者定義函數或擴充預存程序。 EXECEXECUTE 語句可用來將傳遞命令傳送至連結的伺服器。 另外,執行字串或命令所在的內容也可以明確設定。 您可以使用 WITH RESULT SETS 選項來定義結果集的元數據。

重要

使用字元字串呼叫 EXECUTE 之前,請先驗證字元字串。 永不執行從尚未驗證的使用者輸入建構的命令。

Transact-SQL 語法慣例

Syntax

下列程式代碼區塊顯示 SQL Server 2019 (15.x) 和更新版本的語法。 或者,請改為參閱 SQL Server 2017 和更早版本中的語法

SQL Server 2019 和更新版本的語法。

-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable [ OUTPUT ]
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[ ; ]

-- Execute a character string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS { LOGIN | USER } = ' name ' ]
[ ; ]

-- Execute a pass-through command against a linked server
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'command_string [ ? ]' } [ + ...n ]
        [ { , { value | @variable [ OUTPUT ] } } [ ...n ] ]
    )
    [ AS { LOGIN | USER } = ' name ' ]
    [ AT linked_server_name ]
    [ AT DATA_SOURCE data_source_name ]
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

<result_sets_definition> ::=
{
    (
         { column_name
           data_type
         [ COLLATE collation_name ]
         [ NULL | NOT NULL ] }
         [,...n ]
    )
    | AS OBJECT
        [ db_name . [ schema_name ] . | schema_name . ]
        {table_name | view_name | table_valued_function_name }
    | AS TYPE [ schema_name.]table_type_name
    | AS FOR XML
}

下列程式代碼區塊顯示 SQL Server 2017 (14.x) 和舊版中的語法。 或者,請改為參閱 SQL Server 2019 中的語法

SQL Server 2017 和舊版的語法。

-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable [ OUTPUT ]
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[ ; ]

-- Execute a character string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS { LOGIN | USER } = ' name ' ]
[ ; ]

-- Execute a pass-through command against a linked server
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'command_string [ ? ]' } [ + ...n ]
        [ { , { value | @variable [ OUTPUT ] } } [ ...n ] ]
    )
    [ AS { LOGIN | USER } = ' name ' ]
    [ AT linked_server_name ]
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

<result_sets_definition> ::=
{
    (
         { column_name
           data_type
         [ COLLATE collation_name ]
         [ NULL | NOT NULL ] }
         [,...n ]
    )
    | AS OBJECT
        [ db_name . [ schema_name ] . | schema_name . ]
        {table_name | view_name | table_valued_function_name }
    | AS TYPE [ schema_name.]table_type_name
    | AS FOR XML
}

In-Memory OLTP 的語法。

-- Execute a natively compiled, scalar user-defined function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
<execute_option>::=
{
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

Azure SQL Database 的語法。

-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name  | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable [ OUTPUT ]
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH RECOMPILE ]
    }
[ ; ]

-- Execute a character string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS {  USER } = ' name ' ]
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

<result_sets_definition> ::=
{
    (
         { column_name
           data_type
         [ COLLATE collation_name ]
         [ NULL | NOT NULL ] }
         [,...n ]
    )
    | AS OBJECT
        [ db_name . [ schema_name ] . | schema_name . ]
        {table_name | view_name | table_valued_function_name }
    | AS TYPE [ schema_name.]table_type_name
    | AS FOR XML
}

Azure Synapse Analytics 和平行處理數據倉儲的語法。

-- Execute a stored procedure
[ { EXEC | EXECUTE } ]
    procedure_name
        [ { value | @variable [ OUT | OUTPUT ] } ] [ ,...n ]
[ ; ]

-- Execute a SQL string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'tsql_string' } [ +...n ] )
[ ; ]

Microsoft Fabric 的語法。

-- Execute a stored procedure
[ { EXEC | EXECUTE } ]
    procedure_name
        [ { value | @variable [ OUT | OUTPUT ] } ] [ ,...n ]
        [ WITH <execute_option> [ ,...n ] ]  }
[ ; ]

-- Execute a SQL string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'tsql_string' } [ +...n ] )
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

引數

@return_status

選擇性的整數變數,可儲存模組的傳回狀態。 此變數必須在批次、預存程式或函式中宣告,才能在 EXECUTE 語句中使用。

當用來叫用純量值使用者定義函數時,@return_status 變數可以是任何純量數據類型。

module_name

要呼叫之預存程式或純量值用戶定義函數的完整或非完整名稱。 模組名稱必須符合識別碼的規則。 無論伺服器定序為何,擴充預存程序的名稱一定有大小寫區分。

如果執行模組的用戶擁有模組,或具有適當的許可權,可以在另一個資料庫中建立的模組執行。 如果執行某個模組的使用者,具有適當的權限可以使用該伺服器 (遠端存取),以及在該資料庫中執行該模組,就可以在另一個執行 SQL Server 的伺服器上執行該模組。 如果指定了伺服器名稱,但沒有指定資料庫名稱,則 SQL Server 資料庫引擎會在該使用者的預設資料庫中尋找該模組。

;number

選擇性整數,用來將相同名稱的程式分組。 此參數不會用於擴充預存程式。

注意

SQL Server 的未來版本將移除此功能。 請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。

如需程式群組的詳細資訊,請參閱 CREATE PROCEDURE

@module_name_var

代表模組名稱的本機定義變數名稱。

這可以是保存原生編譯純量使用者定義函數名稱的變數。

@parameter

module_name的參數,如模組中所定義。 參數名稱前面必須加上 at 符號 (@)。 搭配 @parameter_name = 格式使用時,參數名稱和常數不必依照模組中定義的順序提供。 不過,如果 @parameter_name = 表單用於任何參數,則必須用於所有後續參數。

依預設,參數可為 Null。

value

要傳遞至模組或傳遞命令的參數值。 如果未指定參數名稱,則必須依照模組中定義的順序提供參數值。

在對連結伺服器執行傳遞命令時,參數值的順序會隨著連結伺服器的 OLE DB 提供者而不同。 大部分的 OLE DB 提供者,都會將值由左到右繫結到參數。

如果參數值是物件名稱、字元字串或者由資料庫名稱或結構描述名稱所限定,則必須以單引號括住整個名稱。 如果參數值是關鍵字,則必須以雙引號括住關鍵字。

如果您傳遞的單一單字不是以 @開頭,則不會以引號括住 (例如,如果您忘記參數名稱上的 @),該字會被視為 nvarchar 字元串,儘管遺漏引號。

如果預設值是在模組中定義,使用者就可以直接執行該模組,不必指定參數。

預設值也可以 NULL。 一般而言,模組定義會指定參數值 NULL時應該採取的動作。

@variable

儲存參數或傳回參數的變數。

OUTPUT

指定讓模組或命令字串傳回參數。 模組或命令字串中的比對參數也必須使用 關鍵詞 OUTPUT來建立。 當您把資料指標變數當做參數使用時,請使用這個關鍵字。

如果 定義為針對連結伺服器執行的模組 OUTPUT,則 OLE DB 提供者所執行之對應 @parameter 的任何變更會複製到模組執行結束時的變數。

如果使用 OUTPUT 參數,且意圖是在呼叫批次或模組內的其他語句中使用傳回值,則必須以變數的形式傳遞參數的值,例如 @parameter = @variable。 您無法為模組中未定義為 OUTPUT 參數的參數指定 OUTPUT 來執行模組。 常數無法使用 OUTPUT傳遞至模組;return 參數需要變數名稱。 在執行該程序之前,必須先宣告該變數的資料類型,並且指定一個值。

EXECUTE 用於遠端預存程式,或針對連結的伺服器執行傳遞命令時,OUTPUT 參數不能是任何大型物件 (LOB) 資料類型。

傳回參數可以是 LOB 資料類型以外的任何資料類型。

DEFAULT

提供模組所定義的參數預設值。 當模組預期參數的值沒有定義的預設值,而且遺漏參數或指定了 DEFAULT 關鍵詞時,就會發生錯誤。

@string_variable

局部變數的名稱。 @string_variable 可以是任何 charvarcharncharnvarchar 數據類型。 其中包含 (max) 資料類型在內。

[N]'tsql_string'

常數位串。 tsql_string 可以是任何 nvarcharvarchar 資料類型。 如果包含 ,字串會解譯為 nvarchar 數據類型

AS context_specification

指定執行陳述式的內容。

LOGIN

指定您要模擬的內容是登入。 模擬範圍是伺服器。

USER

指定您要模擬的內容是目前資料庫中的使用者。 模擬範圍僅限於目前資料庫。 內容切換至資料庫使用者不會繼承該使用者的伺服器層級許可權。

重要

當內容切換至資料庫使用者為使用中時,任何存取資料庫外部資源的嘗試都會使語句失敗。 這包括 USE <database> 語句、分散式查詢,以及使用三部分或四部分標識元參考另一個資料庫的查詢。

'name'

有效的使用者或登入名稱。 名稱 自變數必須是 sysadmin 固定伺服器角色的成員,或分別存在於 sys.database_principalssys.server_principals中。

這個自變數不能是內建帳戶,例如 NT AUTHORITY\LocalServiceNT AUTHORITY\NetworkServiceNT AUTHORITY\LocalSystem

如需詳細資訊,請參閱本文稍後的 指定使用者或登入名稱

[N]'command_string'

常數位符串,包含要傳遞至連結伺服器的命令。 如果包含 ,字串會解譯為 nvarchar 數據類型

[?]

指出在 <arg-list> 語句中使用的傳遞命令 EXECUTE ('...', <arg-list>) AT <linkedsrv> 中提供值的參數。

AT linked_server_name

指定 command_stringlinked_server_name 執行,並將結果 (若有) 傳回用戶端。 linked_server_name 必須參考本機伺服器中現有的連結伺服器定義。 連結伺服器是利用 sp_addlinkedserver 所定義。

  • WITH <execute_option>

    可能的執行選項。 無法在 RESULT SETS 語句中指定 INSERT...EXECUTE 選項。

AT DATA_SOURCE data_source_name

適用於:SQL Server 2019 (15.x) 和更新版本。

指定 command_string 是對 data_source_name 執行,並會將結果 (若有的話) 傳回用戶端。 data_source_name 必須參考資料庫中現有的 EXTERNAL DATA SOURCE 定義。 僅支援指向 SQL Server 的資料來源。 此外,支援指向計算集區、數據集區或存放集區的SQL Server 巨量數據叢集數據源。 資料來源是透過使用 CREATE EXTERNAL DATA SOURCE 來定義。

  • WITH <execute_option>

    可能的執行選項。 無法在 RESULT SETS 語句中指定 INSERT...EXECUTE 選項。

    詞彙 定義
    RECOMPILE 在執行模組之後,強制編譯、使用和捨棄新計畫。 如果模組有現有的查詢計劃,此計劃會保留在快取中。

    如果您要提供的參數是非典型參數,或數據已大幅變更,請使用此選項。 此選項不會用於擴充預存程式。 我們建議您謹慎使用這個選項,因為它很昂貴。

    注意: 呼叫使用 WITH RECOMPILE 語法的預存程式時,您無法使用 OPENDATASOURCE。 指定四部分物件名稱時,會忽略 WITH RECOMPILE 選項。

    注意:原生編譯的純量使用者定義函式不支援RECOMPILE。 如果您需要重新編譯,請使用 sp_recompile
    RESULT SETS UNDEFINED 此選項不保證傳回結果,且未提供任何定義。 如果傳回任何結果或未傳回結果,陳述式會正確無誤地執行。 如果未提供result_sets_option,則 RESULT SETS UNDEFINED 是預設行為。

    針對解譯的純量使用者定義函式,以及原生編譯的純量使用者定義函式,此選項無法運作,因為函式永遠不會傳回結果集。

    適用於:SQL Server 2012 (11.x) 和更新版本,以及 Azure SQL Database。
    RESULT SETS NONE 保證 EXECUTE 語句不會傳回任何結果。 如果傳回任何結果,會中止批次。

    針對解譯的純量使用者定義函式,以及原生編譯的純量使用者定義函式,此選項無法運作,因為函式永遠不會傳回結果集。

    適用於:SQL Server 2012 (11.x) 和更新版本,以及 Azure SQL Database。
    <result_sets_definition> 提供保證結果會如 result_sets_definition中所指定傳回。 針對傳回多個結果集的陳述式,請提供多個 result_sets_definition 區段。 將每個 result_sets_definition 括在括號中,並以逗號分隔。 如需詳細資訊,請參閱本文稍後的 <result_sets_definition>

    此選項對於原生編譯的純量使用者定義函數一律會產生錯誤,因為函數永遠不會傳回結果集。

    適用於:SQL Server 2012 (11.x) 和更新版本,以及 Azure SQL Database。

    <result_sets_definition> 描述執行語句所傳回的結果集。 result_sets_definition 的 子句具有下列意義:

    詞彙 定義
    { column_name data_type
    [ COLLATE collation_name ]
    [NULL |NOT NULL] }
    請參閱下表。
    db_name 包含數據表、檢視或數據表值函式的資料庫名稱。
    schema_name 擁有數據表、檢視或數據表值函式的架構名稱。
    table_name | view_name | table_valued_function_name 指定傳回的數據行是在名為的數據表、檢視或數據表值函式中指定的數據行。 AS 物件語法不支持數據表變數、臨時表和同義字。
    AS TYPE [ schema_name。 ]table_type_name 指定傳回的數據列是在數據表類型中指定的數據行。
    AS FOR XML 指定 EXECUTE 語句所呼叫之語句或預存程式所呼叫的 XML 結果會轉換成格式,就像由 SELECT ... FOR XML ... 語句所產生一樣。 會移除原始語句中類型指示詞的所有格式設定,而且傳回的結果就像沒有指定類型指示詞一樣。 AS FOR XML 不會將執行語句或預存程式的非 XML 表格式結果轉換成 XML。
    詞彙 定義
    column_name 每個資料行的名稱。 如果資料行數目不同於結果集,就會發生錯誤並且中止批次。 如果資料行名稱不同於結果集,傳回的資料行名稱會設為已定義的名稱。
    data_type 每個資料行的資料類型。 如果資料類型不同,則會隱含轉換成已定義的資料類型。 如果轉換失敗,則會中止批次。
    COLLATE collation_name 每個資料行的定序。 如果定序不符,則會嘗試隱含定序。 如果定序失敗,則會中止批次。
    NULL | NOT NULL 每個資料行的 Null 屬性。 如果定義的可為 Null 功能 NOT NULL 且傳回的數據包含 Null,就會發生錯誤並中止批次。 如果未指定,預設值會符合 ANSI_NULL_DFLT_ONANSI_NULL_DFLT_OFF 選項的設定。

    在執行期間傳回的實際結果集可能與使用下列其中一種方式使用 WITH RESULT SETS 子句所定義的結果不同:結果集數目、數據行數目、數據行名稱、nullability 和數據類型。 如果結果集數目不同,就會發生錯誤並且中止批次。

備註

您可以使用 或使用 @parameter_name = 來提供參數。 參數不是交易的一部分;因此,如果在稍後復原的交易中變更參數,則參數的值不會還原為先前的值。 傳回呼叫端的值一定是模組傳回時的值。

當一個模組呼叫另一個模組,或者參考 Common Language Runtime (CLR) 模組、使用者定義類型或彙總來執行 Managed 程式碼時,就會產生巢狀結構。 當呼叫的模組或 Managed 程式代碼參考開始執行時,巢狀層級會遞增,並在呼叫的模組或 Managed 程式代碼參考完成時遞減。 如果超過 32 個巢狀層級上限,完整的呼叫鏈便會失敗。 目前的巢狀層級會儲存在 @@NESTLEVEL 系統函式中。

因為遠端預存程式和擴充預存程式不在交易範圍內(除非在 BEGIN DISTRIBUTED TRANSACTION 語句內發出,或搭配各種組態選項使用時),因此透過呼叫執行的命令無法回復。 如需詳細資訊,請參閱 系統預存程式BEGIN DISTRIBUTED TRANSACTION

當您使用資料指標變數時,如果您執行傳遞具有配置給數據指標之數據指標之數據指標之數據指標的程式,就會發生錯誤。

如果語句是批次中的第一個模組,則不需要指定 EXECUTE 關鍵詞。

如需 CLR 預存程式的特定詳細資訊,請參閱 CLR 預存程式

搭配預存程式使用 EXECUTE

當您在語句是批次中的第一個預存程式時,您不需要指定 EXECUTE 關鍵詞。

SQL Server 系統預存程式從字元 sp_開始。 它們會實際儲存在 資源資料庫中,但邏輯上會顯示在每個系統和使用者定義資料庫的 sys 架構中。 當您在批次或模組內 (例如,使用者定義的預存程序或函數) 執行系統預存程序時,我們建議您以 sys 結構描述名稱來限定預存程序名稱。

SQL Server 系統擴充預存程式會從 xp_字元開始,這些程式會包含在 master 資料庫的 dbo 架構中。 當您在批次或模組內執行系統擴充預存程式時,例如使用者定義的預存程式或函式,建議您使用 master.dbo限定預存程式名稱。

當您在批次或模組內 (例如,使用者定義的預存程序或函數) 執行使用者定義的預存程序時,我們建議您以結構描述名稱來限定預存程序名稱。 不建議您將使用者定義預存程式命名為與系統預存程式同名。 如需執行預存程式的詳細資訊,請參閱 執行預存程式

搭配字元字串使用 EXECUTE

在 SQL Server 中,您可以指定 varchar(max)nvarchar(max) 資料類型,讓它接受最多達 2 GB 資料的字元字串。

資料庫內容中的變更只會持續到 EXECUTE 語句的結尾為止。 例如,執行下列語句中的 EXECUTE 之後,資料庫內容會 master

USE master;

EXECUTE ('USE AdventureWorks2022; SELECT BusinessEntityID, JobTitle FROM HumanResources.Employee;');

內容切換

您可以使用 AS { LOGIN | USER } = '<name>' 子句來切換動態陳述式的執行內容。 當內容切換被指定為 EXECUTE ('string') AS <context_specification> 時,內容切換的持續時間就限於目前所執行的查詢範圍內。

指定使用者或登入名稱

AS { LOGIN | USER } = '<name>' 中指定的使用者或登入名稱必須分別以主體的形式存在 sys.database_principalssys.server_principals,否則語句會失敗。 此外,必須在主體上授與 IMPERSONATE 許可權。 除非呼叫端是資料庫擁有者,或是 系統管理員 固定伺服器角色的成員,即使使用者透過 Windows 群組成員資格存取 SQL Server 的資料庫或實例,主體也必須存在。 例如,假設有下列情況:

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

  • CompanyDomain\SqlUser1SQLUsers 的成員,因此具有 Sales 資料庫的隱含存取權。

雖然 CompanyDomain\SqlUser1 可透過 SQLUsers 群組的成員資格存取資料庫,但是語句 EXECUTE @string_variable AS USER = 'CompanyDomain\SqlUser1' 失敗,因為 CompanyDomain\SqlUser1 不存在為資料庫中的主體。

最佳做法

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

權限

執行 EXECUTE 語句不需要許可權。 不過,在 EXECUTE 字串內參考的安全性實體上需要許可權。 例如,如果字串包含 INSERT 語句,則 EXECUTE 語句的呼叫端必須具有目標數據表的 INSERT 許可權。 即使模組中包含 EXECUTE 語句,也會在遇到語句 EXECUTE 時檢查許可權。

模組的 EXECUTE 許可權預設為模組的擁有者,他們可以將其轉移給其他使用者。 當您執行某個模組來執行字串時,將會檢查執行此模組之使用者內容中的權限,不過不會檢查建立模組之使用者內容中的權限。 不過,如果相同的用戶擁有呼叫模組和所呼叫的模組,則不會針對第二個模組執行 EXECUTE 許可權檢查。

如果模組存取其他資料庫物件,當您具有模組的 EXECUTE 許可權,且下列其中一個條件成立時,執行就會成功:

  • 模組會標示為 EXECUTE AS USEREXECUTE AS SELF,而模組擁有者具有參考對象的對應許可權。 如需模組內仿真的詳細資訊,請參閱 EXECUTE AS 子句

  • 模組會標示為 EXECUTE AS CALLER,而且您具有 對象的對應許可權。

  • 模組標示為 EXECUTE AS <user_name>,且 <user_name> 具有對象的對應許可權。

內容切換許可權

若要在登入上指定 EXECUTE AS,呼叫端必須具有指定登入名稱的 IMPERSONATE 許可權。 若要在資料庫使用者上指定 EXECUTE AS,呼叫者必須具有指定使用者名稱的 IMPERSONATE 許可權。 如果未指定任何執行內容,或指定 EXECUTE AS CALLER,則不需要 IMPERSONATE 許可權。

範例:SQL Server

本文中的 Transact-SQL 程式代碼範例會使用 AdventureWorks2022AdventureWorksDW2022 範例資料庫,您可以從 Microsoft SQL Server 範例和社群專案 首頁下載。

A. 使用 EXECUTE 傳遞單一參數

uspGetEmployeeManagers AdventureWorks2022 資料庫中的預存程式需要一個參數 (@EmployeeID)。 下列範例會將 uspGetEmployeeManagers 當做參數值來執行 Employee ID 6 預存程序。

EXECUTE dbo.uspGetEmployeeManagers 6;
GO

此變數可以在執行作業中明確命名:

EXECUTE dbo.uspGetEmployeeManagers @EmployeeID = 6;
GO

如果下列是批次或 sqlcmd 腳本中的第一個語句,則不需要 EXECUTE

dbo.uspGetEmployeeManagers 6;
GO

--Or
dbo.uspGetEmployeeManagers @EmployeeID = 6;
GO

B. 使用多個參數

下列範例會在 spGetWhereUsedProductID AdventureWorks2022 資料庫中執行預存程式。 它會傳遞兩個參數:第一個參數是產品標識符(819),而第二個參數 @CheckDatedatetime 值。

DECLARE @CheckDate AS DATETIME;
SET @CheckDate = GETDATE();

EXECUTE dbo.uspGetWhereUsedProductID 819, @CheckDate;
GO

C. 搭配變數使用 EXECUTE 'tsql_string'

下列範例會示範 EXECUTE 如何處理含有變數的動態建立字串。 這個範例會建立 tables_cursor 資料指標來保存一份 AdventureWorks2022 資料庫中所有使用者定義資料表的清單,然後再利用這份清單在資料表上重建所有的索引。

DECLARE tables_cursor CURSOR
    FOR SELECT s.name, t.name FROM sys.objects AS t
    INNER JOIN sys.schemas AS s ON s.schema_id = t.schema_id
    WHERE t.type = 'U';

OPEN tables_cursor;

DECLARE @schemaname AS sysname;
DECLARE @tablename AS sysname;

FETCH NEXT FROM tables_cursor INTO @schemaname, @tablename;

WHILE (@@FETCH_STATUS <> -1)
    BEGIN
        EXECUTE ('ALTER INDEX ALL ON ' +
            @schemaname + '.' +
            @tablename + ' REBUILD;');
        FETCH NEXT FROM tables_cursor INTO @schemaname, @tablename;
    END

PRINT 'The indexes on all tables have been rebuilt.';

CLOSE tables_cursor;

DEALLOCATE tables_cursor;

D. 搭配遠端預存程式使用 EXECUTE

下列範例會在遠端伺服器 uspGetEmployeeManagers 中執行 SQLSERVER1 預存程序,並且儲存傳回狀態,指出 @retstat 是成功還是失敗。

DECLARE @retstat AS INT;

EXECUTE
    @retstat = SQLSERVER1.AdventureWorks2022.dbo.uspGetEmployeeManagers
    @BusinessEntityID = 6;

E. 搭配預存程式變數使用 EXECUTE

下列範例會建立一個代表預存程序名稱的變數。

DECLARE @proc_name AS VARCHAR (30);
SET @proc_name = 'sys.sp_who';

EXECUTE @proc_name;

F. 搭配 DEFAULT 使用 EXECUTE

下列範例會針對第一個和第三個參數採用預設值來建立預存程序。 在執行程序時,如果呼叫中沒有傳遞任何值,或者如果未指定預設值,就會針對第一個和第三個參數插入這些預設值。 請注意各種可以使用 DEFAULT 關鍵字的方法。

IF OBJECT_ID(N'dbo.ProcTestDefaults', N'P') IS NOT NULL
    DROP PROCEDURE dbo.ProcTestDefaults;
GO

-- Create the stored procedure.
CREATE PROCEDURE dbo.ProcTestDefaults (
    @p1 SMALLINT = 42,
    @p2 CHAR (1),
    @p3 VARCHAR (8) = 'CAR'
)
AS
SET NOCOUNT ON;
SELECT @p1, @p2, @p3;
GO

您可以利用多種組合執行 Proc_Test_Defaults 預存程序。

-- Specifying a value only for one parameter (@p2).
EXECUTE dbo.ProcTestDefaults @p2 = 'A';

-- Specifying a value for the first two parameters.
EXECUTE dbo.ProcTestDefaults 68, 'B';

-- Specifying a value for all three parameters.
EXECUTE dbo.ProcTestDefaults 68, 'C', 'House';

-- Using the DEFAULT keyword for the first parameter.
EXECUTE dbo.ProcTestDefaults
    @p1 = DEFAULT,
    @p2 = 'D';

-- Specifying the parameters in an order different from the order defined in the procedure.
EXECUTE dbo.ProcTestDefaults DEFAULT,
    @p3 = 'Local',
    @p2 = 'E';

-- Using the DEFAULT keyword for the first and third parameters.
EXECUTE dbo.ProcTestDefaults DEFAULT, 'H', DEFAULT;
EXECUTE dbo.ProcTestDefaults DEFAULT, 'I', @p3 = DEFAULT;

G. 搭配AT linked_server_name 使用EXECUTE

下列範例會傳遞一個命令字串到遠端伺服器。 其它會建立一個連結伺服器 SeattleSales,指向 SQL Server 的另一個執行個體,然後針對該連結伺服器執行 DDL 陳述式 (CREATE TABLE)。

EXECUTE sp_addlinkedserver 'SeattleSales', 'SQL Server';
GO

EXECUTE ('CREATE TABLE AdventureWorks2022.dbo.SalesTbl
(SalesID INT, SalesName VARCHAR(10)); ') AT SeattleSales;
GO

H. 使用 EXECUTE WITH RECOMPILE

下列範例會執行 Proc_Test_Defaults 預存程序,並在執行模組之後,強制編譯、使用和捨棄新的查詢計劃。

EXECUTE dbo.Proc_Test_Defaults @p2 = 'A' WITH RECOMPILE;
GO

I. 搭配使用者定義函式使用 EXECUTE

下列範例會在 ufnGetSalesOrderStatusText AdventureWorks2022 資料庫中執行純量使用者定義函數。 它會使用變數 @returnstatus 來儲存該函數所傳回的值。 該函數會預期接受一個輸入參數 @Status。 它定義為 tinyint 資料類型。

DECLARE @returnstatus AS NVARCHAR (15);
SET @returnstatus = NULL;

EXECUTE
    @returnstatus = dbo.ufnGetSalesOrderStatusText
    @Status = 2;

PRINT @returnstatus;
GO

J. 使用 EXECUTE 查詢連結伺服器上的 Oracle 資料庫

下列範例會執行遠端 Oracle 伺服器上的幾個 SELECT 陳述式。 這個範例一開始就加入 Oracle 伺服器當做連結伺服器,並且建立連結伺服器登入。

-- Setup the linked server.
EXECUTE sp_addlinkedserver
    @server = 'ORACLE',
    @srvproduct = 'Oracle',
    @provider = 'OraOLEDB.Oracle',
    @datasrc = 'ORACLE10';

EXECUTE sp_addlinkedsrvlogin
    @rmtsrvname = 'ORACLE',
    @useself = 'false',
    @locallogin = NULL,
    @rmtuser = 'scott',
    @rmtpassword = 'tiger';

EXECUTE sp_serveroption 'ORACLE', 'rpc out', true;
GO

-- Execute several statements on the linked Oracle server.
EXECUTE ('SELECT * FROM scott.emp') AT ORACLE;
GO

EXECUTE ('SELECT * FROM scott.emp WHERE MGR = ?', 7902) AT ORACLE;
GO

DECLARE @v AS INT;
SET @v = 7902;

EXECUTE ('SELECT * FROM scott.emp WHERE MGR = ?', @v) AT ORACLE;
GO

K. 使用 EXECUTE AS USER 將內容切換至其他使用者

下列範例會執行 Transact-SQL 字串來建立一個資料表,以及指定 AS USER 子句,將陳述式的執行內容從呼叫端切換到 User1。 Database Engine 會在執行 語句時檢查 User1 的許可權。 User1 必須是資料庫中的使用者,並須具備在 Sales 結構描述中建立資料表的權限,否則陳述式將會失敗。

EXECUTE ('CREATE TABLE Sales.SalesTable (SalesID INT, SalesName VARCHAR(10));')
AS USER = 'User1';
GO

L. 搭配 EXECUTE 和 AT linked_server_name 使用參數

下列範例會使用問號 (?) 預留位置代表參數,將命令字串傳遞至遠端伺服器。 它會建立一個連結伺服器 SeattleSales,指向 SQL Server 的另一個執行個體,然後對該連結伺服器執行 SELECT 陳述式。 SELECT 陳述式會使用問號當做 ProductID 參數 (952) 的預留位置,而這會在陳述式之後提供。

-- Setup the linked server.
EXECUTE sp_addlinkedserver 'SeattleSales', 'SQL Server';
GO

-- Execute the SELECT statement.
EXECUTE ('SELECT ProductID, Name
    FROM AdventureWorks2022.Production.Product
    WHERE ProductID = ? ', 952) AT SeattleSales;
GO

M. 使用 EXECUTE 重新定義單一結果集

適用於:SQL Server 2012 (11.x) 和更新版本,以及 Azure SQL Database。

先前的一些範例會執行 EXECUTE dbo.uspGetEmployeeManagers 6; 傳回七個數據行。 下列範例示範如何使用 WITH RESULT SET 語法來變更傳回結果集的名稱和資料類型。

EXECUTE uspGetEmployeeManagers 16 WITH RESULT SETS
((
    [Reporting Level] INT NOT NULL,
    [ID of Employee] INT NOT NULL,
    [Employee First Name] NVARCHAR (50) NOT NULL,
    [Employee Last Name] NVARCHAR (50) NOT NULL,
    [Employee ID of Manager] NVARCHAR (MAX) NOT NULL,
    [Manager First Name] NVARCHAR (50) NOT NULL,
    [Manager Last Name] NVARCHAR (50) NOT NULL
));

N. 使用 EXECUTE 重新定義兩個結果集

適用於:SQL Server 2012 (11.x) 和更新版本,以及 Azure SQL Database。

當執行一個會傳回多個結果集的陳述式時,請定義每個預期的結果集。 AdventureWorks2022 中的下列範例會建立一個可傳回兩個結果集的程序。 然後使用 WITH RESULT SETS 子句執行程式,並指定兩個結果集定義。

--Create the procedure
CREATE PROCEDURE Production.ProductList
@ProdName NVARCHAR (50)
AS
-- First result set
SELECT
    ProductID,
    Name,
    ListPrice
FROM Production.Product
WHERE Name LIKE @ProdName;
-- Second result set
SELECT Name,
    COUNT(S.ProductID) AS NumberOfOrders
FROM Production.Product AS P
    INNER JOIN Sales.SalesOrderDetail AS S
        ON P.ProductID = S.ProductID
WHERE Name LIKE @ProdName
GROUP BY Name;
GO

-- Execute the procedure
EXECUTE Production.ProductList '%tire%' WITH RESULT SETS
(
    -- first result set definition starts here
    (ProductID INT,
    [Name] NAME,
    ListPrice MONEY)
    -- comma separates result set definitions
    ,
    -- second result set definition starts here
    ([Name] NAME,
    NumberOfOrders INT)
);

O. 使用 EXECUTE 搭配 AT DATA_SOURCE data_source_name查询远程 SQL Server

適用於:SQL Server 2019 (15.x) 和更新版本。

下列範例會將命令字串傳遞至指向 SQL Server 執行個體的外部資料來源。

EXECUTE ( 'SELECT @@SERVERNAME' ) AT DATA_SOURCE my_sql_server;
GO

P. 使用 EXECUTE 搭配 AT DATA_SOURCE data_source_name查询 SQL Server 巨量數據叢集中的計算集區

適用於:SQL Server 2019 (15.x)。

下列範例會將命令字串傳遞至指向 SQL Server 巨量資料叢集中計算集區的外部資料來源。 此範例會針對 SQL Server 巨量資料叢集中的計算集區建立資料來源 SqlComputePool,然後針對該資料來源執行 SELECT 陳述式。

CREATE EXTERNAL DATA SOURCE SqlComputePool
WITH (LOCATION = 'sqlcomputepool://controller-svc/default');

EXECUTE ('SELECT @@SERVERNAME') AT DATA_SOURCE SqlComputePool;
GO

Q. 搭配AT DATA_SOURCE data_source_name使用EXECUTE來查詢 SQL Server 巨量數據叢集中的數據集區

適用於:SQL Server 2019 (15.x)。

下列範例會將命令字串傳遞至指向 SQL Server 巨量資料叢集 (BDC) 中計算集區的外部數據來源。 此範例會針對 BDC 中的數據集區建立數據源 SqlDataPool,並針對數據源執行 SELECT 語句。

CREATE EXTERNAL DATA SOURCE SqlDataPool
WITH (LOCATION = 'sqldatapool://controller-svc/default');

EXECUTE ('SELECT @@SERVERNAME') AT DATA_SOURCE SqlDataPool;
GO

R. 使用 EXECUTE 搭配 AT DATA_SOURCE data_source_name查询 SQL Server 巨量數據叢集中的存放集區

適用於:SQL Server 2019 (15.x)。

下列範例會將命令字串傳遞至指向 SQL Server 巨量資料叢集中計算集區的外部資料來源。 此範例會針對 SQL Server 巨量資料叢集中的資料集區建立資料來源 SqlStoragePool,然後針對該資料來源執行 SELECT 陳述式。

CREATE EXTERNAL DATA SOURCE SqlStoragePool
WITH (LOCATION = 'sqlhdfs://controller-svc/default');

EXECUTE ('SELECT @@SERVERNAME') AT DATA_SOURCE SqlStoragePool;
GO

範例:Azure Synapse Analytics

本文中的 Transact-SQL 程式代碼範例會使用 AdventureWorks2022AdventureWorksDW2022 範例資料庫,您可以從 Microsoft SQL Server 範例和社群專案 首頁下載。

答:基本程序執行

執行預存程式:

EXECUTE proc1;

通叫在執行時間判斷名稱的預存程式:

EXECUTE ('EXECUTE ' + @var);

從預存程式內呼叫預存程式:

CREATE sp_first AS EXECUTE sp_second; EXECUTE sp_third;

B:執行字串

執行 SQL 字串:

EXECUTE ('SELECT * FROM sys.types');

執行巢狀字串:

EXECUTE ('EXECUTE (''SELECT * FROM sys.types'')');

執行字串變數:

DECLARE @stringVar AS NVARCHAR (100);
SET @stringVar = N'SELECT name FROM' + ' sys.sql_logins';

EXECUTE (@stringVar);

C:具有參數的程式

下列範例會建立具有參數的程式,並示範三種執行程式的方式:

CREATE PROCEDURE ProcWithParameters (
    @name NVARCHAR (50),
    @color NVARCHAR (15)
)
AS
SELECT ProductKey,
       EnglishProductName,
       Color
FROM [dbo].[DimProduct]
WHERE EnglishProductName LIKE @namef
      AND Color = @color;
GO

使用位置參數執行:

EXECUTE ProcWithParameters N'%arm%', N'Black';

依序使用具名參數執行:

EXECUTE ProcWithParameters
    @name = N'%arm%',
    @color = N'Black';

依序使用具名參數執行:

EXECUTE ProcWithParameters
    @color = N'Black',
    @name = N'%arm%';
GO