准备 SQL 语句

SQL Server 关系引擎完全支持在执行 SQL 语句前准备 SQL 语句。如果应用程序需要多次执行 SQL 语句,可以使用数据库 API 来执行下列操作:

  • 准备一次语句。这将 SQL 语句编译为执行计划。

  • 每当需要执行语句时都会执行预编译的执行计划。这将防止在第一次执行 SQL 语句后对每个执行计划必须重新编译 SQL 语句。

    语句的准备和执行由 API 函数和方法控制。它不是 Transact-SQL 语言的一部分。SQL Server Native Client OLE DB 访问接口和 SQL Server Native Client ODBC 驱动程序支持用于执行 SQL 语句的准备/执行模型。在准备请求时,访问接口或驱动程序通过请求将语句发送到 SQL Server,以准备该语句。SQL Server 编译执行计划并将该计划的句柄返回到该访问接口或驱动程序。在请求执行时,访问接口或驱动程序向服务器发送请求以执行与句柄相关联的计划。

预定义语句不能用于在 SQL Server 上创建临时对象。预定义语句不能引用创建临时对象(如临时表)的系统存储过程。必须直接执行这些过程。

过多地使用准备/执行模型会降低性能。如果一条语句只执行一次,直接执行只需要与服务器进行一次网络往返。准备并执行只执行一次的 SQL 语句,则需要多进行一次网络往返;一次是准备语句,一次是执行语句。

如果使用参数标记,可更有效地准备语句。例如,假设可能偶尔让应用程序从 AdventureWorks 示例数据库检索产品信息。应用程序可以采用两种方法执行此操作。

使用第一种方法,应用程序可以为请求的每个产品执行一个单独的查询:

SELECT * FROM AdventureWorks.Production.Product
WHERE ProductID = 63;

使用第二种方法,应用程序可以执行下列操作:

  1. 准备带参数标记 (?) 的语句:

    SELECT * FROM AdventureWorks.Production.Product
    WHERE ProductID = ?;
    
  2. 将程序变量绑定到参数标记上。

  3. 每次需要产品信息时,用键值填充绑定的变量,然后执行该语句。

如果执行语句的次数多于三次,第二种方法更有效。

在 SQL Server 中,由于 SQL Server 重新使用执行计划的方式,准备/执行模型相对于直接执行没有明显的性能优势。SQL Server 有高效的算法,可将当前的 SQL 语句与为前面执行同一 SQL 语句而生成的执行计划相匹配。如果应用程序使用参数标记多次执行一个 SQL 语句,SQL Server 将在第二次以及后续执行中重新使用第一次执行的执行计划(除非该计划已在过程缓存中老化)。准备/执行模型还具有下列优点:

  • 与通过算法将 SQL 语句与现有执行计划进行匹配的方法相比,通过识别句柄查找执行计划的方法更有效。

  • 应用程序可以控制何时创建和重新使用执行计划。

  • 准备/执行模型可移植到其他数据库,包括早期版本的 SQL Server。