可以使用 value 或 @parameter_name = value 来提供参数。参数不是事务的一部分,如果在以后将回滚的事务中更改了参数,则此参数的值不会恢复为其以前的值。返回给调用方的值总是模块返回时的值。
当一个模块调用其他模块或通过引用公共语言运行时 (CLR) 模块、用户定义类型或聚合执行托管代码时,将出现嵌套。当开始执行调用模块或托管代码引用时,嵌套级别将增加,而当调用模块或托管代码引用完成时,嵌套级别将减少。嵌套级别最高为 32 级,超过 32 级时,会导致整个调用链失败。当前的嵌套级别存储在 @@NESTLEVEL 系统函数中。
因为远程存储过程和扩展存储过程不在事务的范围内(除非在 BEGIN DISTRIBUTED TRANSACTION 语句中发出或者是和不同的配置选项一起使用),所以通过调用执行的命令不能回滚。有关详细信息,请参阅系统存储过程 (Transact-SQL) 和 BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)。
当使用游标变量时,如果执行的过程传递一个分配有游标的游标变量,就会出错。
在执行模块时,如果语句是批处理中的第一个语句,则不一定要指定 EXECUTE 关键字。
在存储过程中使用 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 AdventureWorks; SELECT EmployeeID, Title 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 不是数据库的主体。
最佳实践
指定具有执行语句或模块中定义的操作所需的最低权限的登录名或用户。例如,如果只需数据库级别权限,则不要指定拥有服务器级别权限的登录名;如果不需要相应权限,也不要指定数据库所有者帐户。