如何执行参数化查询

本主题概括并演示了如何使用 SQL Server Driver for PHP 来执行参数化查询。

执行参数化查询的步骤可概括为四步:

  1. 将问号 (?)作为参数占位符放入作为要执行的查询的 Transact-SQL 字符串中。
  2. 使用第 2 步中的 PHP 变量创建或更新依次与此 Transact-SQL 字符串中的参数占位符对应的参数值数组。
  3. 使用 sqlsrv_querysqlsrv_prepare/sqlsrv_execute 执行查询。

备注

参数是通过使用 sqlsrv_prepare 隐式绑定的。也就是说,如果参数化查询是使用 sqlsrv_prepare 预定义的并且参数数组中的值已更新,则会在下次执行查询时使用更新后的值。有关详细信息,请参阅本主题中的第二个示例。

示例

下面的示例更新 AdventureWorks 数据库的 Production.ProductInventory 表中指定产品 ID 对应的产品数量。数量和产品 ID 是 UPDATE 查询中的参数。

然后,该示例将查询数据库以验证数量是否已正确更新。产品 ID 是 SELECT 查询中的一个参数。

此示例假定本地计算机上已安装了 SQL Server 和 AdventureWorks 数据库。从命令行运行此示例时,所有的输出都将写入控制台。

<?php
/* Connect to the local server using Windows Authentication and
specify the AdventureWorks database as the database in use. */
$serverName = "(local)";
$connectionInfo = array( "Database"=>"AdventureWorks");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
     echo "Could not connect.\n";
     die( print_r( sqlsrv_errors(), true));
}

/* Define the Transact-SQL query.
Use question marks as parameter placeholders. */
$tsql1 = "UPDATE Production.ProductInventory 
          SET Quantity = ? 
          WHERE ProductID = ?";

/* Initialize $qty and $productId */
$qty = 10; $productId = 709;

/* Execute the statement with the specified parameter values. */
$stmt1 = sqlsrv_query( $conn, $tsql1, array($qty, $productId));
if( $stmt1 === false )
{
     echo "Statement 1 could not be executed.\n";
     die( print_r( sqlsrv_errors(), true));
}

/* Free statement resources. */
sqlsrv_free_stmt( $stmt1);

/* Now verify the updated quantity.
Use a question mark as parameter placeholder. */
$tsql2 = "SELECT Quantity 
          FROM Production.ProductInventory
          WHERE ProductID = ?";

/* Execute the statement with the specified parameter value.
Display the returned data if no errors occur. */
$stmt2 = sqlsrv_query( $conn, $tsql2, array($productId));
if( $stmt2 === false )
{
     echo "Statement 2 could not be executed.\n";
     die( print_r(sqlsrv_errors(), true));
}
else
{
     $qty = sqlsrv_fetch_array( $stmt2);
     echo "There are $qty[0] of product $productId in inventory.\n";
}

/* Free statement and connection resources. */
sqlsrv_free_stmt( $stmt2);
sqlsrv_close( $conn);
?>

上一示例使用 sqlsrv_query 函数来执行查询。此函数非常适合执行一次性查询,原因是它既预定义语句,又执行语句。结合使用 sqlsrv_prepare/sqlsrv_execute 则是使用不同参数值重新执行查询的最佳方法。若要查看使用不同参数值重新执行查询的示例,请参阅下一示例或参阅如何多次执行一个查询

下面的示例演示在使用 sqlsrv_prepare 函数时如何隐式绑定变量。该示例将几个销售订单插入 Sales.SalesOrderDetail 表中。调用 sqlsrv_prepare 时,$params 数组会绑定到语句 ($stmt)。在每次执行将一个新的销售订单插入表的查询之前,$params 数组会使用与销售订单详细信息对应的新值进行更新。后续查询执行将使用新的参数值。

此示例假定本地计算机上已安装了 SQL Server 和 AdventureWorks 数据库。从命令行运行此示例时,所有的输出都将写入控制台。

<?php
/* Connect to the local server using Windows Authentication and
specify the AdventureWorks database as the database in use. */
$serverName = "(local)";
$connectionInfo = array( "Database"=>"AdventureWorks");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
     echo "Could not connect.\n";
     die( print_r( sqlsrv_errors(), true));
}

$tsql = "INSERT INTO Sales.SalesOrderDetail (SalesOrderID, 
                                             OrderQty, 
                                             ProductID, 
                                             SpecialOfferID, 
                                             UnitPrice)
         VALUES (?, ?, ?, ?, ?)";

/* Each sub array here will be a parameter array for a query.
The values in each sub array are, in order, SalesOrderID, OrderQty,
 ProductID, SpecialOfferID, UnitPrice. */
$parameters = array( array(43659, 8, 711, 1, 20.19),
                     array(43660, 6, 762, 1, 419.46),
                     array(43661, 4, 741, 1, 818.70)
                    );

/* Initialize parameter values. */
$orderId = 0;
$qty = 0;
$prodId = 0;
$specialOfferId = 0;
$price = 0.0;

/* Prepare the statement. $params is implicitly bound to $stmt. */
$stmt = sqlsrv_prepare( $conn, $tsql, array( &$orderId,
                                             &$qty,
                                             &$prodId,
                                             &$specialOfferId,
                                             &$price));
if( $stmt === false )
{
     echo "Statement could not be prepared.\n";
     die( print_r( sqlsrv_errors(), true));
}

/* Execute a statement for each set of params in $parameters.
Because $params is bound to $stmt, as the values are changed, the
new values are used in the subsequent execution. */
foreach( $parameters as $params)
{
     list($orderId, $qty, $prodId, $specialOfferId, $price) = $params;
     if( sqlsrv_execute($stmt) === false )
     {
          echo "Statement could not be executed.\n";
          die( print_r( sqlsrv_errors(), true));
     }
     else
     {
          /* Verify that the row was successfully inserted. */
          echo "Rows affected: ".sqlsrv_rows_affected( $stmt )."\n";
     }
}
/* Free statement and connection resources. */
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>

另请参见

参考

sqlsrv_rows_affected

概念

安全注意事项
关于文档中的代码示例

其他资源

设计注意事项
转换数据类型