共用方式為


如何:執行參數化查詢

本主題將摘要及示範如何使用 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 資料表中更新指定之產品識別碼的數量。數量和產品識別碼都是 UPDATE 查詢中的參數。

然後此範例會查詢資料庫,以確認數量已正確更新。產品識別碼是 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

概念

安全性考量
有關文件集中的程式碼範例

其他資源

設計考量
轉換資料類型