如何:執行參數化查詢
本主題摘要說明並示範如何使用 Microsoft Drivers for PHP for SQL Server,執行參數化查詢。
執行參數化查詢的步驟也可彙整成四個步驟:
將問號 (?) 當作參數預留位置放入即將執行查詢的 Transact-SQL 字串中。
初始化或更新對應至 Transact-SQL 查詢中預留位置的 PHP 變數。
使用步驟 2 中的 PHP 變數,來建立或更新對應至 Transact-SQL 字串中參數預留位置的參數值陣列。 陣列中參數值的順序,必須與加以代表的預留位置相同。
執行查詢:
如果您使用 SQLSRV 驅動程式,請使用 sqlsrv_query 或 sqlsrv_prepare/sqlsrv_execute。
如果您要使用 PDO_SQLSRV 驅動程式,請以 PDO::prepare 和 PDOStatement::execute 執行查詢。 PDO::prepare 和 PDOStatement::execute 的主題有程式碼範例。
本主題的其餘部分將討論使用 SQLSRV 驅動程式的參數化查詢。
注意
使用 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 資料表中。 $params 陣列會在呼叫 sqlsrv_prepare 時繫結至陳述式 ( $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);
?>