运行时生成语句-SQL
2009-08-25 16:09
246 查看
SQL Server 2008 联机丛书(2009 年 5 月)
使用 sp_executesql
建议您在执行字符串时,使用 sp_executesql 存储过程而不要使用 EXECUTE 语句。由于此存储过程支持参数替换,因此 sp_executesql 比 EXECUTE 的功能更多;由于 SQL Server 更可能重用 sp_executesql 生成的执行计划,因此 sp_executesql 比 EXECUTE 更有效。
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
自包含批处理
当 sp_executesql 或 EXECUTE 语句执行字符串时,字符串将作为它的自包含批处理执行。SQL Server 会将字符串中的一个或多个 Transact-SQL 语句编译为独立于批处理(包含 sp_executesql 或 EXECUTE 语句)执行计划的执行计划。下列规则适用于自包含批处理:
在执行 sp_executesql 或 EXECUTE 语句之前,不会将 sp_executesql 或 EXECUTE 字符串中的 Transact-SQL 语句编译到执行计划中。执行字符串之前,不会分析或检查其错误。执行时才对字符串中引用的名称进行解析。
已执行的字符串中的 Transact-SQL 语句不能访问包含 sp_executesql 或 EXECUTE 语句的批处理中声明的任何变量。包含 sp_executesql 或 EXECUTE 语句的批处理不能访问已执行字符串中定义的变量或局部游标。
如果已执行字符串包含一个更改数据库上下文的 USE 语句,则对数据库上下文所做的更改将仅持续到 sp_executesql 或 EXECUTE 语句运行结束。
运行下列两个批处理说明了这些方面:
[align=center][/align]复制代码
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
替换参数值
sp_executesql 支持替换 Transact-SQL 字符串中指定的任何参数值,但 EXECUTE 语句不支持。因此,由 sp_executesql 生成的 Transact-SQL 字符串比那些由 EXECUTE 语句生成的字符串更加相似。SQL Server 查询优化器可能将 sp_executesql 的 Transact-SQL 语句与以前所执行的语句的执行计划相匹配,从而节省编译新的执行计划的开销。
使用 EXECUTE 语句,所有参数值都必须转换为字符或 Unicode,并成为 Transact-SQL 字符串的一部分。
如果重复执行语句,则即使只有提供的参数值不同,每次执行时也必须生成全新的 Transact-SQL 字符串。这样就会以下列方式生成额外的开销:
不断更改字符串文本(特别是复杂 Transact-SQL 语句)中的参数值,会影响 SQL Server 查询优化器将新的 Transact-SQL 字符串与现有执行计划相匹配的功能。
每次执行时均必须重新生成整个字符串。
每次执行时必须将参数值(非字符或 Unicode 值)转换为字符或 Unicode 格式。
sp_executesql 可以单独使用 Transact-SQL 字符串来设置参数值:
[align=center][/align]复制代码
sp_executesql 还另有以下优点:
因为 Transact-SQL 语句的实际文本在两次执行之间未更改,所以查询优化器能够将第二次执行中的 Transact-SQL 语句与第一次执行时生成的执行计划相匹配。因此,SQL Server 不必编译第二条语句。
Transact-SQL 字符串只生成一次。
整型参数按其本身格式指定。不需要转换为 Unicode。
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
重用执行计划
在 SQL Server 早期版本中,唯一可以重用执行计划的方式是将 Transact-SQL 语句定义为存储过程并让应用程序执行该存储过程。这会产生管理应用程序的额外开销。使用 sp_executesql 可有助于减少此开销,并允许 SQL Server 仍重用执行计划。当提供给 Transact-SQL 语句的参数值只有一个变量时,如果要多次执行 Transact-SQL 语句,则可以使用 sp_executesql 而不要使用其他存储过程。因为 Transact-SQL 语句本身保持不变,仅参数值发生更改,所以 SQL Server 查询优化器可能会重用第一次执行时生成的执行计划。
下面的示例为服务器上的每个数据库(四个系统数据库除外)生成并执行
[align=center][/align]复制代码
要执行的 Transact-SQL 语句包含绑定的参数标记时,SQL Server ODBC 驱动程序使用 sp_executesql 来实施 SQLExecDirect。这样,可以将 sp_executesql 提供的优势扩展到使用 ODBC 或通过 ODBC 定义的 API(例如 RDO)的所有应用程序。连接到 SQL Server 的现有 ODBC 应用程序无需重写就可以自动获得性能上的改进。但有一个例外,如果是执行时数据参数,则不能使用 sp_executesql。有关详细信息,请参阅 使用语句参数。
SQL Server Native Client ODBC 访问接口也使用 sp_executesql 来直接执行带有绑定参数的语句。使用 OLE DB 或 ADO 的应用程序无需重写就可以利用 sp_executesql 具有的优点。
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
请参阅
DECLARE @local_variable (Transact-SQL)
SELECT (Transact-SQL)
sp_executesql (Transact-SQL)
使用 sp_executesql
建议您在执行字符串时,使用 sp_executesql 存储过程而不要使用 EXECUTE 语句。由于此存储过程支持参数替换,因此 sp_executesql 比 EXECUTE 的功能更多;由于 SQL Server 更可能重用 sp_executesql 生成的执行计划,因此 sp_executesql 比 EXECUTE 更有效。
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
自包含批处理
当 sp_executesql 或 EXECUTE 语句执行字符串时,字符串将作为它的自包含批处理执行。SQL Server 会将字符串中的一个或多个 Transact-SQL 语句编译为独立于批处理(包含 sp_executesql 或 EXECUTE 语句)执行计划的执行计划。下列规则适用于自包含批处理:
在执行 sp_executesql 或 EXECUTE 语句之前,不会将 sp_executesql 或 EXECUTE 字符串中的 Transact-SQL 语句编译到执行计划中。执行字符串之前,不会分析或检查其错误。执行时才对字符串中引用的名称进行解析。
已执行的字符串中的 Transact-SQL 语句不能访问包含 sp_executesql 或 EXECUTE 语句的批处理中声明的任何变量。包含 sp_executesql 或 EXECUTE 语句的批处理不能访问已执行字符串中定义的变量或局部游标。
如果已执行字符串包含一个更改数据库上下文的 USE 语句,则对数据库上下文所做的更改将仅持续到 sp_executesql 或 EXECUTE 语句运行结束。
运行下列两个批处理说明了这些方面:
[align=center][/align]复制代码
/*Show not having access to variables from the calling batch. */ DECLARE @CharVariable CHAR(3); SET @CharVariable = 'abc'; /* sp_executesql fails because @CharVariable has gone out of scope. */ EXECUTE sp_executesql N'PRINT @CharVariable'; GO /* Show database context resetting after sp_executesql finishes. */ USE master; GO EXECUTE sp_executesql N'USE AdventureWorks;' GO /* This statement fails because the database context has now returned to master. */ SELECT * FROM Sales.Store; GO
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
替换参数值
sp_executesql 支持替换 Transact-SQL 字符串中指定的任何参数值,但 EXECUTE 语句不支持。因此,由 sp_executesql 生成的 Transact-SQL 字符串比那些由 EXECUTE 语句生成的字符串更加相似。SQL Server 查询优化器可能将 sp_executesql 的 Transact-SQL 语句与以前所执行的语句的执行计划相匹配,从而节省编译新的执行计划的开销。
使用 EXECUTE 语句,所有参数值都必须转换为字符或 Unicode,并成为 Transact-SQL 字符串的一部分。
如果重复执行语句,则即使只有提供的参数值不同,每次执行时也必须生成全新的 Transact-SQL 字符串。这样就会以下列方式生成额外的开销:
不断更改字符串文本(特别是复杂 Transact-SQL 语句)中的参数值,会影响 SQL Server 查询优化器将新的 Transact-SQL 字符串与现有执行计划相匹配的功能。
每次执行时均必须重新生成整个字符串。
每次执行时必须将参数值(非字符或 Unicode 值)转换为字符或 Unicode 格式。
sp_executesql 可以单独使用 Transact-SQL 字符串来设置参数值:
[align=center][/align]复制代码
DECLARE @IntVariable INT; DECLARE @SQLString NVARCHAR(500); DECLARE @ParmDefinition NVARCHAR(500); /* Build the SQL string one time. */ SET @SQLString = N'SELECT * FROM AdventureWorks.Sales.Store WHERE SalesPersonID = @SalesID'; /* Specify the parameter format one time. */ SET @ParmDefinition = N'@SalesID int'; /* Execute the string with the first parameter value. */ SET @IntVariable = 275; EXECUTE sp_executesql @SQLString, @ParmDefinition, @SalesID = @IntVariable; /* Execute the same string with the second parameter value. */ SET @IntVariable = 276; EXECUTE sp_executesql @SQLString, @ParmDefinition, @SalesID = @IntVariable;
sp_executesql 还另有以下优点:
因为 Transact-SQL 语句的实际文本在两次执行之间未更改,所以查询优化器能够将第二次执行中的 Transact-SQL 语句与第一次执行时生成的执行计划相匹配。因此,SQL Server 不必编译第二条语句。
Transact-SQL 字符串只生成一次。
整型参数按其本身格式指定。不需要转换为 Unicode。
![]() 注意: |
---|
语句字符串中的对象名称必须完全符合 SQL Server 重用执行计划的要求。 |
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
重用执行计划
在 SQL Server 早期版本中,唯一可以重用执行计划的方式是将 Transact-SQL 语句定义为存储过程并让应用程序执行该存储过程。这会产生管理应用程序的额外开销。使用 sp_executesql 可有助于减少此开销,并允许 SQL Server 仍重用执行计划。当提供给 Transact-SQL 语句的参数值只有一个变量时,如果要多次执行 Transact-SQL 语句,则可以使用 sp_executesql 而不要使用其他存储过程。因为 Transact-SQL 语句本身保持不变,仅参数值发生更改,所以 SQL Server 查询优化器可能会重用第一次执行时生成的执行计划。
下面的示例为服务器上的每个数据库(四个系统数据库除外)生成并执行
DBCC CHECKDB语句。
[align=center][/align]复制代码
USE master; GO SET NOCOUNT ON; GO DECLARE AllDatabases CURSOR FOR SELECT name FROM sys.databases WHERE database_id > 4 OPEN AllDatabases DECLARE @DBNameVar NVARCHAR(128) DECLARE @Statement NVARCHAR(300) FETCH NEXT FROM AllDatabases INTO @DBNameVar WHILE (@@FETCH_STATUS = 0) BEGIN PRINT N'CHECKING DATABASE ' + @DBNameVar SET @Statement = N'USE ' + @DBNameVar + CHAR(13) + N'DBCC CHECKDB (' + @DBNameVar + N')' + N'WITH PHYSICAL_ONLY' EXEC sp_executesql @Statement PRINT CHAR(13) + CHAR(13) FETCH NEXT FROM AllDatabases INTO @DBNameVar END CLOSE AllDatabases DEALLOCATE AllDatabases GO SET NOCOUNT OFF; GO
要执行的 Transact-SQL 语句包含绑定的参数标记时,SQL Server ODBC 驱动程序使用 sp_executesql 来实施 SQLExecDirect。这样,可以将 sp_executesql 提供的优势扩展到使用 ODBC 或通过 ODBC 定义的 API(例如 RDO)的所有应用程序。连接到 SQL Server 的现有 ODBC 应用程序无需重写就可以自动获得性能上的改进。但有一个例外,如果是执行时数据参数,则不能使用 sp_executesql。有关详细信息,请参阅 使用语句参数。
SQL Server Native Client ODBC 访问接口也使用 sp_executesql 来直接执行带有绑定参数的语句。使用 OLE DB 或 ADO 的应用程序无需重写就可以利用 sp_executesql 具有的优点。
![](http://i.msdn.microsoft.com/Global/Images/clear.gif)
请参阅
其他资源
SQL 注入DECLARE @local_variable (Transact-SQL)
SELECT (Transact-SQL)
sp_executesql (Transact-SQL)
帮助和信息
获取 SQL Server 2008 帮助相关文章推荐
- T-SQL 运行时生成语句
- T-SQL 运行时生成语句
- T-SQL 运行时生成语句
- T-SQL 运行时生成语句
- T-SQL 之 运行时生成语句
- SQL练习题,MySQL数据库查询语句经典例题练习,附带答案和运行效果截图以供参考
- 案例学习:如何让你的SQL运行得更快 转 荐
- 如何让你的SQL运行得更快
- sql语句没问题,在数据库运行ok ,也查出了数据,但就是显示的时候报空指针异常..
- SQLSERVER 监视SQL运行效率
- 如何让你的SQL运行得更快
- PL/SQL批量运行SQL语句
- 设置Sql Agent运行Job时的执行账户
- Oracle数据库案例整理-Oracle系统运行时故障-sql_trace设置为TRUE导致Oracle根目录可用空间不足
- 案例学习:如何让你的SQL运行得更快
- oracle sqlplus运行sql文件
- 如何让你的SQL运行得更快!
- 通过运行sql文件增加mysql不存在的列
- 如何让你的SQL运行得更快!
- oracle的sqldeveloper在ubuntu上以图标显示且双击能运行