准备 SQL 语句
SQL Server 2005 关系引擎完全支持在执行 SQL 语句前准备 SQL 语句。如果应用程序需要多次执行 SQL 语句,可以使用数据库 API 来执行下列操作:
- 准备一次语句。这将 SQL 语句编译为执行计划。
- 每当需要执行语句时都会执行预编译的执行计划。这将防止在第一次执行 SQL 语句后对每个执行计划必须重新编译 SQL 语句。
语句的准备和执行由 API 函数和方法控制。它不是 Transact-SQL 语言的一部分。用于执行 SQL 语句的准备/执行模型由 SQL Native Client OLE DB 访问接口和 SQL Native Client ODBC 驱动程序支持。在准备请求时,访问接口或驱动程序通过请求将语句发送到 SQL Server,以准备该语句。SQL Server 编译执行计划并将该计划的句柄返回到该访问接口或驱动程序。在请求执行时,访问接口或驱动程序向服务器发送请求以执行与句柄相关联的计划。
准备的语句不能用于在 SQL Server 2005 上创建临时对象。准备的语句不能引用创建临时对象(如临时表)的系统存储过程。必须直接执行这些过程。
过多地使用准备/执行模型会降低性能。如果一条语句只执行一次,直接执行只需要与服务器进行一次网络往返。准备并执行只执行一次的 SQL 语句,则需要多进行一次网络往返;一次是准备语句,一次是执行语句。
如果使用参数标记,可更有效地准备语句。例如,假设可能偶尔让应用程序从 AdventureWorks 示例数据库检索产品信息。应用程序可以采用两种方法执行此操作。
使用第一种方法,应用程序可以为请求的每个产品执行一个单独的查询:
SELECT * FROM AdventureWorks.Production.Product
WHERE ProductID = 63
使用第二种方法,应用程序可以执行下列操作:
准备带参数标记 (?) 的语句:
SELECT * FROM AdventureWorks.Production.Product WHERE ProductID = ?
将程序变量绑定到参数标记上。
每次需要产品信息时,用键值填充绑定的变量,然后执行该语句。
如果执行语句的次数多于三次,第二种方法更有效。
在 SQL Server 2005 中,由于 SQL Server 2005 重新使用执行计划的方式,准备/执行模型相对于直接执行没有明显的性能优势。SQL Server 2005 有高效的算法,可将当前的 SQL 语句与为前面执行同一 SQL 语句而生成的执行计划进行匹配。如果应用程序使用参数标记多次执行一个 SQL 语句,SQL Server 2005 将在第二次执行以及后面的执行中重新使用第一次执行的执行计划(除非该计划已从过程缓存老化掉)。准备/执行模型还具有下列优点:
- 与通过算法将 SQL 语句与现有执行计划进行匹配的方法相比,通过识别句柄查找执行计划的方法更有效。
- 应用程序可以控制何时创建和重新使用执行计划。
- 准备/执行模型可移植到其他数据库,包括早期的 SQL Server 版本。
在 SQL Server 早期版本中准备和执行
SQL Server 6.5 版和更早版本不直接支持准备/执行模型。但是,SQL Server ODBC 驱动程序通过使用存储过程支持准备/执行模型:
- 应用程序请求准备 SQL 语句时,ODBC 驱动程序将 SQL 语句包装在 CREATE PROCEDURE 语句中并将其发送给 SQL Server。
- 在请求执行时,ODBC 驱动程序将请求 SQL Server 执行生成的存储过程。
在 SQL Server 6.5 和 SQL Server 6.0 中,生成的存储过程是存储在 tempdb 中的临时存储过程。SQL Server 4.21a 版及早期版本不支持临时存储过程,因此驱动程序生成存储在当前数据库中的常规存储过程。与 SQL Server 2000 一起发布的用于 SQL Server 的 Microsoft OLE DB Provider for SQL Server 和 SQL Server ODBC 驱动程序在连接到 SQL Server 6.5 版、6.0 版和 SQL Server 4.21a 版时遵循此行为。