EXECUTE (Transact-SQL)

执行 Transact-SQL 批处理中的命令字符串、字符串或执行下列模块之一:系统存储过程、用户定义存储过程、CLR 存储过程、标量值用户定义函数或扩展存储过程。 EXECUTE 语句可用于向链接服务器发送传递命令。 此外,还可以显式设置执行字符串或命令的上下文。 可以使用 WITH RESULT SETS 选项定义结果集的元数据。

安全说明安全说明

在使用字符串调用 EXECUTE 之前,请先验证该字符串。永远不要执行由未经验证的用户输入构造的命令。

适用范围:SQL Server(SQL Server 2008 至当前版本),Windows Azure SQL Database(初始版本至当前版本)。

主题链接图标 Transact-SQL 语法约定

语法

-- SQL Server Syntax

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 
}

-- Windows 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 

参数

  • @return\_status
    可选的整型变量,存储模块的返回状态。 这个变量在用于 EXECUTE 语句前,必须在批处理、存储过程或函数中声明过。

    在用于调用标量值用户定义函数时,@return_status 变量可以为任意标量数据类型。

  • module_name
    是要调用的存储过程或标量值用户定义函数的完全限定或者不完全限定名称。 模块名称必须符合标识符规则。 无论服务器的排序规则如何,扩展存储过程的名称总是区分大小写。

    用户可以执行在另一数据库中创建的模块,只要运行模块的用户拥有此模块或具有在该数据库中执行该模块的适当权限。 用户可以在另一台运行 SQL Server 的服务器中执行模块,只要该用户有相应的权限使用该服务器(远程访问),并能在数据库中执行该模块。 如果指定了服务器名称但没有指定数据库名称,则 SQL Server 数据库引擎会在用户的默认数据库中查找该模块。

  • ;number

    适用于:SQL Server 2008 到 SQL Server 2014。

    是可选整数,用于对同名的过程分组。 该参数不能用于扩展存储过程。

    备注

    后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。

    有关过程分组的详细信息,请参阅 CREATE PROCEDURE (Transact-SQL)

  • @module\_name\_var
    是局部定义的变量名,代表模块名称。

  • @parameter
    module_name 的参数,与在模块中定义的相同。 参数名称前必须加上符号 (@)。 在与 @parameter\_name=value 格式一起使用时,参数名和常量不必按它们在模块中定义的顺序提供。 但是,如果对任何参数使用了 @parameter\_name=value 格式,则必须对所有后续参数都使用此格式。

    默认情况下,参数可为空值。

  • value
    传递给模块或传递命令的参数值。 如果参数名称没有指定,参数值必须以在模块中定义的顺序提供。

    对链接服务器执行传递命令时,参数值的顺序取决于链接服务器的 OLE DB 访问接口。 大多数 OLE DB 访问接口按从左到右的顺序将值绑定到参数。

    如果参数值是一个对象名、字符串或由数据库名称或架构名称限定,则整个名称必须用单引号括起来。 如果参数值是一个关键字,则该关键字必须用双引号括起来。

    如果在模块中定义了默认值,用户执行该模块时可以不必指定参数。

    默认值也可以为 NULL。 通常,模块定义会指定当参数值为 NULL 时应该执行的操作。

  • @variable
    是用来存储参数或返回参数的变量。

  • OUTPUT
    指定模块或命令字符串返回一个参数。 该模块或命令字符串中的匹配参数也必须已使用关键字 OUTPUT 创建。 使用游标变量作为参数时使用该关键字。

    如果将 value 定义为对链接服务器执行的模块的 OUTPUT 参数值,在此模块执行结束时,OLE DB 访问接口对相应 @parameter 执行的任何更改都会复制回此变量。

    如果正在使用 OUTPUT 参数,并且使用的目的是在执行调用的批处理或模块内的其他语句中使用其返回值,则此参数的值必须作为变量传递,例如,@parameter = @variable。 如果一个参数在模块中没有定义为 OUTPUT 参数,则不能通过对该参数指定 OUTPUT 执行模块。 不能使用 OUTPUT 将常量传递给模块;返回参数需要变量名称。 在执行过程之前,必须声明变量的数据类型并赋值。

    当对远程存储过程使用 EXECUTE 或对链接服务器执行传递命令时,OUTPUT 参数不能是任何大型对象 (LOB) 数据类型。

    返回参数可以是 LOB 数据类型之外的任意数据类型。

  • DEFAULT
    根据模块的定义,提供参数的默认值。 当模块需要的参数值没有定义默认值,并且缺少参数或指定了 DEFAULT 关键字,则会发生错误。

  • @string\_variable
    局部变量的名称。 @string\_variable 可以是任意 char、varchar、nchar 或 nvarchar 数据类型。 其中包括 (max) 数据类型。

  • [N] 'tsql_string'
    常量字符串。 tsql_string 可以是任何 nvarchar 或 varchar 数据类型。 如果包含 N,则字符串将解释为 nvarchar 数据类型。

  • AS <context_specification>
    指定执行语句的上下文。

  • LOGIN

    适用于:SQL Server 2008 到 SQL Server 2014。

    指定要模拟的上下文是登录名。 模拟范围为服务器。

  • USER
    指定要模拟的上下文是当前数据库中的用户。 模拟范围只限于当前数据库。 对数据库用户的上下文切换不会继承该用户的服务器级别权限。

    重要说明重要提示

    当到数据库用户的上下文切换处于活动状态时,任何对数据库外部资源的访问尝试都会导致语句失败。这包括 USE database 语句、分布式查询和使用三部分或四部分标识符引用其他数据库的查询。

  • 'name'
    有效的用户或登录名。 name 必须是 sysadmin 固定服务器角色成员,或者分别作为 sys.database_principalssys.server_principals 中的主体存在。

    name 不能为内置帐户,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。

    有关详细信息,请参阅本主题后面的指定用户名或登录名。

  • [N] 'command_string'
    常量字符串,包含要传递给链接服务器的命令。 如果包含 N,则字符串将解释为 nvarchar 数据类型。

  • [?]
    指示参数,该参数的值在 EXEC('…', <arg-list>) AT <linkedsrv> 语句中所使用的 <arg-list> 传递命令中提供。

  • AT linked_server_name

    适用于:SQL Server 2008 到 SQL Server 2014。

    指定对 linked_server_name 执行 command_string,并将结果(如果有)返回客户端。 linked_server_name 必须引用本地服务器中的现有链接服务器定义。 链接服务器是使用 sp_addlinkedserver 定义的。

  • WITH <execute_option>
    可能的执行选项。 不能在 INSERT…EXEC 语句中指定 RESULT SETS 选项。

    术语

    定义

    RECOMPILE

    执行模块后,强制编译、使用和放弃新计划。 如果该模块存在现有查询计划,则该计划将保留在缓存中。

    如果所提供的参数为非典型参数或者数据有很大的改变,使用该选项。 该选项不能用于扩展存储过程。 建议尽量少使用该选项,因为它消耗较多系统资源。

    备注

    在调用使用 OPENDATASOURCE 语法的存储过程时,不能使用 WITH RECOMPILE。如果指定由四个部分组成的对象名,则忽略 WITH RECOMPILE 选项。

    RESULT SETS UNDEFINED

    适用范围:SQL Server 2012 到 SQL Server 2014,Windows Azure SQL Database。

    </div>
    <p>此选项不保证将返回任何结果(如果有),并且不提供任何定义。 如果返回任何结果,则说明语句正常执行而没有发生错误,否则,不会返回任何结果。 如果未提供 result_sets_option,则 RESULT SETS UNDEFINED 是默认行为。</p></td>
    </tr>
    <tr class="odd">
    <td><p>RESULT SETS NONE</p></td>
    <td><div class="caption">
    
    </div>
    <div class="tableSection">
    <table>
    <colgroup>
    <col style="width: 100%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><p><strong>适用范围</strong>:SQL Server 2012 到 SQL Server 2014,Windows Azure SQL Database。</p></td>
    </tr>
    </tbody>
    </table>
    
    </div>
    <p>保证执行语句不返回任何结果。 如果返回任何结果,则会中止批处理。</p></td>
    </tr>
    <tr class="even">
    <td><p>&lt;result_sets_definition&gt;</p></td>
    <td><div class="caption">
    
    </div>
    <div class="tableSection">
    <table>
    <colgroup>
    <col style="width: 100%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><p><strong>适用范围</strong>:SQL Server 2012 到 SQL Server 2014,Windows Azure SQL Database。</p></td>
    </tr>
    </tbody>
    </table>
    
    </div>
    <p>保证返回 result_sets_definition 中指定的结果。 对于返回多个结果集的语句,请提供多个 result_sets_definition 部分。 将每个 result_sets_definition 用圆括号括起来并由逗号分隔。 有关详细信息,请参阅本主题后面的 &lt;result_sets_definition&gt;。</p></td>
    </tr>
    </tbody>
    </table>
    
    • <result_sets_definition>

      适用范围:SQL Server 2012 到 SQL Server 2014,Windows Azure SQL Database。

      描述执行的语句所返回的结果集。 result_sets_definition 的子句具有以下含义

      定义

      {

          column_name

          data_type

          [ COLLATE collation_name]

          [NULL | NOT NULL]

      }

      定义

      column_name

      每个列的名称。 如果列数不同于结果集,则会发生错误并中止批处理。 如果列名不同于结果集,则将返回的列名设置为定义的名称。

      data_type

      每个列的数据类型。 如果数据类型不同,则对定义的数据类型执行隐式转换。 如果转换失败,则中止批处理。

      COLLATE collation_name

      每个列的排序规则。 如果排序规则不匹配,则尝试使用隐式排序规则。 如果该操作失败,则中止批处理。

      NULL | NOT NULL

      每个列的为 Null 性。 如果定义的为 NULL 性为 NOT NULL,并且返回的数据包含 NULL,则会发生错误并中止批处理。 如果未指定,则默认值符合 ANSI_NULL_DFLT_ON 和 ANSI_NULL_DFLT_OFF 选项的设置。

      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。

      执行期间返回的实际结果集在以下方面可能不同于使用 WITH RESULT SETS 子句定义的结果:结果集数、列数、列名、为 Null 性以及数据类型。 如果结果集数不同,则会发生错误并中止批处理。

    注释

    可以使用 value 或 @parameter\_name = value 来提供参数。参数不是事务的一部分;因此,如果在以后回滚的事务中更改了参数,则此参数的值不会恢复为以前的值。 返回给调用方的值总是模块返回时的值。

    当一个模块调用其他模块或通过引用公共语言运行时 (CLR) 模块、用户定义类型或聚合执行托管代码时,将出现嵌套。 当开始执行调用模块或托管代码引用时,嵌套级别将增加,而当调用模块或托管代码引用完成时,嵌套级别将减少。 嵌套级别最高为 32 级,超过 32 级时,会导致整个调用链失败。 当前的嵌套级别存储在 @@NESTLEVEL 系统函数中。

    因为远程存储过程和扩展存储过程不在事务的范围内(除非在 BEGIN DISTRIBUTED TRANSACTION 语句中发出或者是和不同的配置选项一起使用),所以通过调用执行的命令不能回滚。 有关详细信息,请参阅系统存储过程 (Transact-SQL)BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)

    当使用游标变量时,如果执行的过程传递一个分配有游标的游标变量,就会出错。

    在执行模块时,如果语句是批处理中的第一个语句,则不一定要指定 EXECUTE 关键字。

    有关 CLR 存储过程特定的其他信息,请参阅 CLR 存储过程。

    在存储过程中使用 EXECUTE

    在执行存储过程时,如果语句是批处理中的第一个语句,则不一定要指定 EXECUTE 关键字。

    SQL Server 系统存储过程以字符 sp_ 开头。 这些存储过程物理上存储在资源数据库中,但逻辑上出现在每个系统数据库和用户定义数据库的 sys 架构中。 在批处理或模块(如用户定义存储过程或函数)中执行系统存储过程时,建议使用 sys 架构名称限定存储过程名称。

    SQL Server 系统扩展存储过程以字符 xp_, 开头,这些存储过程包含在 master 数据库的 dbo 架构中。 在批处理或模块(如用户定义存储过程或函数)内执行系统扩展存储过程时,建议使用 master.dbo 限定存储过程名称。

    在批处理或模块(如用户定义存储过程或函数)内执行用户定义存储过程时,建议使用架构名限定存储过程名称。 建议不要使用与系统存储过程相同的名称命名用户定义存储过程。 有关执行存储过程的详细信息,请参阅执行存储过程

    使用带字符串的 EXECUTE 命令

    在 SQL Server 的早期版本中,字符串限制为 8,000 字节。 这要求连接长字符串,以便动态执行。 在 SQL Server 中,可以指定 varchar(max) 和 nvarchar(max) 数据类型,它们允许字符串使用多达 2 GB 数据。

    数据库上下文的更改只在 EXECUTE 语句结束前有效。 例如,在运行下面这条语句中的 EXEC 后,数据库上下文将为 master。

    USE master; EXEC ('USE AdventureWorks2012; SELECT BusinessEntityID, JobTitle FROM HumanResources.Employee;');
    

    上下文切换

    可以使用 AS { LOGIN | USER } = ' name ' 子句切换动态语句的执行上下文。 当将上下文切换指定为 EXECUTE ('string') AS <context_specification> 时,上下文切换的持续时间限制为执行查询的范围。

    指定用户名或登录名

    AS { LOGIN | USER } = ' name ' 中指定的用户名或登录名必须分别作为 sys.database_principals 或 sys.server_principals 的主体存在,否则该语句将失败。 此外,还必须为该主体授予 IMPERSONATE 权限。 除非调用方是数据库所有者或 sysadmin 固定服务器角色的成员,否则,即使在用户通过 Windows 组成员身份访问数据库或 SQL Server 实例时,也必须存在该主体。 例如,假设条件如下:

    • CompanyDomain\SQLUsers 组有权访问 Sales 数据库。

    • CompanyDomain\SqlUser1 是 SQLUsers 的成员,因此具有 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 USER 或 SELF,并且模块所有者对被引用对象具有相应权限。 有关模块内模拟的详细信息,请参阅 EXECUTE AS 子句 (Transact-SQL)

    • 模块被标记为 EXECUTE AS CALLER,并且您对对象具有相应权限。

    • 模块被标记为 EXECUTE AS user_name,并且 user_name 对对象具有相应权限。

    上下文切换权限

    若要对某登录名指定 EXECUTE AS,调用方必须具有对所指定登录名的 IMPERSONATE 权限。 若要对某数据库用户指定 EXECUTE AS,调用方必须具有对所指定用户名的 IMPERSONATE 权限。 如果未指定执行上下文或指定了 EXECUTE AS CALLER,则无需 IMPERSONATE 权限。

    示例

    A.使用 EXECUTE 传递单个参数

    AdventureWorks2012 数据库中的 uspGetEmployeeManagers 存储过程需要一个参数 (@EmployeeID)。 以下示例执行 uspGetEmployeeManagers 存储过程,以 Employee ID 6 作为参数值。

    EXEC dbo.uspGetEmployeeManagers 6;
    GO
    

    在执行过程中变量可以显式命名:

    EXEC dbo.uspGetEmployeeManagers @EmployeeID = 6;
    GO
    

    如果以下语句为批处理、osqlsqlcmd 脚本中的第一个语句,则无需 EXEC。

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

    B.使用多个参数

    下面的示例在 AdventureWorks2012 数据库中执行 spGetWhereUsedProductID 存储过程。 该存储过程将传递两个参数:第一个参数为产品 ID (819),第二个参数 @CheckDate, 是 datetime 值。

    DECLARE @CheckDate datetime;
    SET @CheckDate = GETDATE();
    EXEC dbo.uspGetWhereUsedProductID 819, @CheckDate;
    GO
    

    C.使用带变量的 EXECUTE 'tsql_string' 语句

    下面的示例说明了 EXECUTE 如何处理动态生成的包含变量的字符串。 该示例创建 tables_cursor 游标以保存 AdventureWorks2012 数据库中所有用户定义表的列表,然后使用该列表重新生成对表的全部索引。

    DECLARE tables_cursor CURSOR
       FOR
       SELECT s.name, t.name 
       FROM sys.objects AS t
       JOIN sys.schemas AS s ON s.schema_id = t.schema_id
       WHERE t.type = 'U';
    OPEN tables_cursor;
    DECLARE @schemaname sysname;
    DECLARE @tablename 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;
    GO
    

    D.对远程存储过程使用 EXECUTE 语句

    以下示例在远程服务器 SQLSERVER1 上执行 uspGetEmployeeManagers 存储过程,然后在 @retstat 中存储指示成功或失败的返回状态。

    适用于:SQL Server 2008 到 SQL Server 2014。

    DECLARE @retstat int;
    EXECUTE @retstat = SQLSERVER1.AdventureWorks2012.dbo.uspGetEmployeeManagers @BusinessEntityID = 6;
    

    E.使用带存储过程变量的 EXECUTE 语句

    以下示例创建一个代表存储过程名称的变量。

    DECLARE @proc_name varchar(30);
    SET @proc_name = 'sys.sp_who';
    EXEC @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)。

    适用于:SQL Server 2008 到 SQL Server 2014。

    EXEC sp_addlinkedserver 'SeattleSales', 'SQL Server'
    GO
    EXECUTE ( 'CREATE TABLE AdventureWorks2012.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

    下面的示例在 AdventureWorks2012 数据库中执行 ufnGetSalesOrderStatusText 标量用户定义函数。 该语句使用 @returnstatus 变量存储函数的返回值。 函数需要一个输入参数 @Status。 该参数定义为 tinyint 数据类型。

    DECLARE @returnstatus nvarchar(15);
    SET @returnstatus = NULL;
    EXEC @returnstatus = dbo.ufnGetSalesOrderStatusText @Status = 2;
    PRINT @returnstatus;
    GO
    

    J.使用 EXECUTE 查询链接服务器上的 Oracle 数据库

    以下示例在远程 Oracle 服务器上执行几个 SELECT 语句。 示例开始时添加 Oracle 服务器作为链接服务器,并创建链接服务器登录。

    适用于:SQL Server 2008 到 SQL Server 2014。

    -- Setup the linked server.
    EXEC sp_addlinkedserver  
            @server='ORACLE',
            @srvproduct='Oracle',
            @provider='OraOLEDB.Oracle', 
            @datasrc='ORACLE10';
    
    EXEC sp_addlinkedsrvlogin 
        @rmtsrvname='ORACLE',
        @useself='false', 
        @locallogin=null, 
        @rmtuser='scott', 
        @rmtpassword='tiger';
     
    EXEC sp_serveroption 'ORACLE', 'rpc out', true;
    GO
     
    -- Execute several statements on the linked Oracle server.
    EXEC ( 'SELECT * FROM scott.emp') AT ORACLE;
    GO
    EXEC ( 'SELECT * FROM scott.emp WHERE MGR = ?', 7902) AT ORACLE;
    GO
    DECLARE @v INT; 
    SET @v = 7902;
    EXEC ( 'SELECT * FROM scott.emp WHERE MGR = ?', @v) AT ORACLE;
    GO 
    

    K.使用 EXECUTE AS USER 将上下文切换为其他用户

    以下示例执行用于创建表的 Transact-SQL 字符串并指定 AS USER 子句将语句的执行上下文从调用方切换为 User1。 当语句运行时,数据库引擎将检查 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)(该参数在语句后提供)的占位符。

    适用于:SQL Server 2008 到 SQL Server 2014。

    -- Setup the linked server.
    EXEC sp_addlinkedserver 'SeattleSales', 'SQL Server'
    GO
    -- Execute the SELECT statement.
    EXECUTE ('SELECT ProductID, Name 
        FROM AdventureWorks2012.Production.Product
        WHERE ProductID = ? ', 952) AT SeattleSales;
    GO
    

    M.使用 EXECUTE 重新定义单个结果集

    前面的一些示例执行 EXEC dbo.uspGetEmployeeManagers 6;,将返回 7 个列。 以下示例说明如何使用 WITH RESULT SET 语法更改返回的结果集的名称和数据类型。

    适用范围:SQL Server 2012 到 SQL Server 2014,Windows Azure SQL Database。

    EXEC 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 重新定义两个结果集

    在执行返回多个结果集的语句时,请定义每个预期结果集。 以下示例在 AdventureWorks2012 中创建一个返回两个结果集的过程。 然后使用 WITH RESULT SETS 子句执行该过程并指定两个结果集定义。

    适用范围:SQL Server 2012 到 SQL Server 2014,Windows Azure SQL Database。

    --Create the procedure
    CREATE PROC 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
        JOIN Sales.SalesOrderDetail AS S
            ON P.ProductID  = S.ProductID 
        WHERE Name LIKE @ProdName
        GROUP BY Name;
    GO
    
    -- Execute the procedure 
    EXEC Production.ProductList '%tire%'
    WITH RESULT SETS 
    (
        (ProductID int,   -- first result set definition starts here
        Name Name,
        ListPrice money)
        ,                 -- comma separates result set definitions
        (Name Name,       -- second result set definition starts here
        NumberOfOrders int)
    );
    

    请参阅

    参考

    @@NESTLEVEL (Transact-SQL)

    DECLARE @local\_variable (Transact-SQL)

    EXECUTE AS 子句 (Transact-SQL)

    osql 实用工具

    REVERT (Transact-SQL)

    sp_addlinkedserver (Transact-SQL)

    sqlcmd 实用工具

    SUSER_NAME (Transact-SQL)

    sys.database_principals (Transact-SQL)

    sys.server_principals (Transact-SQL)

    USER_NAME (Transact-SQL)

    OPENDATASOURCE (Transact-SQL)

    概念

    主体(数据库引擎)